From 3b0d16fd900005d4708d498a7655dc8b04f2b881 Mon Sep 17 00:00:00 2001 From: Jochen Hoenle <173445474+hoe-jo@users.noreply.github.com> Date: Wed, 22 Jul 2026 10:01:50 +0200 Subject: [PATCH] [rules score] update documentation --- .bazelignore | 2 + .github/workflows/tests.yml | 5 + bazel/rules/rules_score/BUILD | 10 + ...e.puml => SeoocExample_DynamicDesign.puml} | 13 +- .../docs/_assets/SeoocExample_FTA.puml | 29 ++ ...ign.puml => SeoocExample_InternalApi.puml} | 11 +- ...icApi.puml => SeoocExample_PublicApi.puml} | 8 +- .../_assets/SeoocExample_StaticDesign.puml | 32 ++ .../SeoocExample_UnitClassDiagram.puml | 36 ++ .../rules_score/docs/integration_guide.rst | 11 + bazel/rules/rules_score/docs/overview.rst | 67 +++- .../rules/rules_score/docs/rule_reference.rst | 136 ++++++- .../docs/user_guide/architectural_design.md | 287 -------------- .../docs/user_guide/architectural_design.rst | 371 ++++++++++++++++++ .../docs/user_guide/assumptions_of_use.rst | 119 ++++++ .../docs/user_guide/dependability_analysis.md | 227 ----------- .../user_guide/dependability_analysis.rst | 353 +++++++++++++++++ .../rules_score/docs/user_guide/general.md | 115 ------ .../rules_score/docs/user_guide/general.rst | 110 ++++++ .../rules_score/docs/user_guide/index.rst | 13 + .../docs/user_guide/requirements.md | 339 ---------------- .../docs/user_guide/requirements.rst | 340 ++++++++++++++++ .../docs/user_guide/tutorial/architecture.rst | 89 +++++ .../docs/user_guide/tutorial/build.rst | 46 +++ .../docs/user_guide/tutorial/index.rst | 36 ++ .../docs/user_guide/tutorial/requirements.rst | 80 ++++ .../docs/user_guide/tutorial/unit_design.rst | 83 ++++ .../docs/user_guide/tutorial/validation.rst | 66 ++++ .../docs/user_guide/unit_design.md | 26 -- .../docs/user_guide/unit_design.rst | 147 +++++++ .../rules_score/examples/integrator/.bazelrc | 8 + .../examples/integrator/.bazelversion | 1 + .../rules_score/examples/integrator/BUILD | 12 +- .../examples/integrator/MODULE.bazel | 65 +++ .../integrator/bazel/toolchains/BUILD | 34 ++ .../integrator/docs/requirements/BUILD | 2 +- .../rules_score/examples/minimal/.bazelrc | 8 + .../examples/minimal/.bazelversion | 1 + .../rules/rules_score/examples/minimal/BUILD | 103 +++++ .../rules_score/examples/minimal/MODULE.bazel | 42 ++ .../examples/minimal/bazel/toolchains/BUILD | 31 ++ .../minimal/docs/class_design.puml} | 15 +- .../examples/minimal/docs/static_design.puml | 23 ++ .../examples/minimal/requirements/asr.trlc | 23 ++ .../requirements/feature_requirements.trlc | 30 ++ .../examples/minimal/src/my_unit.cpp | 23 ++ .../examples/minimal/src/my_unit.h | 29 ++ .../examples/minimal/test/my_unit_test.cpp | 32 ++ bazel/rules/rules_score/examples/seooc/BUILD | 28 +- .../examples/seooc/design/static_design.puml | 1 + .../examples/seooc/docs/requirements/BUILD | 14 + .../component_requirements_sub.trlc | 23 ++ .../seooc/unit_1/docs/unit_1_design.rst | 3 + .../seooc/unit_2/docs/unit_2_design.rst | 4 + 54 files changed, 2706 insertions(+), 1056 deletions(-) rename bazel/rules/rules_score/docs/_assets/{MySeooc_WriteSequence.puml => SeoocExample_DynamicDesign.puml} (68%) create mode 100644 bazel/rules/rules_score/docs/_assets/SeoocExample_FTA.puml rename bazel/rules/rules_score/docs/_assets/{MySeooc_StaticDesign.puml => SeoocExample_InternalApi.puml} (69%) rename bazel/rules/rules_score/docs/_assets/{MySeooc_PublicApi.puml => SeoocExample_PublicApi.puml} (78%) create mode 100644 bazel/rules/rules_score/docs/_assets/SeoocExample_StaticDesign.puml create mode 100644 bazel/rules/rules_score/docs/_assets/SeoocExample_UnitClassDiagram.puml delete mode 100644 bazel/rules/rules_score/docs/user_guide/architectural_design.md create mode 100644 bazel/rules/rules_score/docs/user_guide/architectural_design.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/assumptions_of_use.rst delete mode 100644 bazel/rules/rules_score/docs/user_guide/dependability_analysis.md create mode 100644 bazel/rules/rules_score/docs/user_guide/dependability_analysis.rst delete mode 100644 bazel/rules/rules_score/docs/user_guide/general.md create mode 100644 bazel/rules/rules_score/docs/user_guide/general.rst delete mode 100644 bazel/rules/rules_score/docs/user_guide/requirements.md create mode 100644 bazel/rules/rules_score/docs/user_guide/requirements.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/tutorial/architecture.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/tutorial/build.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/tutorial/index.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/tutorial/requirements.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/tutorial/unit_design.rst create mode 100644 bazel/rules/rules_score/docs/user_guide/tutorial/validation.rst delete mode 100644 bazel/rules/rules_score/docs/user_guide/unit_design.md create mode 100644 bazel/rules/rules_score/docs/user_guide/unit_design.rst create mode 100644 bazel/rules/rules_score/examples/integrator/.bazelrc create mode 100644 bazel/rules/rules_score/examples/integrator/.bazelversion create mode 100644 bazel/rules/rules_score/examples/integrator/MODULE.bazel create mode 100644 bazel/rules/rules_score/examples/integrator/bazel/toolchains/BUILD create mode 100644 bazel/rules/rules_score/examples/minimal/.bazelrc create mode 100644 bazel/rules/rules_score/examples/minimal/.bazelversion create mode 100644 bazel/rules/rules_score/examples/minimal/BUILD create mode 100644 bazel/rules/rules_score/examples/minimal/MODULE.bazel create mode 100644 bazel/rules/rules_score/examples/minimal/bazel/toolchains/BUILD rename bazel/rules/rules_score/{docs/_assets/MySeooc_FTA.puml => examples/minimal/docs/class_design.puml} (65%) create mode 100644 bazel/rules/rules_score/examples/minimal/docs/static_design.puml create mode 100644 bazel/rules/rules_score/examples/minimal/requirements/asr.trlc create mode 100644 bazel/rules/rules_score/examples/minimal/requirements/feature_requirements.trlc create mode 100644 bazel/rules/rules_score/examples/minimal/src/my_unit.cpp create mode 100644 bazel/rules/rules_score/examples/minimal/src/my_unit.h create mode 100644 bazel/rules/rules_score/examples/minimal/test/my_unit_test.cpp create mode 100644 bazel/rules/rules_score/examples/seooc/docs/requirements/component_requirements_sub.trlc diff --git a/.bazelignore b/.bazelignore index ef1e4a20..83c51ebd 100644 --- a/.bazelignore +++ b/.bazelignore @@ -18,3 +18,5 @@ bazel/rules/rules_score/test # Separate local Bazel modules (use @seooc// and @some_other_library// instead) bazel/rules/rules_score/examples/seooc bazel/rules/rules_score/examples/some_other_library +# Separate local Bazel module (system integrator demo, depends on @seooc//) +bazel/rules/rules_score/examples/integrator diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index efa22280..67676623 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,6 +122,11 @@ jobs: cd bazel/rules/rules_score/examples/seooc bazel build //... bazel test //... + - name: integrator_example + run: | + cd bazel/rules/rules_score/examples/integrator + bazel build //... + bazel test //... - name: some_other_library_example run: | cd bazel/rules/rules_score/examples/some_other_library diff --git a/bazel/rules/rules_score/BUILD b/bazel/rules/rules_score/BUILD index 47a4fd47..c365f3ac 100644 --- a/bazel/rules/rules_score/BUILD +++ b/bazel/rules/rules_score/BUILD @@ -165,6 +165,15 @@ sphinx_docs_library( strip_prefix = "validation/core/docs/specifications/", ) +# Source files from the standalone minimal example, mapped into the Sphinx +# source tree so that general.rst can reference them via literalinclude. +sphinx_docs_library( + name = "minimal_example_srcs", + srcs = ["//bazel/rules/rules_score/examples/minimal:doc_sources"], + prefix = "bazel/rules/rules_score/docs/examples/minimal/", + strip_prefix = "bazel/rules/rules_score/examples/minimal/", +) + sphinx_module( name = "rules_score_doc", testonly = True, @@ -182,6 +191,7 @@ sphinx_module( "//bazel/rules/rules_score/docs/requirements:use_cases_rst", ], docs_library_deps = [ + ":minimal_example_srcs", ":tool_readme_ai_checker_assets", ":validation_specs", ], diff --git a/bazel/rules/rules_score/docs/_assets/MySeooc_WriteSequence.puml b/bazel/rules/rules_score/docs/_assets/SeoocExample_DynamicDesign.puml similarity index 68% rename from bazel/rules/rules_score/docs/_assets/MySeooc_WriteSequence.puml rename to bazel/rules/rules_score/docs/_assets/SeoocExample_DynamicDesign.puml index 578dd90a..a220b160 100644 --- a/bazel/rules/rules_score/docs/_assets/MySeooc_WriteSequence.puml +++ b/bazel/rules/rules_score/docs/_assets/SeoocExample_DynamicDesign.puml @@ -11,15 +11,12 @@ ' SPDX-License-Identifier: Apache-2.0 ' ******************************************************************************* -@startuml MySeooc_WriteSequence +@startuml SeoocExample_DynamicDesign -actor Caller -participant KeyValueStore -participant StorageBackend +participant "Unit 1" as unit_1 <> +participant "Unit 2" as unit_2 <> -Caller -> KeyValueStore : write(key, value) -KeyValueStore -> StorageBackend : flush() -StorageBackend --> KeyValueStore : OK -KeyValueStore --> Caller : Result::Ok +unit_1 -> unit_2 : GetData() +unit_2 --> unit_1 : return : Data* @enduml diff --git a/bazel/rules/rules_score/docs/_assets/SeoocExample_FTA.puml b/bazel/rules/rules_score/docs/_assets/SeoocExample_FTA.puml new file mode 100644 index 00000000..a3b3853e --- /dev/null +++ b/bazel/rules/rules_score/docs/_assets/SeoocExample_FTA.puml @@ -0,0 +1,29 @@ +' ******************************************************************************* +' 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 +' ******************************************************************************* + +@startuml SeoocExample_FTA + +!include fta_metamodel.puml + +$TopEvent("SampleFailureMode takes over the world", "SampleLibrary.SampleFailureMode") + +$OrGate("OG1", "SampleLibrary.SampleFailureMode") + +$IntermediateEvent("SampleFailureMode is Angry", "IEF", "OG1") +$BasicEvent("Just bad luck", "SampleLibrary.JustBadLuck", "OG1") + +$AndGate("AG2", "IEF") +$BasicEvent("No More Cookies", "SampleLibrary.NoMoreCookies", "AG2") +$BasicEvent("No More Coffee", "SampleLibrary.NoMoreCoffee", "AG2") + +@enduml diff --git a/bazel/rules/rules_score/docs/_assets/MySeooc_StaticDesign.puml b/bazel/rules/rules_score/docs/_assets/SeoocExample_InternalApi.puml similarity index 69% rename from bazel/rules/rules_score/docs/_assets/MySeooc_StaticDesign.puml rename to bazel/rules/rules_score/docs/_assets/SeoocExample_InternalApi.puml index 87e3df99..cba23b05 100644 --- a/bazel/rules/rules_score/docs/_assets/MySeooc_StaticDesign.puml +++ b/bazel/rules/rules_score/docs/_assets/SeoocExample_InternalApi.puml @@ -11,13 +11,14 @@ ' SPDX-License-Identifier: Apache-2.0 ' ******************************************************************************* -@startuml MySeooc_StaticDesign +@startuml SeoocExample_InternalApi -package "MySeooc" as MySeooc <> { - component "KvsComponent" as KvsComponent <> { - component "KeyValueStore" as KeyValueStore <> - component "StorageBackend" as StorageBackend <> +namespace safety_software_seooc_example { + namespace component_example { + interface "InternalInterface" as InternalInterface <>{ + {abstract} GetData(BindingType binding): Data* } + } } @enduml diff --git a/bazel/rules/rules_score/docs/_assets/MySeooc_PublicApi.puml b/bazel/rules/rules_score/docs/_assets/SeoocExample_PublicApi.puml similarity index 78% rename from bazel/rules/rules_score/docs/_assets/MySeooc_PublicApi.puml rename to bazel/rules/rules_score/docs/_assets/SeoocExample_PublicApi.puml index 77453a03..444a5f24 100644 --- a/bazel/rules/rules_score/docs/_assets/MySeooc_PublicApi.puml +++ b/bazel/rules/rules_score/docs/_assets/SeoocExample_PublicApi.puml @@ -11,11 +11,11 @@ ' SPDX-License-Identifier: Apache-2.0 ' ******************************************************************************* -@startuml MySeooc_PublicApi +@startuml SeoocExample_PublicApi -interface "KeyValueStore" as KVS { - + write(key: string, value: bytes): Result - + read(key: string): Optional +package "SampleLibraryAPI" as SampleLibraryAPI { + interface "GetNumber" as GetNumber + ' interface "SetNumber" as SetNumber } @enduml diff --git a/bazel/rules/rules_score/docs/_assets/SeoocExample_StaticDesign.puml b/bazel/rules/rules_score/docs/_assets/SeoocExample_StaticDesign.puml new file mode 100644 index 00000000..499eefbe --- /dev/null +++ b/bazel/rules/rules_score/docs/_assets/SeoocExample_StaticDesign.puml @@ -0,0 +1,32 @@ +' ******************************************************************************* +' 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 +' ******************************************************************************* + +@startuml SeoocExample_StaticDesign + +package "Safety Software SEooC Example" as safety_software_seooc_example <> { + component "ComponentExample" as component_example <> { + component "Unit 1" as unit_1 <> + component "Unit 2" as unit_2 <> + component "Sub Component Example" as sub_component_example <> + + interface "InternalInterface" as InternalInterface + unit_1 -l-( InternalInterface + unit_2 )-r- InternalInterface + } +} + +package "SampleLibraryAPI" as SampleLibraryAPI + +component_example --> SampleLibraryAPI + +@enduml diff --git a/bazel/rules/rules_score/docs/_assets/SeoocExample_UnitClassDiagram.puml b/bazel/rules/rules_score/docs/_assets/SeoocExample_UnitClassDiagram.puml new file mode 100644 index 00000000..e4fbc360 --- /dev/null +++ b/bazel/rules/rules_score/docs/_assets/SeoocExample_UnitClassDiagram.puml @@ -0,0 +1,36 @@ +' ******************************************************************************* +' 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 +' ******************************************************************************* + +@startuml SeoocExample_UnitClassDiagram + +namespace unit_1 { + class Foo <>{ + -- + + GetNumber() : uint8_t + + SetNumber(value : uint8_t) : void + } +} + +namespace unit_2 { + class Bar <>{ + -- + - foo_ : unique_ptr + -- + + Bar(foo : unique_ptr) + + AssertNumber() : bool + } +} + +Bar --> Foo : uses + +@enduml diff --git a/bazel/rules/rules_score/docs/integration_guide.rst b/bazel/rules/rules_score/docs/integration_guide.rst index d3f9a9e2..34cb1123 100644 --- a/bazel/rules/rules_score/docs/integration_guide.rst +++ b/bazel/rules/rules_score/docs/integration_guide.rst @@ -15,6 +15,17 @@ Integration Guide ================= +Build Flow +---------- + +The diagram below shows how input files flow through the Bazel rules to +produce the final outputs. + +.. uml:: _assets/seooc_flow.puml + :align: center + :alt: SEooC build flow + :width: 90% + .. _rule-toolchain-configuration: Toolchain Setup diff --git a/bazel/rules/rules_score/docs/overview.rst b/bazel/rules/rules_score/docs/overview.rst index ff472d7c..c4a24f16 100644 --- a/bazel/rules/rules_score/docs/overview.rst +++ b/bazel/rules/rules_score/docs/overview.rst @@ -17,9 +17,10 @@ Overview ``rules_score`` organises safety-critical software artefacts into four groups: -**Documentation Rule** — the generic Sphinx builder underlying all other rules: +**Documentation Rules** — Sphinx builder and supporting helpers: - :ref:`sphinx_module ` — Builds Sphinx HTML from RST/MD sources with dependency merging +- :ref:`filter_execpath ` — Resolves a build output path into a Sphinx ``-D`` flag at analysis time *(advanced)* **Artifact Rules** — declare individual process work products: @@ -27,6 +28,7 @@ Overview - :ref:`feature_requirements ` — High-level feature specifications - :ref:`component_requirements ` — Component-level requirements - :ref:`assumptions_of_use ` — Safety-relevant operating conditions imposed on the integrator +- :ref:`glossary ` — Glossary pages included in the generated documentation - :ref:`architectural_design ` — Software architecture (static, dynamic, public API) - :ref:`unit_design ` — Code-level design diagrams scoped to a single unit - :ref:`fmea ` — Failure Mode and Effects Analysis (failure modes, FTA, control measures) @@ -40,10 +42,61 @@ Overview All rules support cross-module dependencies for sphinx-needs integration and HTML merging. -Architecture diagram --------------------- +Quick Reference +--------------- -.. uml:: _assets/rules_score_overview.puml - :align: center - :alt: Overview of rules_score architecture - :width: 100% +.. list-table:: + :header-rows: 1 + :widths: 28 20 52 + + * - Rule + - Category + - User Guide + * - :ref:`sphinx_module ` + - Documentation + - :doc:`integration_guide` + * - :ref:`filter_execpath ` + - Documentation + - :ref:`Rule reference ` *(advanced)* + * - :ref:`assumed_system_requirements ` + - Artifact + - :doc:`user_guide/requirements` + * - :ref:`feature_requirements ` + - Artifact + - :doc:`user_guide/requirements` + * - :ref:`component_requirements ` + - Artifact + - :doc:`user_guide/requirements` + * - :ref:`assumptions_of_use ` + - Artifact + - :doc:`user_guide/assumptions_of_use` + * - :ref:`glossary ` + - Artifact + - :ref:`Rule reference ` + * - :ref:`architectural_design ` + - Artifact + - :doc:`user_guide/architectural_design` + * - :ref:`unit_design ` + - Artifact + - :doc:`user_guide/unit_design` + * - :ref:`fmea ` + - Artifact + - :doc:`user_guide/dependability_analysis` + * - :ref:`dependability_analysis ` + - Artifact + - :doc:`user_guide/dependability_analysis` + * - :ref:`unit ` + - Structural + - :doc:`user_guide/architectural_design` + * - :ref:`component ` + - Structural + - :doc:`user_guide/architectural_design` + * - :ref:`dependable_element ` + - Structural + - :doc:`user_guide/general` + +.. seealso:: + + :doc:`User Guide ` — step-by-step guides for every rule + + :doc:`Rule Reference ` — complete attribute reference for all rules diff --git a/bazel/rules/rules_score/docs/rule_reference.rst b/bazel/rules/rules_score/docs/rule_reference.rst index 20aec0c9..9a4ca2fd 100644 --- a/bazel/rules/rules_score/docs/rule_reference.rst +++ b/bazel/rules/rules_score/docs/rule_reference.rst @@ -77,6 +77,60 @@ cross-module dependencies and automatic HTML merging. - ```` — HTML output under ``bazel-bin//html/``; use in ``deps`` of other ``sphinx_module`` targets. - ``_needs`` — ``needs.json`` produced by the needs builder; consumed transitively by downstream modules for cross-module ``{requirement:downstream-ref}`` resolution. See :ref:`two-phase-sphinx-build` for the full data-flow description. +.. _rule-filter-execpath: + +filter_execpath +~~~~~~~~~~~~~~~ + +*Advanced.* Resolves a Sphinx ``-D`` command-line argument (such as a Doxygen +build output path) from a Bazel target's outputs at analysis time, producing +a fully-qualified string that can be passed to ``sphinx_module.extra_opts_targets``. +This is needed when a Sphinx extension (e.g. Breathe for Doxygen integration) +requires a path that is only known once the dependency has been built. + +.. code-block:: python + + filter_execpath( + name = "breathe_project_path", + flag = "-Dbreathe_projects.MyLib", + target = "//doc:doxygen_build", + filter_pattern = "xml/index.xml", + ) + + sphinx_module( + name = "my_docs", + srcs = glob(["docs/**/*.rst"]), + index = "docs/index.rst", + extra_opts_targets = [":breathe_project_path"], + ) + +.. list-table:: + :header-rows: 1 + :widths: 18 12 10 60 + + * - Attribute + - Type + - Required + - Description + * - ``name`` + - string + - yes + - Target name + * - ``flag`` + - string + - yes + - The Sphinx ``-D`` flag name (e.g. ``"-Dbreathe_projects.MyLib"``) + * - ``target`` + - label + - yes + - Bazel target whose output files are searched + * - ``filter_pattern`` + - string + - yes + - Substring used to identify the relevant output file within ``target``'s outputs + +**Provides:** ``FilteredExecpathInfo`` — carries ``flag``, ``resolved_path``, and the combined ``arg`` string (``flag=resolved_path``). Consumed via ``sphinx_module.extra_opts_targets``. + Artifact Rules -------------- @@ -234,9 +288,8 @@ Conditions that the *integrating project* must fulfil when using this SEooC. .. code-block:: python assumptions_of_use( - name = "aous", - srcs = ["docs/assumptions.trlc"], - requirements = [":features"], + name = "aous", + srcs = ["docs/assumptions.trlc"], ) .. list-table:: @@ -254,11 +307,19 @@ Conditions that the *integrating project* must fulfil when using this SEooC. * - ``srcs`` - label list - yes - - ``.trlc`` files containing ``AoU`` records - * - ``requirements`` + - ``.trlc`` files (containing ``AoU`` records), ``.rst`` files, or labels to existing ``TrlcProviderInfo``-providing targets + * - ``deps`` - label list - no - - ``feature_requirements`` or ``component_requirements`` targets that these AoUs trace to (default ``[]``) + - Other requirement targets (``TrlcProviderInfo``) needed for cross-reference parsing (default ``[]``) + * - ``ref_package`` + - string + - no + - TRLC package prefix used for ``derived_from`` cross-references when converting RST sources (default ``None``) + * - ``lobster_config`` + - label + - no + - Advanced: override the Lobster YAML configuration for AoU traceability extraction (default: built-in S-CORE AoU config) * - ``visibility`` - — - no @@ -326,16 +387,18 @@ Example glossary source (``.rst``): architectural_design ~~~~~~~~~~~~~~~~~~~~ -Bundles static, dynamic, and public-API architecture views into a single target. -Provides ``ArchitecturalDesignInfo`` consumed by ``dependable_element`` and ``fmea``. +Bundles static, dynamic, public-API, and internal-API architecture views into a +single target. Provides ``ArchitecturalDesignInfo`` consumed by ``dependable_element`` +and ``fmea``. .. code-block:: python architectural_design( - name = "arch", - static = ["docs/static_design.puml"], - dynamic = ["docs/sequence.puml"], - public_api = ["docs/public_api.puml"], + name = "arch", + static = ["docs/static_design.puml"], + dynamic = ["docs/sequence.puml"], + public_api = ["docs/public_api.puml"], + internal_api = ["docs/internal_api.puml"], ) .. list-table:: @@ -361,7 +424,15 @@ Provides ``ArchitecturalDesignInfo`` consumed by ``dependable_element`` and ``fm * - ``public_api`` - label list - no - - Public-API diagram files (``.puml``); also generates traceability items for safety analysis (default ``[]``) + - Public-API diagram files (``.puml``); also generates traceability items for safety analysis, exposed via ``ArchitecturalDesignInfo.public_api_lobster_files`` (default ``[]``) + * - ``internal_api`` + - label list + - no + - Internal-API diagram files (``.puml``) describing interfaces exposed between components inside the SEooC; their FlatBuffers output is exposed via ``ArchitecturalDesignInfo.internal_api`` for downstream validation (default ``[]``) + * - ``maturity`` + - string + - no + - ``"release"`` (default) treats validation findings as errors; ``"development"`` emits warnings and continues * - ``visibility`` - — - no @@ -477,8 +548,9 @@ Running ``bazel test`` validates the full FMEA traceability chain. .. code-block:: python dependability_analysis( - name = "analysis", - fmea = [":my_fmea"], + name = "analysis", + arch_design = ":my_arch", + fmea = [":my_fmea"], ) .. list-table:: @@ -495,8 +567,12 @@ Running ``bazel test`` validates the full FMEA traceability chain. - Target name * - ``fmea`` - label list - - yes - - ``fmea`` targets to include in this analysis + - no + - ``fmea`` targets to include in this analysis (default ``[]``) + * - ``arch_design`` + - label + - no + - Optional ``architectural_design`` target this analysis relates to (default ``None``) * - ``visibility`` - — - no @@ -552,9 +628,13 @@ diagram. - yes - Test targets that verify this unit (may be ``[]``) * - ``scope`` - - label list + - string list - no - - Additional targets needed by the implementation but not listed in ``implementation`` (default ``[]``) + - Additional Bazel label strings, not already reachable through ``implementation``, that this unit is allowed to depend on. Each entry is either a specific target label (``//pkg:target``, allowlisting just that target) or a package wildcard (``//pkg:__pkg__`` for everything directly in that package, ``//pkg:__subpackages__`` for the whole package tree). Any transitive implementation dependency not covered by ``implementation`` or ``scope`` triggers a scope violation at ``dependable_element`` build time. (default ``[]``) + * - ``maturity`` + - string + - no + - ``"release"`` (default) treats scope violations as errors; ``"development"`` emits warnings and continues * - ``testonly`` - bool - no @@ -686,6 +766,10 @@ and scope checks at build/test time. - label list - no - Additional ``.rst`` / ``.md`` checklist files (default ``[]``) + * - ``glossary`` + - label list + - no + - ``glossary`` targets whose pages are included in the generated documentation under a dedicated Glossary section (default ``[]``) * - ``deps`` - label list - no @@ -693,11 +777,21 @@ and scope checks at build/test time. * - ``aou_forwarding`` - label - no - - A YAML file selecting which *received* AoUs to chain-forward to elements that depend on this one. Each entry requires an ``aou_id`` and a ``justification``. Own AoUs (from ``assumptions_of_use``) are always forwarded automatically. + - Optional YAML file that selects which *received* AoUs to chain-forward to elements that depend on this one. Own AoUs (declared in ``assumptions_of_use``) are always forwarded automatically — no file needed. Schema: + + .. code-block:: yaml + + forwarded_aous: + - aou_id: "Package.AOU_ID" + justification: > + Reason why this element cannot handle the AoU itself + and must forward it to its own integrators. + + See :ref:`requirements user guide ` for the full forwarding workflow. * - ``maturity`` - string - no - - ``"release"`` (default) or ``"development"`` — in development mode, scope violations and architecture errors are downgraded to warnings + - ``"release"`` (default) treats certified-scope violations and architecture consistency errors as hard build failures. ``"development"`` downgrades them to warnings so the build still succeeds — useful when iterating before all scope and architecture declarations are finalised. **Always revert to ``"release"`` before a certification delivery.** * - ``testonly`` - bool - no diff --git a/bazel/rules/rules_score/docs/user_guide/architectural_design.md b/bazel/rules/rules_score/docs/user_guide/architectural_design.md deleted file mode 100644 index 6b72b919..00000000 --- a/bazel/rules/rules_score/docs/user_guide/architectural_design.md +++ /dev/null @@ -1,287 +0,0 @@ - - -# Architectural Design - -## Overview and Hierarchy - -Software in `rules_score` is structured in three levels: - -``` -dependable_element (SEooC — complete Safety Element out of Context) -└── component (groups units; owns component-level integration tests and requirements) - ├── unit (smallest independently verifiable architectural element: implementation + unit tests) - └── component (components can be nested for deeper hierarchies) - └── unit -``` - -Two rules apply: - -- `unit` targets must always be wrapped in a `component` — they cannot be placed directly under `dependable_element`. -- `component` targets can be nested: a component may contain other components as well as units, allowing arbitrary depth. - -This hierarchy exists for two complementary reasons: - -- **Interrelations between units and components** — A component defines a clear boundary within which its units collaborate. Grouping units into components keeps inter-unit coupling explicit and local, while the component's public interface controls what the rest of the system can depend on. The static architecture diagrams document exactly which components expose which interfaces, preventing accidental cross-boundary dependencies. -- **Interface-driven safety analysis** — The `public_api` diagrams at the SEooC level define the interfaces that external consumers may call. Failure modes in the FMEA reference individual interface items by name, establishing a direct traceability link from the safety analysis back to the architecture. Without a well-defined interface boundary this traceability would be impossible. - -Each level of the hierarchy has a corresponding design artifact: - -| Level | Design rule | Content | -|---|---|---| -| SEooC / component | `architectural_design` | Static structure, dynamic behaviour, public API | -| Unit | `unit_design` | Implementation Details, unit-level sequences | - -A consistency check at build time verifies that every component and unit in the Bazel implementation tree also appears in the PlantUML target architecture diagrams. If anything is out of sync the build fails with a descriptive error. - - -## Static Architecture - -The static view describes the **structural organisation** of your software: what components and units exist, how they relate to each other, and which dependencies they carry. It is the primary input for the architecture consistency check. - -### PlantUML - -Write a PlantUML class or component diagram that names every `component` and `unit` from your Bazel BUILD file. - -```{uml} ../_assets/MySeooc_StaticDesign.puml -:align: center -:alt: MySeooc static architecture -``` - -```text -@startuml MySeooc_StaticDesign - -package "MySeooc" as MySeooc <> { - component "KvsComponent" as KvsComponent <> { - component "KeyValueStore" as KeyValueStore <> - component "StorageBackend" as StorageBackend <> - } -} - -@enduml -``` - -#### Valid PlantUML Definitions - -The validator identifies elements by their **stereotype**, not by the PlantUML keyword used. Both `package` and `component` keywords are accepted at each level. - -| Stereotype | Valid PlantUML keywords | Meaning | Bazel rule | -|---|---|---|---| -| `<>` | `package`, `component` | Safety Element out of Context boundary | `dependable_element` | -| `<>` | `component`, `package` | Architectural component | `component` | -| `<>` | `component`, `package` | Leaf implementation unit | `unit` | - -#### Ports and Interface Bindings - -Elements with stereotype `<>` or `<>` may declare ports and bind them to interfaces. This documents which external interfaces the element requires or provides. - -```text -@startuml MySeooc_StaticDesign - -package "MySeooc" as MySeooc <> { - component "KvsComponent" as KvsComponent <> { - component "KeyValueStore" as KeyValueStore <> - } - - portin " " as p_storage ' required interface port - portout " " as p_api ' provided interface port -} - -interface "score::storage" as storage -interface "kvsapi" as kvsapi - -p_storage -( storage : requires -p_api )- kvsapi : provides - -@enduml -``` - -**Rules:** - -- `portin` / `portout` are declared inside the `<>` or `<>` element. -- `-(` binds a required (incoming) interface; `)-` binds a provided (outgoing) interface. -- The `--()` lollipop syntax (e.g. `port --() Interface`) is treated as a plain association and does **not** carry interface-binding semantics. -- Plain `package` without a stereotype cannot carry interface bindings. - -### Bazel - -The PlantUML diagrams capture *intended* structure; the Bazel rules model the *actual* implementation. Using the same example as the diagram above — SEooC `MySeooc` containing component `KvsComponent` with units `KeyValueStore` and `StorageBackend` — the three rules work together like this: - -#### architectural_design - -declares which diagram files belong to which view category: - -```starlark -load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "architectural_design") - -architectural_design( - name = "my_arch", - static = ["static_design.puml"], # the MySeooc_StaticDesign diagram above - dynamic = ["sequence_design.puml"], -) -``` - -#### unit - -one target per leaf unit (`<>` stereotype) in the diagram. The unit name must match the name used in the PlantUML. It ties together implementation targets, test targets, and an optional `unit_design` target (see {doc}`unit_design`): - -```starlark -load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "unit") - -# Unit for KeyValueStore -cc_library(name = "kvs_lib", srcs = ["kvs.cpp"], hdrs = ["kvs.h"]) -cc_test (name = "kvs_unit_test", srcs = ["kvs_test.cpp"], deps = [":kvs_lib"]) - -unit( - name = "KeyValueStore", - unit_design = [":kvs_unit_design"], - implementation = [":kvs_lib"], - tests = [":kvs_unit_test"], -) - -# Unit for StorageBackend -cc_library(name = "storage_lib", srcs = ["storage_backend.cpp"], hdrs = ["storage_backend.h"]) -cc_test (name = "storage_unit_test", srcs = ["storage_test.cpp"], deps = [":storage_lib"]) - -unit( - name = "StorageBackend", - unit_design = [":storage_unit_design"], - implementation = [":storage_lib"], - tests = [":storage_unit_test"], -) -``` - - -#### component - -groups the units that belong to `KvsComponent` in the diagram. It aggregates one or more `unit` (or nested `component`) targets and links them to component-level requirements. Integration tests that verify the units working together are declared here: - -```starlark -load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", - "component", "component_requirements") - -component_requirements( - name = "kvs_comp_req", - srcs = ["component_requirements.trlc"], - deps = [":feature_req"], -) - -# The component maps to KvsComponent in the PlantUML diagram -component( - name = "KvsComponent", - requirements = [":kvs_comp_req"], - components = [":KeyValueStore", ":StorageBackend"], - tests = [], -) -``` - -## Dynamic Architecture - -The dynamic view describes **behavioural aspects** — sequences of interactions, state transitions, and activity flows. Dynamic diagrams document how your software behaves at runtime. They are not validated against the Bazel structure at build time. - -### PlantUML - -```{uml} ../_assets/MySeooc_WriteSequence.puml -:align: center -:alt: MySeooc write sequence -``` - -```text -@startuml MySeooc_WriteSequence - -actor Caller -participant KeyValueStore -participant StorageBackend - -Caller -> KeyValueStore : write(key, value) -KeyValueStore -> StorageBackend : flush() -StorageBackend --> KeyValueStore : OK -KeyValueStore --> Caller : Result::Ok - -@enduml -``` - -### Bazel - -```starlark -architectural_design( - name = "my_arch", - static = ["static_design.puml"], - dynamic = ["sequence.puml"], -) -``` - -## Public API - -The public API view describes the **interface your SEooC exposes to its environment**. These diagrams are linked to safety analysis: `FailureMode` records reference interface items by name (via the `interface` field), enabling traceability from each failure mode back to the architecture. - -### PlantUML - -```{uml} ../_assets/MySeooc_PublicApi.puml -:align: center -:alt: MySeooc public API -``` - -```text -@startuml MySeooc_PublicApi - -interface "KeyValueStore" as KVS { - + write(key: string, value: bytes): Result - + read(key: string): Optional -} - -@enduml -``` - -### Bazel - -```starlark -architectural_design( - name = "my_arch", - public_api = ["public_api.puml"], -) -``` - -The `public_api` attribute also generates traceability items that can be referenced by `fmea` targets (see {doc}`dependability_analysis`) via the `arch_design` attribute. - -(rst-and-markdown-wrappers)= -## RST and Markdown Wrappers - -When you want to combine a diagram with text, create an RST or Markdown file that embeds the diagram using the `.. uml::` directive (RST) or the MyST equivalent. - -**RST wrapper example:** - -```rst -Static Architecture -------------------- - -The following diagram shows the component structure of MySeooc. - -.. uml:: MySeooc_StaticDesign.puml -``` - -Include both the wrapper file *and* the referenced `.puml` file in the same Bazel list — the build needs both: - -```starlark -architectural_design( - name = "my_arch", - static = [ - "static_design.rst", # wrapper with prose - "MySeooc_StaticDesign.puml", # diagram referenced by the wrapper - ], -) -``` - -## Rule Reference: `architectural_design` - -For the complete `architectural_design` attribute reference, see {ref}`architectural_design ` in the rule index. diff --git a/bazel/rules/rules_score/docs/user_guide/architectural_design.rst b/bazel/rules/rules_score/docs/user_guide/architectural_design.rst new file mode 100644 index 00000000..e1fd2599 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/architectural_design.rst @@ -0,0 +1,371 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Architectural Design +===================== + +Declared vs. Implemented Architecture +--------------------------------------- + +- **Declared architecture** — the PlantUML diagrams passed to ``architectural_design`` (``static``, ``dynamic``, ``public_api``, ``internal_api``). This is what your architecture is *supposed* to look like: the components, units, and interfaces you intend to build, and how they should relate to each other. + +- **Implemented architecture** — the actual Bazel targets that get compiled and tested: ``unit(implementation = [...])`` wraps the real source files, ``component(components = [...])`` groups those units, and ``dependable_element(components = [...])`` assembles the complete SEooC. This is what your architecture *actually* is. + +Because these two views are authored independently, they can drift apart. Therefore ``rules_score`` implements an automatic **architecture consistency** check that runs at ``bazel build``/``bazel test`` time: every component or unit that appears in ``dependable_element.components`` must also appear, under the same name, in the static PlantUML diagram declared via ``architectural_design.static`` — and vice versa. A mismatch fails the build. See :doc:`general` for the full list of automatic validations ``rules_score`` performs. + +Overview and Hierarchy +------------------------ + +- **Static** — the structural organisation: which components and units exist, how they nest, and how they depend on each other. Validated against the Bazel model at build time. +- **Dynamic** — behavioural sequences, state transitions, and activity flows. Documentation only, not validated against Bazel targets. +- **Public API** — the interfaces the SEooC exposes to its environment, linked to safety analysis via ``FailureMode.interface``. +- **Internal API** — interfaces exposed between components inside the SEooC that are not part of the public boundary. + +Static Architecture +-------------------- + +The static view describes the **structural organisation** of your software: what components and units exist, how they relate to each other, and which dependencies they carry. It is the primary input for the architecture consistency check. + +Software in ``rules_score`` is structured in three levels: + +:: + + dependable_element (SEooC — complete Safety Element out of Context) + └── component (groups units; owns component-level integration tests and requirements) + ├── unit (smallest independently verifiable architectural element: implementation + unit tests) + └── component (components can be nested for deeper hierarchies) + └── unit + +Two rules apply: + +- ``unit`` targets must always be wrapped in a ``component`` — they cannot be placed directly under ``dependable_element``. +- ``component`` targets can be nested: a component may contain other components as well as units, allowing arbitrary depth. + +PlantUML +~~~~~~~~~ + +Write a PlantUML class or component diagram that names every ``component`` and ``unit`` from your Bazel BUILD file. + +.. uml:: ../_assets/SeoocExample_StaticDesign.puml + :align: center + :alt: SEooC example static architecture + +.. code-block:: text + + @startuml static_design + + package "Safety Software SEooC Example" as safety_software_seooc_example <> { + component "ComponentExample" as component_example <> { + component "Unit 1" as unit_1 <> + component "Unit 2" as unit_2 <> + component "Sub Component Example" as sub_component_example <> + + interface "InternalInterface" as InternalInterface + unit_1 -l-( InternalInterface + unit_2 )-r- InternalInterface + } + } + + package "SampleLibraryAPI" as SampleLibraryAPI + + component_example --> SampleLibraryAPI + + @enduml + +Valid PlantUML Definitions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The validator identifies elements by their **stereotype**, not by the PlantUML keyword used. Both ``package`` and ``component`` keywords are accepted at each level. + +.. list-table:: + :header-rows: 1 + + * - Stereotype + - Valid PlantUML keywords + - Meaning + - Bazel rule + * - ``<>`` + - ``package``, ``component`` + - Safety Element out of Context boundary + - ``dependable_element`` + * - ``<>`` + - ``component``, ``package`` + - Architectural component + - ``component`` + * - ``<>`` + - ``component``, ``package`` + - Leaf implementation unit + - ``unit`` + +Interface Bindings +^^^^^^^^^^^^^^^^^^^ + +Any component-type element (``<>``, ``<>``, or ``<>``) can bind directly to an interface using the lollipop syntax — also a dedicated port can be drawn. + +.. code-block:: text + + @startuml static_design + + package "Safety Software SEooC Example" as safety_software_seooc_example <> { + component "ComponentExample" as component_example <> { + component "Unit 1" as unit_1 <> + component "Unit 2" as unit_2 <> + component "Sub Component Example" as sub_component_example <> + + interface "InternalInterface" as InternalInterface + unit_1 -l-( InternalInterface + unit_2 )-r- InternalInterface + } + } + + package "SampleLibraryAPI" as SampleLibraryAPI + + component_example --> SampleLibraryAPI + + @enduml + +Named Ports (alternative) +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When an element needs an explicitly named, standalone binding point — for example to distinguish multiple provided interfaces without attaching them to a specific child unit — declare a ``portin`` / ``portout`` inside the ``<>`` or ``<>`` element instead of binding directly on a child element: + +.. code-block:: text + + @startuml MySeooc_StaticDesign + + package "MySeooc" as MySeooc <> { + component "KvsComponent" as KvsComponent <> { + component "KeyValueStore" as KeyValueStore <> + } + + portin " " as p_storage ' required interface port + portout " " as p_api ' provided interface port + } + + interface "score::storage" as storage + interface "kvsapi" as kvsapi + + p_storage -( storage : requires + p_api )- kvsapi : provides + + @enduml + +Bazel +~~~~~~ + +architectural_design +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: starlark + + load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "architectural_design") + + architectural_design( + name = "my_arch", + static = ["static_design.puml"], # the static diagram above + dynamic = ["sequence_design.puml"], + ) + +unit +^^^^^ + +.. code-block:: starlark + + load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "unit") + + # Unit for KeyValueStore + cc_library(name = "kvs_lib", srcs = ["kvs.cpp"], hdrs = ["kvs.h"]) + cc_test (name = "kvs_unit_test", srcs = ["kvs_test.cpp"], deps = [":kvs_lib"]) + + unit( + name = "KeyValueStore", + unit_design = [":kvs_unit_design"], + implementation = [":kvs_lib"], + tests = [":kvs_unit_test"], + ) + + # Unit for StorageBackend + cc_library(name = "storage_lib", srcs = ["storage_backend.cpp"], hdrs = ["storage_backend.h"]) + cc_test (name = "storage_unit_test", srcs = ["storage_test.cpp"], deps = [":storage_lib"]) + + unit( + name = "StorageBackend", + unit_design = [":storage_unit_design"], + implementation = [":storage_lib"], + tests = [":storage_unit_test"], + ) + +component +^^^^^^^^^^ + +.. code-block:: starlark + + load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "component", "component_requirements") + + component_requirements( + name = "kvs_comp_req", + srcs = ["component_requirements.trlc"], + deps = [":feature_req"], + ) + + # The component maps to KvsComponent in the PlantUML diagram + component( + name = "KvsComponent", + requirements = [":kvs_comp_req"], + components = [":KeyValueStore", ":StorageBackend"], + tests = [], + ) + +Dynamic Architecture +---------------------- + +The dynamic view describes **behavioural aspects** — sequences of interactions, state transitions, and activity flows. Dynamic diagrams document how your software behaves at runtime. They are not validated against the Bazel structure at build time. + +PlantUML +~~~~~~~~~ + +.. uml:: ../_assets/SeoocExample_DynamicDesign.puml + :align: center + :alt: SEooC example dynamic sequence + +.. code-block:: text + + @startuml SeoocExample_DynamicDesign + + participant "Unit 1" as unit_1 <> + participant "Unit 2" as unit_2 <> + + unit_1 -> unit_2 : GetData() + unit_2 --> unit_1 : return : Data* + + @enduml + +Bazel +~~~~~~ + +.. code-block:: starlark + + architectural_design( + name = "my_arch", + static = ["static_design.puml"], + dynamic = ["sequence.puml"], + ) + +Public API +------------ + +The public API view describes the **interface your SEooC exposes to its environment**. These diagrams are linked to safety analysis: ``FailureMode`` records reference interface items by name (via the ``interface`` field), enabling traceability from each failure mode back to the architecture. + +PlantUML +~~~~~~~~~ + +.. uml:: ../_assets/SeoocExample_PublicApi.puml + :align: center + :alt: SEooC example public API + +.. code-block:: text + + @startuml SeoocExample_PublicApi + + package "SampleLibraryAPI" as SampleLibraryAPI { + interface "GetNumber" as GetNumber + } + + @enduml + +Bazel +~~~~~~ + +.. code-block:: starlark + + architectural_design( + name = "my_arch", + public_api = ["public_api.puml"], + ) + +The ``public_api`` attribute also generates traceability items that can be referenced by ``fmea`` targets (see :doc:`dependability_analysis`) via the ``arch_design`` attribute. + +Internal API +-------------- + +The internal API view documents interfaces exposed **between components inside the SEooC** that are not part of the public boundary — for example, a service one component provides to a sibling component. These diagrams are parsed like static/dynamic views, but their FlatBuffers output is tracked separately via ``ArchitecturalDesignInfo.internal_api`` for downstream validation. Unlike ``public_api``, they do not generate failure-mode traceability items. + +PlantUML +~~~~~~~~~ + +Model the interface inside the namespace of the owning component so its fully-qualified name reflects the containment hierarchy: + +.. uml:: ../_assets/SeoocExample_InternalApi.puml + :align: center + :alt: SEooC example internal API + +.. code-block:: text + + @startuml + + namespace safety_software_seooc_example { + namespace component_example { + interface "InternalInterface" as InternalInterface <> { + {abstract} GetData(BindingType binding): Data* + } + } + } + + @enduml + +Bazel +~~~~~~ + +.. code-block:: starlark + + architectural_design( + name = "my_arch", + internal_api = ["internal_api.puml"], + ) + +.. _rst-and-markdown-wrappers: + +RST and Markdown Wrappers +---------------------------- + +When you want to combine a diagram with text, create an RST or Markdown file that embeds the diagram using the ``.. uml::`` directive (RST) or the MyST equivalent. + +**RST wrapper example:** + +.. code-block:: rst + + Static Architecture + ------------------- + + The following diagram shows the component structure of MySeooc. + + .. uml:: MySeooc_StaticDesign.puml + +Include both the wrapper file *and* the referenced ``.puml`` file in the same Bazel list — the build needs both: + +.. code-block:: starlark + + architectural_design( + name = "my_arch", + static = [ + "static_design.rst", # wrapper with prose + "MySeooc_StaticDesign.puml", # diagram referenced by the wrapper + ], + ) + +Rule Reference: ``architectural_design`` +------------------------------------------- + +For the complete ``architectural_design`` attribute reference, see :ref:`architectural_design ` in the rule index. diff --git a/bazel/rules/rules_score/docs/user_guide/assumptions_of_use.rst b/bazel/rules/rules_score/docs/user_guide/assumptions_of_use.rst new file mode 100644 index 00000000..f7da12c6 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/assumptions_of_use.rst @@ -0,0 +1,119 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Assumptions of Use +=================== + +Conditions that the *integrating project* must satisfy when using your SEooC. +The optional ``mitigates`` field describes (as a free-form string) the hazard +or risk that is mitigated when this assumption is fulfilled. + +Traceability to requirements is established at the Bazel level via the ``deps`` +attribute on the ``assumptions_of_use`` rule — there is no TRLC ``derived_from`` +or ``satisfies`` field on ``AoU``. + +.. code-block:: text + :caption: examples/seooc/docs/aous.trlc + + package SampleType + + import ScoreReq + + ScoreReq.AoU SampleAoU { + description = "It shall be made sure that this SampleAoU never ends up anywhere" + safety = ScoreReq.Asil.B + mitigates = "ShmemCreatedWrongName" + version = 1 + } + +.. code-block:: starlark + :caption: examples/seooc/docs/BUILD and examples/seooc/BUILD + + assumptions_of_use( + name = "sample_aous", + srcs = ["aous.trlc"], + ) + + dependable_element( + name = "safety_software_seooc_example", + assumptions_of_use = ["//docs:sample_aous"], + ... + ) + +AoU Forwarding +-------------- + +When a dependable element depends on another via ``deps``, all **assumptions of +use** defined by the dependency are automatically forwarded to the dependee. +This ensures the integrating project is made aware of every condition it must +satisfy — even those originating from transitive dependencies. + +There are two forwarding mechanisms: + +**Automatic forwarding (own AoUs)** +All AoUs declared in a dependable element's ``assumptions_of_use`` attribute are +automatically forwarded to every element that lists it in ``deps``. No +configuration is needed. + +**Chain-forwarding (received AoUs)** +When a dependable element receives forwarded AoUs from its own dependencies, it +can selectively forward them further by providing an ``aou_forwarding`` YAML +file. Each entry requires a mandatory justification explaining *why* this AoU +is forwarded rather than handled locally: + +.. code-block:: yaml + :caption: examples/seooc/aou_forwarding.yaml + + forwarded_aous: + - aou_id: "OtherLibrary.TimingConstraint" + justification: > + This SEooC is a library component and has no control over the + invocation cycle time. The system integrator must ensure that + calls to the library do not exceed the 10ms cycle time constraint + imposed by the underlying other_seooc dependency. + +**Handling forwarded AoUs in the dependee** +Forwarded AoUs appear as a "Forwarded AoUs" tier in the dependee's lobster +traceability report. The dependee must handle each forwarded AoU by one of: + +- Linking it to a component requirement that addresses the assumption +- Linking it to a test that verifies the assumption is met +- Chain-forwarding it further (with justification) to its own dependees + +If a forwarded AoU is not handled, the ``bazel test`` traceability check will fail. + +**Example: three-level forwarding chain** (the real working code for this +example lives in ``examples/some_other_library``, ``examples/seooc``, and +``examples/integrator``) + +:: + + other_seooc → defines AoU: OtherLibrary.TimingConstraint + ↑ (deps) + safety_software_seooc_example → defines own AoU: SampleType.SampleAoU (auto-forwarded) + → chain-forwards received TimingConstraint via aou_forwarding.yaml + ↑ (deps) + integrator_seooc → receives SampleType.SampleAoU (auto-forwarded) + and OtherLibrary.TimingConstraint (chain-forwarded), must handle both + +.. code-block:: starlark + :caption: examples/seooc/BUILD + + dependable_element( + name = "safety_software_seooc_example", + assumptions_of_use = ["//docs:sample_aous"], + aou_forwarding = "aou_forwarding.yaml", + deps = ["@some_other_library//:other_seooc"], + ... + ) diff --git a/bazel/rules/rules_score/docs/user_guide/dependability_analysis.md b/bazel/rules/rules_score/docs/user_guide/dependability_analysis.md deleted file mode 100644 index 992fcbec..00000000 --- a/bazel/rules/rules_score/docs/user_guide/dependability_analysis.md +++ /dev/null @@ -1,227 +0,0 @@ - - -# Dependability Analysis - -The `dependability_analysis` rule summarizes the all the dependability analyses (Safety / Security) for a dependable element. A single element may have multiple dependability analyses. - -## Overview - -### Why safety analysis? - -Safety analysis is required to systematically identify failures that could violate safety goals and to demonstrate that appropriate countermeasures are in place. In ISO 26262 terms it provides the evidence that residual risk is acceptable. - -### How FMEA works - -A Failure Mode and Effects Analysis (FMEA) follows three steps for each public interface of the software module: - -1. **Identify failure modes** — apply structured fault models (see below) to each public interface to derive what can cause a violation of a overarching safety goal. -2. **Analyse effects and causes** — document the effect on the system and decompose to root causes using a Fault Tree Analysis (FTA). -3. **Define countermeasures** — for every root cause specify a `ControlMeasure` (or `PreventiveMeasure` / `Mitigation`) and trace it back through the FTA to the failure mode. - -### Fault models - -The failure modes to consider are defined by the SCORE process: - -> [FMEA Fault Models — Process Description](https://eclipse-score.github.io/process_description/main/process_areas/safety_analysis/guidance/fault_models_guideline.html#id1) - -The fault models cover three categories: **messages** (send/receive behaviour), **time constraints** (too early / too late), and **execution** (wrong result, loss, delay, corruption, non-determinism). The `Guideword` enum in the `ScoreReq` model maps each category to a structured label used in the `FailureMode` records. - -The description below covers the FMEA-based **safety** analysis for a software module. - -## Bazel Rule `dependability_analysis` - -```starlark -load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", - "dependability_analysis") - -dependability_analysis( - name = "my_da", - fmea = [":my_fmea"], -) -``` - -**Generated targets:** `` — build produces the documentation and traceability report; `bazel test` validates the full chain. - -## FMEA - -The Failure Mode and Effects Analysis (FMEA) is the core safety analysis method used by `dependability_analysis`. Each `fmea` target bundles four types of artifacts that must be linked together: - -| Artifact | Format | What it represents | -|---|---|---| -| **Public API Interfaces** | PlantUML (from `architectural_design.public_api`) | Interfaces where failures can manifest; referenced by `FailureMode.interface` | -| **Failure Modes** | TRLC (`.trlc`) | Effects identified in the FMEA: what can go wrong and its impact | -| **FTA Diagrams** | PlantUML (`.puml`) | Fault Tree Analysis: structural decomposition of each failure mode into root causes | -| **Control Measures** | TRLC (`.trlc`) | Countermeasures that address the root causes identified in the FTA | - -The public API connects the architectural view to the safety analysis: `FailureMode.interface` references an interface name defined in the `public_api` of the `architectural_design` target. - -The FTA artifacts are linked by a shared naming convention: the **TRLC fully-qualified record name** (package + record name) must match the **alias** used in the FTA PlantUML diagram. This is how traceability is established automatically in the report. - -### Failure Modes (TRLC) - -A failure mode is a `FailureMode` record in the `ScoreReq` model: - -```text -package MySeooc - -import ScoreReq - -ScoreReq.FailureMode FM_001 { - guidewords = [ScoreReq.Guideword.LossOfFunction] - description = "Key-value store returns stale data after power loss" - failureeffect = "Incorrect system state at startup" - safety = ScoreReq.Asil.B - interface = "KeyValueStore.read" - version = 1 -} -``` - -The TRLC fully-qualified name of this record is **`MySeooc.FM_001`**. This name is used as the `$TopEvent` alias in the FTA diagram. - -### FTA Diagrams (PlantUML) - -Each failure mode gets a Fault Tree Analysis diagram. A dedicated PlantUML metamodel (`fta_metamodel.puml`) provides the graphical elements — it is located at `plantuml/fta_metamodel.puml` in the score-tooling repository. Your diagram uses procedure calls from that metamodel; no standard PlantUML shapes are needed. - -Every `.puml` FTA file must begin with `!include fta_metamodel.puml` so that the procedure definitions are available. - -#### Available procedures - -| Procedure | Description | -|---|---| -| `$TopEvent(name, alias)` | The top-level failure mode. `alias` must equal the fully-qualified TRLC name of the corresponding `FailureMode` record (e.g. `MySeooc.FM_001`) | -| `$IntermediateEvent(name, alias, connection)` | An intermediate cause. `connection` is the **alias of the parent** node this event feeds into | -| `$BasicEvent(name, alias, connection)` | A root cause (leaf node). `alias` must equal the fully-qualified TRLC name of the corresponding `ControlMeasure` record. `connection` is the alias of the parent gate | -| `$AndGate(alias, connection)` | AND gate. All children must occur for the parent to trigger. `connection` is the alias of the parent node | -| `$OrGate(alias, connection)` | OR gate. Any single child is sufficient to trigger the parent. `connection` is the alias of the parent node | -| `$TransferInGate(name, alias, connection)` | Transfer-in gate linking to another FTA sub-tree | - -#### Linking procedures together - -Each element points to its **parent** via the `connection` parameter — the arrow goes *from* the element *up* to the parent. Build the tree bottom-up: - -1. Declare the `$TopEvent` first (no `connection` parameter — it is the root). -2. Declare gate(s) with `connection` set to the `$TopEvent` alias. -3. Declare `$BasicEvent` / `$IntermediateEvent` nodes with `connection` set to the enclosing gate's alias. - -``` -$TopEvent ← root, no connection - └── $OrGate(alias="OG_1", connection="TopEvent.alias") - ├── $BasicEvent(alias="CM_A", connection="OG_1") - └── $BasicEvent(alias="CM_B", connection="OG_1") -``` - -The `$BasicEvent` **alias IS the fully-qualified TRLC name** (`Package.RecordName`) of the corresponding `ControlMeasure` record. No separate linking step is needed — the naming convention is the link. - -#### Example FTA diagram - -```{uml} ../_assets/MySeooc_FTA.puml -:align: center -:alt: Example FTA diagram -``` - -```text -@startuml MySeooc_FTA -!include fta_metamodel.puml - -$TopEvent("KVS returns stale data after power loss", "MySeooc.FM_001") - -$OrGate("OG_1", "MySeooc.FM_001") - -$BasicEvent("Write not flushed to storage", "MySeooc.RC_001", "OG_1") -$BasicEvent("Corruption on unclean shutdown", "MySeooc.RC_002", "OG_1") - -@enduml -``` - -### Control Measures (TRLC) - -For each `$BasicEvent` in your FTA diagram, define a `ControlMeasure` record whose fully-qualified name matches the event alias: - -```text -package MySeooc - -import ScoreReq - -ScoreReq.ControlMeasure RC_001 { - description = "The KVS implementation shall use a write-ahead log and - flush it synchronously before acknowledging a write" - safety = ScoreReq.Asil.B - version = 1 -} - -ScoreReq.ControlMeasure RC_002 { - description = "On startup, the KVS shall detect and recover from - partially written records using the write-ahead log" - safety = ScoreReq.Asil.B - version = 1 -} -``` - -The alias `MySeooc.RC_001` in the FTA diagram matches the TRLC record `RC_001` in package `MySeooc`. This is how the traceability link is established. - -#### Other measure types - -The SCORE requirements model also defines `PreventiveMeasure` and `Mitigation`, both extending the same abstract `Measure` base type as `ControlMeasure`. Their Bazel and TRLC usage follows the same pattern; the record type name changes but the FTA alias convention (package + record name matching the `$BasicEvent` alias) is identical. - -### `fmea` — Bazel Rule - -For the complete `fmea` attribute reference, see {ref}`fmea ` in the rule index. - -## Traceability Validation - -Running `bazel test //my/package:my_da` executes a traceability check that validates the complete chain: - -``` - public_api interface ← FailureMode.interface - | - $TopEvent - | - AND / OR gate(s) - | - $BasicEvent - | - ControlMeasure -``` - -The check fails if: - -- A `$TopEvent` alias does not match any `FailureMode` record name -- A `$BasicEvent` alias does not match any `ControlMeasure` record name -- A `FailureMode` or `ControlMeasure` is defined but not referenced in any FTA diagram - -Fixing a traceability error means ensuring the naming convention is followed precisely: the fully-qualified TRLC name (package + record name, e.g. `MySeooc.RC_001`) must be used verbatim as the alias in the FTA diagram. - -## Example - -```{code-block} starlark -load( - "@score_tooling//bazel/rules/rules_score:rules_score.bzl", - "dependability_analysis", - "fmea", -) - -fmea( - name = "sample_fmea", - failuremodes = ["//bazel/rules/rules_score/examples/seooc/safety_analysis:sample_fmea_failure_modes.trlc"], - controlmeasures = ["//bazel/rules/rules_score/examples/seooc/safety_analysis:sample_fmea_control_measures.trlc"], - root_causes = ["//bazel/rules/rules_score/examples/seooc/safety_analysis:sample_fta.puml"], - arch_design = "//bazel/rules/rules_score/examples/seooc/design:sample_seooc_design", -) - -dependability_analysis( - name = "sample_dependability_analysis", - arch_design = "//bazel/rules/rules_score/examples/seooc/design:sample_seooc_design", - fmea = [":sample_fmea"], -) -``` diff --git a/bazel/rules/rules_score/docs/user_guide/dependability_analysis.rst b/bazel/rules/rules_score/docs/user_guide/dependability_analysis.rst new file mode 100644 index 00000000..9f7661fd --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/dependability_analysis.rst @@ -0,0 +1,353 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Dependability Analysis +======================= + +.. note:: + A complete working example covering ``fmea`` and ``dependability_analysis`` is + available in + `bazel/rules/rules_score/examples/seooc/safety_analysis/ `_. + +The ``dependability_analysis`` rule summarizes all the dependability analyses +(Safety / Security) for a dependable element. A single element may have +multiple dependability analyses. + +Overview +-------- + +Why safety analysis? +~~~~~~~~~~~~~~~~~~~~~ + +Safety analysis is required to systematically identify failures that could +violate safety goals and to demonstrate that appropriate countermeasures are +in place. In ISO 26262 terms it provides the evidence that residual risk is +acceptable. + +How FMEA works +~~~~~~~~~~~~~~~ + +A Failure Mode and Effects Analysis (FMEA) follows three steps for each public +interface of the software module: + +1. **Identify failure modes** — apply structured fault models (see below) to + each public interface to derive what can cause a violation of a + overarching safety goal. +2. **Analyse effects and causes** — document the effect on the system and + decompose to root causes using a Fault Tree Analysis (FTA). +3. **Define countermeasures** — for every root cause specify a + ``ControlMeasure`` (or ``PreventiveMeasure`` / ``Mitigation``) and trace it + back through the FTA to the failure mode. + +Fault models +~~~~~~~~~~~~~ + +The failure modes to consider are defined by the SCORE process: + + `FMEA Fault Models — Process Description `_ + +The fault models cover three categories: **messages** (send/receive behaviour), +**time constraints** (too early / too late), and **execution** (wrong result, +loss, delay, corruption, non-determinism). The ``Guideword`` enum in the +``ScoreReq`` model maps each category to a structured label used in the +``FailureMode`` records. + +The description below covers the FMEA-based **safety** analysis for a +software module. + +Bazel Rule ``dependability_analysis`` +---------------------------------------- + +.. code-block:: starlark + + load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "dependability_analysis") + + dependability_analysis( + name = "my_da", + arch_design = ":my_arch", + fmea = [":my_fmea"], + ) + +**Generated targets:** ```` — build produces the documentation and +traceability report; ``bazel test`` validates the full chain. + +FMEA +---- + +The Failure Mode and Effects Analysis (FMEA) is the core safety analysis +method used by ``dependability_analysis``. Each ``fmea`` target bundles four +types of artifacts that must be linked together: + +.. list-table:: + :header-rows: 1 + + * - Artifact + - Format + - What it represents + * - **Public API Interfaces** + - PlantUML (from ``architectural_design.public_api``) + - Interfaces where failures can manifest; referenced by ``FailureMode.interface`` + * - **Failure Modes** + - TRLC (``.trlc``) + - Effects identified in the FMEA: what can go wrong and its impact + * - **FTA Diagrams** + - PlantUML (``.puml``) + - Fault Tree Analysis: structural decomposition of each failure mode into root causes + * - **Control Measures** + - TRLC (``.trlc``) + - Countermeasures that address the root causes identified in the FTA + +The public API connects the architectural view to the safety analysis: +``FailureMode.interface`` references an interface name defined in the +``public_api`` of the ``architectural_design`` target. + +The FTA artifacts are linked by a shared naming convention: the **TRLC +fully-qualified record name** (package + record name) must match the +**alias** used in the FTA PlantUML diagram. This is how traceability is +established automatically in the report. + +Failure Modes (TRLC) +~~~~~~~~~~~~~~~~~~~~~ + +A failure mode is a ``FailureMode`` record in the ``ScoreReq`` model. The +example below is taken from ``examples/seooc/safety_analysis``: + +.. code-block:: text + + package SampleLibrary + + import ScoreReq + + ScoreReq.FailureMode SampleFailureMode{ + guidewords = [ScoreReq.Guideword.LossOfFunction] + description = "SampleFailureMode takes over the world" + failureeffect = "The world as we know it will end" + version = 1 + safety = ScoreReq.Asil.B + interface = "SampleLibraryAPI.GetNumber" + } + +The TRLC fully-qualified name of this record is +**``SampleLibrary.SampleFailureMode``**. This name is used as the +``$TopEvent`` alias in the FTA diagram. + +FTA Diagrams (PlantUML) +~~~~~~~~~~~~~~~~~~~~~~~~ + +Each failure mode gets a Fault Tree Analysis diagram. A dedicated PlantUML +metamodel +(`fta_metamodel.puml `_) +provides the graphical elements — it is located at +``plantuml/fta_metamodel.puml`` in the score-tooling repository. Your diagram +uses procedure calls from that metamodel; no standard PlantUML shapes are +needed. + +Every ``.puml`` FTA file must begin with ``!include fta_metamodel.puml`` so +that the procedure definitions are available. + +Available procedures +^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + + * - Procedure + - Description + * - ``$TopEvent(name, alias)`` + - The top-level failure mode. ``alias`` must equal the fully-qualified TRLC name of the corresponding ``FailureMode`` record (e.g. ``SampleLibrary.SampleFailureMode``) + * - ``$IntermediateEvent(name, alias, connection)`` + - An intermediate cause. ``connection`` is the **alias of the parent** node this event feeds into + * - ``$BasicEvent(name, alias, connection)`` + - A root cause (leaf node). ``alias`` must equal the fully-qualified TRLC name of the corresponding ``ControlMeasure`` record. ``connection`` is the alias of the parent gate + * - ``$AndGate(alias, connection)`` + - AND gate. All children must occur for the parent to trigger. ``connection`` is the alias of the parent node + * - ``$OrGate(alias, connection)`` + - OR gate. Any single child is sufficient to trigger the parent. ``connection`` is the alias of the parent node + * - ``$TransferInGate(name, alias, connection)`` + - Transfer-in gate linking to another FTA sub-tree + +Linking procedures together +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Each element points to its **parent** via the ``connection`` parameter — the +arrow goes *from* the element *up* to the parent. Build the tree bottom-up: + +1. Declare the ``$TopEvent`` first (no ``connection`` parameter — it is the root). +2. Declare gate(s) with ``connection`` set to the ``$TopEvent`` alias. +3. Declare ``$BasicEvent`` / ``$IntermediateEvent`` nodes with ``connection`` + set to the enclosing gate's alias. + +:: + + $TopEvent ← root, no connection + └── $OrGate(alias="OG_1", connection="TopEvent.alias") + ├── $BasicEvent(alias="CM_A", connection="OG_1") + └── $BasicEvent(alias="CM_B", connection="OG_1") + +The ``$BasicEvent`` **alias IS the fully-qualified TRLC name** +(``Package.RecordName``) of the corresponding ``ControlMeasure`` record. No +separate linking step is needed — the naming convention is the link. + +Example FTA diagram +^^^^^^^^^^^^^^^^^^^^ + +.. uml:: ../_assets/SeoocExample_FTA.puml + :align: center + :alt: Example FTA diagram + +.. code-block:: text + + @startuml SeoocExample_FTA + !include fta_metamodel.puml + + $TopEvent("SampleFailureMode takes over the world", "SampleLibrary.SampleFailureMode") + + $OrGate("OG1", "SampleLibrary.SampleFailureMode") + + $IntermediateEvent("SampleFailureMode is Angry", "IEF", "OG1") + $BasicEvent("Just bad luck", "SampleLibrary.JustBadLuck", "OG1") + + $AndGate("AG2", "IEF") + $BasicEvent("No More Cookies", "SampleLibrary.NoMoreCookies", "AG2") + $BasicEvent("No More Coffee", "SampleLibrary.NoMoreCoffee", "AG2") + + @enduml + +Control Measures (TRLC) +~~~~~~~~~~~~~~~~~~~~~~~~ + +For each ``$BasicEvent`` in your FTA diagram, define a ``ControlMeasure`` +record whose fully-qualified name matches the event alias: + +.. code-block:: text + + package SampleLibrary + + import ScoreReq + + ScoreReq.ControlMeasure JustBadLuck{ + safety = ScoreReq.Asil.B + description = "Sometimes, the dark side wins. We shall be prepared for that." + version = 1 + } + + ScoreReq.ControlMeasure NoMoreCookies{ + safety = ScoreReq.Asil.B + description = "We shall only order family size cookie jars" + version = 1 + } + + ScoreReq.ControlMeasure NoMoreCoffee{ + safety = ScoreReq.Asil.B + description = "We shall keep a coffee reserve for emergencies" + version = 1 + } + +The alias ``SampleLibrary.JustBadLuck`` in the FTA diagram matches the TRLC +record ``JustBadLuck`` in package ``SampleLibrary`` — and likewise for +``NoMoreCookies``/``NoMoreCoffee``. This is how the traceability link is +established. + +Other measure types +^^^^^^^^^^^^^^^^^^^^ + +The SCORE requirements model also defines ``PreventiveMeasure`` and +``Mitigation``, both extending the same abstract ``Measure`` base type as +``ControlMeasure``. Their Bazel and TRLC usage follows the same pattern; the +record type name changes but the FTA alias convention (package + record name +matching the ``$BasicEvent`` alias) is identical. + +``fmea`` — Bazel Rule +~~~~~~~~~~~~~~~~~~~~~~ + +For the complete ``fmea`` attribute reference, see :ref:`fmea ` in +the rule index. + +Traceability Validation +------------------------ + +Running ``bazel test //my/package:my_da`` executes a traceability check that +validates the complete chain: + +:: + + public_api interface ← FailureMode.interface + | + $TopEvent + | + AND / OR gate(s) + | + $BasicEvent + | + ControlMeasure + +The check fails if: + +- A ``$TopEvent`` alias does not match any ``FailureMode`` record name +- A ``$BasicEvent`` alias does not match any ``ControlMeasure`` record name +- A ``FailureMode`` or ``ControlMeasure`` is defined but not referenced in any FTA diagram + +Fixing a traceability error means ensuring the naming convention is followed +precisely: the fully-qualified TRLC name (package + record name, e.g. +``SampleLibrary.JustBadLuck``) must be used verbatim as the alias in the FTA diagram. + +Example +------- + +The ``fmea`` rule's ``failuremodes``/``controlmeasures``/``root_causes`` +files must live in the **same package** as the ``fmea`` target itself (Bazel +does not allow referencing another package's raw source files without +``exports_files``). The parent ``dependability_analysis`` target then +references the ``fmea`` target by label: + +.. code-block:: starlark + :caption: bazel/rules/rules_score/examples/seooc/safety_analysis/BUILD + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "fmea", + ) + + filegroup( + name = "sample_fta", + srcs = [ + "sample_fta.puml", + "sample_fta2.puml", + ], + visibility = ["//visibility:public"], + ) + + fmea( + name = "sample_fmea", + arch_design = "//design:sample_seooc_design", + controlmeasures = ["sample_fmea_control_measures.trlc"], + failuremodes = ["sample_fmea_failure_modes.trlc"], + root_causes = [":sample_fta"], + visibility = ["//visibility:public"], + ) + +.. code-block:: starlark + :caption: bazel/rules/rules_score/examples/seooc/BUILD + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "dependability_analysis", + ) + + dependability_analysis( + name = "sample_dependability_analysis", + arch_design = "//design:sample_seooc_design", + fmea = ["//safety_analysis:sample_fmea"], + ) diff --git a/bazel/rules/rules_score/docs/user_guide/general.md b/bazel/rules/rules_score/docs/user_guide/general.md deleted file mode 100644 index 6a662bed..00000000 --- a/bazel/rules/rules_score/docs/user_guide/general.md +++ /dev/null @@ -1,115 +0,0 @@ - - -# General Information - -`rules_score` provides a set of Bazel rules that help you build and document a **Safety Element out of Context (SEooC)** — a safety-critical software component developed independently and delivered with all the evidence needed for integration into a safety-relevant system. - -By declaring your workproducts (requirements, architecture, units, safety analysis) as Bazel targets, `rules_score` automatically verifies traceability and consistency of all workproducts and assembles them into a Sphinx HTML documentation including the traceability report. - -## The Dependable Element Concept - -A *dependable element* is the top-level unit of certification work. It bundles: - -| Artifact | What it contains | -|---|---| -| Assumed System Requirements | System-level requirements given as constraints from the surrounding context | -| Feature Requirements | Functional and safety requirements for this element | -| Assumptions of Use | Conditions the integrating project must satisfy | -| Forwarded AoUs | Assumptions of use received from dependencies that must be handled or forwarded further | -| Architectural Design | Software Architectural Design in PlantUML | -| Software Units and Components | Implementation targets linked to their design | -| Dependability Analysis | FMEA, FTA diagrams and control measures | - -When you run `bazel build //:my_element`, all these pieces are assembled into a single HTML documentation site at `bazel-bin/my_element/html/`. - -## Build Flow - -The diagram below shows how your input files flow through the Bazel rules to produce the final outputs. - -```{uml} ../_assets/seooc_flow.puml -:align: center -:alt: SEooC build flow -:width: 90% -``` - -## Assembling a Dependable Element - -### Step 1 — Define your artifacts - -Define your requirements, architecture, units, and safety analysis using the rules described in the topic pages: - -- {doc}`requirements` — `assumed_system_requirements`, `feature_requirements`, `component_requirements`, `assumptions_of_use` -- {doc}`architectural_design` — `architectural_design`, `unit`, `component` -- {doc}`unit_design` — `unit_design` -- {doc}`dependability_analysis` — `fmea`, `dependability_analysis` - -### Step 2 — Wire them together - -```{code-block} starlark -dependable_element( - name = "safety_software_seooc_example", - architectural_design = ["//bazel/rules/rules_score/examples/seooc/design:sample_seooc_design"], - assumptions_of_use = [], - aou_forwarding = "aou_forwarding.yaml", # chain-forward selected received AoUs - components = [":component_example"], - dependability_analysis = [":sample_dependability_analysis"], - integrity_level = "B", - requirements = ["//bazel/rules/rules_score/examples/seooc/docs/requirements:feature_requirements"], - tests = [], - deps = ["//bazel/rules/rules_score/examples/some_other_library:other_seooc"], -) -``` - -### Step 3 — Build - -```bash -bazel build //my/package:my_element -``` - -Output: - -``` -bazel-bin/my/package/my_element/html/ ← HTML documentation -bazel-bin/my/package/my_element_index/ ← traceability report (JSON + HTML) -``` - -Run traceability checks: - -```bash -bazel test //my/package:my_element -``` - -## Rule Reference `dependable_element` - -For the complete `dependable_element` attribute reference, see {ref}`dependable_element ` in the rule index. - -## Automatic Validations - -`rules_score` enforces the following constraints at **build time** — the build fails if any of them are violated: - -TODO: Link here the Test Specifications for the Validations for more details - -### Architecture consistency - -The components and units declared in `dependable_element.components` are compared against the static PlantUML diagrams in `architectural_design`. Every component or unit that appears in the implementation tree must also appear in the architecture diagrams. - -### Certified scope - -Every Bazel target that is transitively referenced through `unit.implementation` must fall within the package tree declared by the `unit` and `component` targets belonging to this element. External library dependencies that are not safety-certified must not appear there. - -When `maturity = "development"` is set, scope violations are printed as warnings instead of failing the build. Switch back to `"release"` before certification. - -### Integrity level - -A `dependable_element` with `integrity_level = "B"` must not depend (via `deps`) on another `dependable_element` with `integrity_level = "A"`. The hierarchy is D > C > B > A. diff --git a/bazel/rules/rules_score/docs/user_guide/general.rst b/bazel/rules/rules_score/docs/user_guide/general.rst new file mode 100644 index 00000000..584100bb --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/general.rst @@ -0,0 +1,110 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +General Information +=================== + +``rules_score`` provides a set of Bazel rules that help you build and document a +**Safety Element out of Context (SEooC)** — a safety-critical software component +developed independently and delivered with all the evidence needed for integration +into a safety-relevant system. + +By declaring your workproducts (requirements, architecture, units, safety analysis) +as Bazel targets, ``rules_score`` automatically verifies traceability and consistency +of all workproducts and assembles them into a Sphinx HTML documentation including +the traceability report. + +The Dependable Element Concept +-------------------------------- + +A *dependable element* is the top-level entity: + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Artifact + - What it contains + * - Assumed System Requirements + - System-level requirements given as constraints from the surrounding context + * - Feature Requirements + - Functional and safety requirements for this element + * - Assumptions of Use + - Conditions the integrating project must satisfy + * - Forwarded AoUs + - Assumptions of use received from dependencies that must be handled or forwarded further + * - Architectural Design + - Software Architectural Design in PlantUML + * - Software Units and Components + - Implementation targets linked to their design + * - Dependability Analysis + - FMEA, FTA diagrams and control measures + +Architecture Overview +--------------------- + +The diagram below shows the full set of ``rules_score`` rules and how they relate +to each other. + +.. uml:: ../_assets/rules_score_overview.puml + :align: center + :alt: Overview of rules_score architecture + :width: 100% + +Getting Started +--------------- + +New to ``rules_score``? Work through the step-by-step +:doc:`tutorial/index` to build a minimal SEooC from scratch. + +Rule Reference ``dependable_element`` +-------------------------------------- + +For the complete ``dependable_element`` attribute reference, see +:ref:`dependable_element ` in the rule index. + +Automatic Validations +---------------------- + +``rules_score`` enforces the following constraints at **build time** — the build +fails if any of them are violated. +The validation logic is specified and tested via the +:doc:`../tool_reference/index`. + +Architecture consistency +~~~~~~~~~~~~~~~~~~~~~~~~ + +The components and units declared in ``dependable_element.components`` are +compared against the static PlantUML diagrams in ``architectural_design``. Every +component or unit that appears in the implementation tree must also appear in the +architecture diagrams. + +Certified scope +~~~~~~~~~~~~~~~ + +Every Bazel target that is transitively referenced through ``unit.implementation`` +must fall within the package tree declared by the ``unit`` and ``component`` +targets belonging to this element. External library dependencies that are not +safety-certified must not appear there. + +When ``maturity = "development"`` is set, scope violations are printed as +warnings instead of failing the build. Switch back to ``"release"`` before +certification. + +Integrity level +~~~~~~~~~~~~~~~ + +A ``dependable_element`` with ``integrity_level = "B"`` must not depend (via +``deps``) on another ``dependable_element`` with ``integrity_level = "A"``. The +hierarchy is D > C > B > A. diff --git a/bazel/rules/rules_score/docs/user_guide/index.rst b/bazel/rules/rules_score/docs/user_guide/index.rst index 20158d22..ee930a2d 100644 --- a/bazel/rules/rules_score/docs/user_guide/index.rst +++ b/bazel/rules/rules_score/docs/user_guide/index.rst @@ -16,10 +16,23 @@ User Guide ========== .. toctree:: + :caption: Overview :maxdepth: 2 general + +.. toctree:: + :caption: Tutorial + :maxdepth: 2 + + tutorial/index + +.. toctree:: + :caption: Guides + :maxdepth: 2 + requirements + assumptions_of_use architectural_design unit_design dependability_analysis diff --git a/bazel/rules/rules_score/docs/user_guide/requirements.md b/bazel/rules/rules_score/docs/user_guide/requirements.md deleted file mode 100644 index 1bd4a4f2..00000000 --- a/bazel/rules/rules_score/docs/user_guide/requirements.md +++ /dev/null @@ -1,339 +0,0 @@ - - -# Requirements - -`rules_score` provides three rules for capturing different levels of requirements. - -## Requirement Hierarchy & Traceability - -``` -AssumedSystemReq → FeatReq → CompReq - (System) (Feature) (Component) - \ ↑ - \________________________/ -``` - -```{list-table} -:header-rows: 1 -:widths: 18 47 35 - -* - Type - - Description - - Traceability -* - **AssumedSystemReq** - - Requirements from the user / assumed system towards the SEooC. - - Too high-level for a single component — can only be satisfied by - multiple components working together. - - Root — no parent -* - **FeatReq** - - Refined requirements derived from `AssumedSystemReq`. - - Used when assumed system requirements are too high-level to be broken - down directly to one component — still require multiple components. - - **Must** reference ≥ 1 `AssumedSystemReq` via `derived_from` -* - **CompReq** - - Requirements assigned to exactly one component. - - Can be directly implemented and tested within that component. - - Optionally references ≥ 1 `FeatReq` via `derived_from` - using `[Package.FeatReq@version]` -``` - -Traceability is enforced by the trlc type system — version pinning (e.g. `@1`) ensures that when a parent requirement changes, all downstream references must be explicitly updated. - -Each rule consumes one or more `.trlc` source files and produces a target that carries both a Sphinx documentation page and traceability information for downstream rules. The TRLC Type Model (.rsl file) is already included in the rule. - -## Modeling Requirements in TRLC - -All requirements are written in [TRLC](https://github.com/bmw-software-engineering/trlc) (Traceability Requirements Language Checker). Each record maps to a specific `ScoreReq` type defined in the [S-CORE requirements model](https://github.com/eclipse-score/tooling/blob/main/bazel/rules/rules_score/trlc/config/score_requirements_model.rsl). - -For `TRLC` both a VSCode Extension and a LSP Server (e.g. for Clion) are [available](https://github.com/bmw-software-engineering/trlc-vscode-extension) - -### Assumed System Requirements - -System-level requirements that your SEooC receives from the wider context — for example, from a system specification. - -```text -package MySeooc - -import ScoreReq - -ScoreReq.AssumedSystemReq SYSREQ_001 { - description = "The system shall provide a real-time clock interface" - safety = ScoreReq.Asil.B - rationale = "Required for time-stamped log entries" - version = 1 -} -``` - -### Feature Requirements - -```text -package MySeooc - -import ScoreReq - -ScoreReq.FeatReq FEAT_001 { - description = "The component shall store key-value pairs persistently" - safety = ScoreReq.Asil.B - derived_from = [MySeooc.SYSREQ_001@1] - version = 1 -} -``` - -### Component Requirements - -`derived_from` uses the versioned tuple syntax `[Package.RecordId@version]`. - -```text -package MySeooc - -import ScoreReq - -ScoreReq.CompReq COMP_001 { - description = "Write operations shall complete within 5 ms" - safety = ScoreReq.Asil.B - derived_from = [MySeooc.FEAT_001@1] - version = 1 -} -``` - -### Assumptions of Use - -Conditions that the *integrating project* must satisfy when using your SEooC. The optional `mitigates` field describes (as a free-form string) the hazard or risk that is mitigated when this assumption is fulfilled. - -Traceability to requirements is established at the Bazel level via the `requirements` attribute on the `assumptions_of_use` rule — there is no TRLC `derived_from` or `satisfies` field on `AoU`. - -```text -package MySeooc - -import ScoreReq - -ScoreReq.AoU AOU_001 { - description = "The integrator shall ensure exclusive write access to the storage partition" - safety = ScoreReq.Asil.B - mitigates = "ConcurrentWriteCorruption" - version = 1 -} -``` - -### AoU Forwarding - -When a dependable element depends on another via `deps`, all **assumptions of use** defined by the dependency are automatically forwarded to the dependee. This ensures the integrating project is made aware of every condition it must satisfy — even those originating from transitive dependencies. - -There are two forwarding mechanisms: - -**Automatic forwarding (own AoUs)** -All AoUs declared in a dependable element's `assumptions_of_use` attribute are automatically forwarded to every element that lists it in `deps`. No configuration is needed. - -**Chain-forwarding (received AoUs)** -When a dependable element receives forwarded AoUs from its own dependencies, it can selectively forward them further by providing an `aou_forwarding` YAML file. Each entry requires a mandatory justification explaining *why* this AoU is forwarded rather than handled locally: - -```yaml -# aou_forwarding.yaml -forwarded_aous: - - aou_id: "OtherLibrary.TimingConstraint" - justification: > - This timing constraint originates from the underlying library and - must be satisfied by the final system integrator who controls scheduling. -``` - -**Handling forwarded AoUs in the dependee** -Forwarded AoUs appear as a "Forwarded AoUs" tier in the dependee's lobster traceability report. The dependee must handle each forwarded AoU by one of: - -- Linking it to a component requirement that addresses the assumption -- Linking it to a test that verifies the assumption is met -- Chain-forwarding it further (with justification) to its own dependees - -If a forwarded AoU is not handled, the `bazel test` traceability check will fail. - -**Example: three-level forwarding chain** - -``` -other_seooc → defines AoU: TimingConstraint - ↑ (deps) -middle_seooc → auto-forwards TimingConstraint - - also chain-forwards it via aou_forwarding.yaml - ↑ (deps) -integrator_seooc → receives TimingConstraint, must handle it -``` - -```{code-block} starlark -:caption: middle_seooc/BUILD - -dependable_element( - name = "middle_seooc", - assumptions_of_use = [":my_aous"], - aou_forwarding = "aou_forwarding.yaml", - deps = ["//other:other_seooc"], - ... -) -``` - -## Allocation of Requirements to Architectural Elements - -Requirements are allocated to architectural elements differently depending on their level: - -**Component Requirements (`CompReq`)** -`CompReq` records are associated with exactly one component. The allocation is expressed implicitly through Bazel: the `component.requirements` attribute lists the `component_requirements` targets that belong to that component. Because a `component` maps directly to an architectural element in the static PlantUML diagram, the allocation to the architecture is established automatically. - -**Feature Requirements (`FeatReq`)** -`FeatReq` records operate at the integration level — they are too broad for a single component and can only be satisfied by multiple components working together. They are therefore allocated to the `dependable_element` as a whole via the Bazel `requirements` attribute: - -```starlark -dependable_element( - name = "my_element", - requirements = [":feature_requirements"], # FeatReq targets - ... -) -``` - -The traceability from `FeatReq` down to the components that implement it runs through the `component_requirements` chain (`FeatReq → CompReq → component`). - -(requirements-images)= -## Adding Images and Diagrams to Requirement Descriptions - -A requirement's `description` field can embed images and PlantUML diagrams so -they are rendered directly in the generated Sphinx documentation, right next -to the requirement text. - -**Markdown-style images** — use `![alt](path)`; it is converted to an RST -`.. image::` directive: - -```text -ScoreReq.CompReq COMP_002 { - description = '''The system shall expose the following architecture. - - ![Architecture overview](diagrams/arch.svg)''' - safety = ScoreReq.Asil.B - derived_from = [MySeooc.FEAT_001@1] - version = 1 -} -``` - -```{note} -Prefer `.svg` over `.png` for images checked into git. SVG is text-based and -diffs/compresses cleanly, whereas `.png` is a binary blob — every change adds a -full new copy to the git history and bloats the repository over time. -``` - -**PlantUML diagrams** — write a raw `.. uml::` RST directive; it is passed -through unmodified (any RST directive, e.g. `.. image::`, `.. figure::`, or -`.. uml::`, is preserved as-is): - -```text -ScoreReq.CompReq COMP_003 { - description = '''The `ClientConnection` shall maintain a state machine. - - .. uml:: client_connection_activity_diagram.puml''' - safety = ScoreReq.Asil.B - derived_from = [MySeooc.FEAT_001@1] - version = 1 -} -``` - -In both cases, the referenced file must also be declared via the `image_srcs` -attribute (available on `assumed_system_requirements`, `feature_requirements`, -and `component_requirements`) so it gets staged next to the rendered `.rst` -file. The path written in the directive must match the file's package-relative -path: - -```starlark -component_requirements( - name = "comp_req", - srcs = ["docs/requirements.trlc"], - image_srcs = [ - "diagrams/arch.svg", - "//path/to:client_connection_activity_diagram.puml", - ], -) -``` - -`image_srcs` accepts `.svg`, `.png`, and `.puml` files. `.puml` files require -`sphinxcontrib-plantuml` to be configured in the consuming project's Sphinx -`conf.py` (already the case for S-CORE projects using `architectural_design` -diagrams — see {ref}`RST and Markdown Wrappers `). - -## Modeling Requirements in Bazel Rules - -For the complete attribute reference for all requirements Bazel rules, see the rule index: - -- {ref}`assumed_system_requirements ` -- {ref}`feature_requirements ` -- {ref}`component_requirements ` -- {ref}`assumptions_of_use ` - -## Validation - -Every requirement target generates a `_test` target that runs `trlc --verify` on your `.trlc` sources. This check runs automatically as part of `bazel test ...`. - -The validation catches: - -- **Syntax errors** — malformed TRLC records -- **Type errors** — wrong value types for fields (e.g. a string where an enum is expected) -- **Mandatory field violations** — missing `description`, `safety`, or `version` -- **Broken cross-references** — a `derived_from` or `satisfies` pointing to a non-existent record -- **Unknown fields** — fields not defined in the S-CORE requirements model - -To run the validation for a single target: - -```bash -bazel test //my/package:my_feature_req_test -``` - -## AI-Powered Quality Check - -In addition to the structural TRLC validation described above, `rules_score` provides an optional AI-powered quality check for requirements via the `trlc_requirements_ai_test` rule. Unlike the structural check — which validates syntax, types, and cross-references — the AI check evaluates the *quality* of each requirement against requirements engineering guidelines (clarity, testability, completeness, etc.). - -### `trlc_requirements_ai_test` - -```starlark -load("@score_tooling//validation/ai_checker:ai_checker.bzl", - "trlc_requirements_ai_test") - -trlc_requirements_ai_test( - name = "feature_requirements_ai_check", - reqs = [":feature_requirements"], - score_threshold = "6.0", - tags = ["manual"], -) -``` - -The `tags = ["manual"]` attribute is strongly recommended to prevent the rule from running automatically during routine `bazel test //...` sweeps. The check requires a locally initialized copilot CLI or network access to an AI model in a cloudroom. - -Run the check explicitly with: - -```bash -bazel test //my/package:feature_requirements_ai_check -``` - -| Attribute | Type | Required | Description | -|---|---|---|---| -| `name` | string | yes | Target name | -| `reqs` | label list | yes | Requirement targets to analyse (any target providing `TrlcProviderInfo`, e.g. `feature_requirements`, `component_requirements`) | -| `model` | string | no | AI model identifier (default: `"anthropic/claude-sonnet-4-5"`) | -| `score_threshold` | string | no | Minimum average quality score from 0 to 10 to pass the test (default: `"0.0"`) | -| `guidelines` | label | no | Filegroup of guideline Markdown files to override the built-in guidelines | - -**Output files** (the AI analysis runs at test time; reports are written to the -test's undeclared-outputs archive at -`bazel-testlogs///test.outputs/outputs.zip`): - -| File | Content | -|---|---| -| `_analysis.json` | Machine-readable scores, findings, and suggestions per requirement | -| `_analysis.html` | Interactive HTML report with colour-coded score cards and guideline references | - -**Prerequisites:** a GitHub Copilot licence (default) or a custom AI model configured via the `_custom_ai_model` attribute — see `https://github.com/eclipse-score/tooling/blob/main/validation/ai_checker/README.md` in the score-tooling repository for details. diff --git a/bazel/rules/rules_score/docs/user_guide/requirements.rst b/bazel/rules/rules_score/docs/user_guide/requirements.rst new file mode 100644 index 00000000..15e2719c --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/requirements.rst @@ -0,0 +1,340 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Requirements +============ + +.. note:: + A complete working example covering all requirement rules is available in + `bazel/rules/rules_score/examples/seooc/ `_ (standalone Bazel workspace). + +``rules_score`` provides three rules for capturing different levels of requirements. + +Requirement Hierarchy & Traceability +------------------------------------- + +:: + + AssumedSystemReq → FeatReq → CompReq + (System) (Feature) (Component) + \ ↑ + \________________________/ + +.. list-table:: + :header-rows: 1 + :widths: 18 47 35 + + * - Type + - Description + - Traceability + * - **AssumedSystemReq** + - Requirements from the user / assumed system towards the SEooC. + + Too high-level for a single component — can only be satisfied by + multiple components working together. + - Root — no parent + * - **FeatReq** + - Refined requirements derived from ``AssumedSystemReq``. + + Used when assumed system requirements are too high-level to be broken + down directly to one component — still require multiple components. + - **Must** reference ≥ 1 ``AssumedSystemReq`` via ``derived_from`` + * - **CompReq** + - Requirements assigned to exactly one component. + + Can be directly implemented and tested within that component. + - Optionally references ≥ 1 ``FeatReq`` via ``derived_from`` + using ``[Package.FeatReq@version]`` + +Traceability throughout the complete requirements traceability is performed via TRLC. +It includes also (manual) version pinning (e.g. ``@1``) of requirements, which ensures +that when a parent requirement changes its content (and thus version), all downstream +references must be explicitly updated. + +Modeling Requirements +--------------------- + +All requirements are written in `TRLC `_ +(Traceability Requirements Language Checker). Each record maps to a specific ``ScoreReq`` +type defined in the +`S-CORE requirements model `_. + +For ``TRLC`` both a VSCode Extension and a LSP Server (e.g. for Clion) are +`available `_ + +Assumed System Requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +System-level requirements that your SEooC receives from the wider context — for example, +from a system specification. The excerpt below is taken from the reference example's +`assumed_system_requirements.trlc `_: + +.. code-block:: text + + package SampleSEooC + + import ScoreReq + + ScoreReq.AssumedSystemReq ASR_SAMPLE_001 { + description = "The system shall provide safe and reliable numeric value management through encapsulated classes, compliant with the selected :term:`integrity level`." + safety = ScoreReq.Asil.B + version = 1 + rationale = "System-level requirement for managing numeric values in a safety-critical context" + } + +.. code-block:: starlark + :caption: docs/requirements/BUILD + + assumed_system_requirements( + name = "assumed_system_requirements", + srcs = ["assumed_system_requirements.trlc"], + visibility = ["//visibility:public"], + ) + +Feature Requirements +~~~~~~~~~~~~~~~~~~~~~ + +Taken from +`feature_requirements.trlc `_, +derived from the ``ASR_SAMPLE_001`` requirement above: + +.. code-block:: text + + package SampleSEooC + + import ScoreReq + + ScoreReq.FeatReq FEAT_001 { + description = "The :term:`component` shall provide a numeric value management interface that returns a `uint8_t` value on every read access, aligned with the :term:`feature requirements`." + safety = ScoreReq.Asil.B + derived_from = [SampleSEooC.ASR_SAMPLE_001@1] + version = 1 + } + +.. code-block:: starlark + :caption: docs/requirements/BUILD + + feature_requirements( + name = "feature_requirements", + srcs = ["feature_requirements.trlc"], + visibility = ["//visibility:public"], + deps = [":assumed_system_requirements"], + ) + +Component Requirements +~~~~~~~~~~~~~~~~~~~~~~~ + +``derived_from`` uses the versioned tuple syntax ``[Package.RecordId@version]`` and may +reference more than one parent requirement, as ``REQ_COMP_004`` does below. Taken from +`component_requirements.trlc `_: + +.. code-block:: text + + package SampleComponent + + import ScoreReq + import SampleSEooC + + ScoreReq.CompReq REQ_COMP_001 { + description = "The numeric value management interface shall provide a read operation that returns a uint8_t value" + safety = ScoreReq.Asil.B + derived_from = [SampleSEooC.FEAT_001@1] + version = 1 + } + + ScoreReq.CompReq REQ_COMP_004 { + description = "The numeric value validator shall accept a numeric value manager instance as its sole constructor argument" + safety = ScoreReq.Asil.B + derived_from = [SampleSEooC.FEAT_003@1, SampleSEooC.FEAT_004@1] + version = 1 + } + +.. code-block:: starlark + :caption: docs/requirements/BUILD + + component_requirements( + name = "component_requirements", + srcs = ["component_requirements.trlc"], + visibility = ["//visibility:public"], + deps = [ + ":assumed_system_requirements", + ":feature_requirements", + ], + ) + +Validation +---------- + +Every requirement target generates a ``_test`` target that runs ``trlc --verify`` +on your ``.trlc`` sources. This check runs automatically as part of ``bazel test ...``. + +The validation catches: + +- **Syntax errors** — malformed TRLC records +- **Type errors** — wrong value types for fields (e.g. a string where an enum is expected) +- **Mandatory field violations** — missing ``description``, ``safety``, or ``version`` +- **Broken cross-references** — a ``derived_from`` or ``satisfies`` pointing to a non-existent record +- **Unknown fields** — fields not defined in the S-CORE requirements model + +To run the validation for a single target: + +.. code-block:: bash + + bazel test //my/package:my_feature_req_test + +.. _requirements-images: + +Adding Images and Diagrams to Requirement Descriptions +-------------------------------------------------------- + +A requirement's ``description`` field can embed images and PlantUML diagrams so +they are rendered directly in the generated Sphinx documentation, right next +to the requirement text. + +**Markdown-style images** — use ``![alt](path)``; it is converted to an RST +``.. image::`` directive: + +.. code-block:: text + + ScoreReq.CompReq COMP_002 { + description = '''The system shall expose the following architecture. + + ![Architecture overview](diagrams/arch.svg)''' + safety = ScoreReq.Asil.B + derived_from = [MySeooc.FEAT_001@1] + version = 1 + } + +**PlantUML diagrams** — write a raw ``.. uml::`` RST directive; it is passed +through unmodified (any RST directive, e.g. ``.. image::``, ``.. figure::``, or +``.. uml::``, is preserved as-is): + +.. code-block:: text + + ScoreReq.CompReq COMP_003 { + description = '''The `ClientConnection` shall maintain a state machine. + + .. uml:: client_connection_activity_diagram.puml''' + safety = ScoreReq.Asil.B + derived_from = [MySeooc.FEAT_001@1] + version = 1 + } + +In both cases, the referenced file must also be declared via the ``image_srcs`` +attribute (available on ``assumed_system_requirements``, ``feature_requirements``, +and ``component_requirements``) so it gets staged next to the rendered ``.rst`` +file. The path written in the directive must match the file's package-relative +path: + +.. code-block:: starlark + + component_requirements( + name = "comp_req", + srcs = ["docs/requirements.trlc"], + image_srcs = [ + "diagrams/arch.svg", + "//path/to:client_connection_activity_diagram.puml", + ], + ) + +.. note:: + Prefer ``.svg`` over ``.png`` for images checked into git. SVG is text-based and + diffs/compresses cleanly, whereas ``.png`` is a binary blob — every change adds a + full new copy to the git history and bloats the repository over time. + +Allocation of Requirements to Architectural Elements +------------------------------------------------------ + +Requirements are allocated to architectural elements differently depending on their level: + +**Component Requirements (``CompReq``)** +``CompReq`` records are associated with exactly one component. The allocation is +expressed implicitly through Bazel: The Bazel Component rule exposes an attribute +for requirements that accepts any component_requirements target. However, since +the entire file is assigned to a single component, requirements must be split into +separate files. + +.. code-block:: starlark + + component( + name = "MyComponent", + components = [":MyUnit"], + requirements = [":component_requirements"], + tests = [], + ) + +**Feature Requirements (``FeatReq``)** +``FeatReq`` records operate at the integration level — they are too broad for a +single component and can only be satisfied by multiple components working together. +They are therefore allocated to the ``dependable_element`` as a whole via the Bazel +``requirements`` attribute: + +.. code-block:: starlark + + dependable_element( + name = "my_element", + requirements = [":feature_requirements"], # FeatReq targets + ... + ) + +The traceability from ``FeatReq`` down to the components that implement it runs +through the ``component_requirements`` chain (``FeatReq → CompReq → component``). + +AI-Powered Quality Check +------------------------ + +In addition to the structural TRLC validation described above, ``rules_score`` +provides an AI-powered quality check for requirements via the +``trlc_requirements_ai_test`` rule. Unlike the structural check — which validates +syntax, types, and cross-references — the AI check evaluates the *quality* of each +requirement against requirements engineering guidelines (clarity, testability, +completeness, etc.). However since LLM are not deterministic, it is not recommended +to run it in the CI. + +``trlc_requirements_ai_test`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: starlark + + load("@score_tooling//validation/ai_checker:ai_checker.bzl", + "trlc_requirements_ai_test") + + trlc_requirements_ai_test( + name = "feature_requirements_ai_check", + reqs = [":feature_requirements"], + score_threshold = "6.0", + tags = ["manual"], + ) + +Run the check explicitly with: + +.. code-block:: bash + + bazel test //my/package:feature_requirements_ai_check + +**Prerequisites:** a GitHub Copilot licence (default) or a custom AI model +configured via the ``_custom_ai_model`` attribute — see +``https://github.com/eclipse-score/tooling/blob/main/validation/ai_checker/README.md`` +in the score-tooling repository for details. + +Modeling Requirements in Bazel Rules +-------------------------------------- + +For the complete attribute reference for all requirements Bazel rules, see the +rule index: + +- :ref:`assumed_system_requirements ` +- :ref:`feature_requirements ` +- :ref:`component_requirements ` +- :ref:`assumptions_of_use ` diff --git a/bazel/rules/rules_score/docs/user_guide/tutorial/architecture.rst b/bazel/rules/rules_score/docs/user_guide/tutorial/architecture.rst new file mode 100644 index 00000000..f9c32b33 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/tutorial/architecture.rst @@ -0,0 +1,89 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Step 2 — SW Architectural Design +================================ + +Once the requirements are in place, add a static architecture diagram that names: + +- the SEooC +- its components, and +- its units + +During the build process every plantuml diagram will be parsed and checked for consistency +with the implemented architecture / design. To enable this certain rules and guidelines have +to be followed while implementing the architecture diagram. + +The conventions to define those architectural elements are displayed in the following example. + +static_design.puml +------------------ + +.. literalinclude:: ../../examples/minimal/docs/static_design.puml + :language: text + :lines: 14- + +BUILD +------ + +.. code-block:: starlark + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "architectural_design", + ) + + architectural_design( + name = "my_arch", + static = ["docs/static_design.puml"], + ) + +After designing the target architecture in plantuml the real architecture has to be implemented +in Bazel. Therefore following bazel rules are available: + +.. code-block:: starlark + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "component", + "dependable_element", + "unit", + ) + + dependable_element( + name = "my_element", + ... + architectural_design = [":my_arch"], + components = [":MyComponent"], + requirements = [":feature_requirements"], + ... + ) + + unit( + name = "MyUnit", + implementation = [], + unit_design = [], + tests = [], + ) + + component( + name = "MyComponent", + components = [":MyUnit"], + requirements = [], + tests = [], + ) + +Once the architecture is in place, the build parses the PlantUML diagram and validates it against the Bazel model. It verifies element names, structural hierarchy, and consistency between the declared diagram and the implemented architecture. + +→ Full guide: :doc:`../architectural_design` diff --git a/bazel/rules/rules_score/docs/user_guide/tutorial/build.rst b/bazel/rules/rules_score/docs/user_guide/tutorial/build.rst new file mode 100644 index 00000000..be1f538c --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/tutorial/build.rst @@ -0,0 +1,46 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + + +Step 5 — Build +================ + +During Development you can enable a build with warnings instead of errors for all checks: + +``maturity = "development"`` + +Run the build from within the ``examples/minimal/`` standalone module: + +.. code-block:: bash + + bazel build //:my_element + +Expected output files: + +.. code-block:: text + + bazel-bin/my_element_doc/html/ ← Sphinx HTML documentation + +When integrating the element into your own workspace, reference it by its full +package label: + +.. code-block:: bash + + bazel build //my/package:my_element + +Run all validations (architecture consistency, scope checks, traceability): + +.. code-block:: bash + + bazel test //my/package:my_element diff --git a/bazel/rules/rules_score/docs/user_guide/tutorial/index.rst b/bazel/rules/rules_score/docs/user_guide/tutorial/index.rst new file mode 100644 index 00000000..506c050e --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/tutorial/index.rst @@ -0,0 +1,36 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + + +Tutorial: Your First Dependable Element +======================================== + +This tutorial walks you through building a minimal +**Safety Element out of Context (SEooC)** step by step. All examples are taken +from the standalone module at +`bazel/rules/rules_score/examples/minimal/ `_ +(standalone module) — you can run each step there with +``bazel build //:my_element``. + +By the end you will have a fully validated SEooC with requirements, a static +architecture diagram, a unit design, and a passing build. + +.. toctree:: + :maxdepth: 1 + + requirements + architecture + unit_design + validation + build diff --git a/bazel/rules/rules_score/docs/user_guide/tutorial/requirements.rst b/bazel/rules/rules_score/docs/user_guide/tutorial/requirements.rst new file mode 100644 index 00000000..4325b2b5 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/tutorial/requirements.rst @@ -0,0 +1,80 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Step 1 — Requirements +====================== + +A ``dependable_element`` starts with TRLC requirement files and their +corresponding Bazel targets. Dependent on it´s size and complexity, a dependable element can have two +or three levels of requirements. This means that a component requirement can be linked both to an +assumed system and feature requirement. + +Assumed System Requirements +---------------------------- + +``requirements/asr.trlc`` captures the constraints imposed on this element by the +surrounding system context: + +.. literalinclude:: ../../examples/minimal/requirements/asr.trlc + :language: text + +Feature Requirements +--------------------- + +``requirements/feature_requirements.trlc`` lists the functional and safety +requirements for this element, each referencing its parent assumed system +requirement via ``derived_from``: + +.. literalinclude:: ../../examples/minimal/requirements/feature_requirements.trlc + :language: text + +BUILD +------ + +.. code-block:: starlark + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "assumed_system_requirements", + "dependable_element", + "feature_requirements", + ) + + assumed_system_requirements( + name = "assumed_system_requirements", + srcs = ["requirements/asr.trlc"], + ) + + feature_requirements( + name = "feature_requirements", + srcs = ["requirements/feature_requirements.trlc"], + deps = [":assumed_system_requirements"], + ) + + dependable_element( + name = "my_element", + integrity_level = "B", + requirements = [":feature_requirements"], + assumptions_of_use = [], + architectural_design = [], + components = [], + dependability_analysis = [], + tests = [], + ) + +To validate TRLC syntax and Traceability within the requirements, each of the requirements +bazel targets exposes via a marco already a test target, which can be run via e.g.: +``bazel test //:assumed_system_requirements_test``. + +→ Full guide: :doc:`../requirements` diff --git a/bazel/rules/rules_score/docs/user_guide/tutorial/unit_design.rst b/bazel/rules/rules_score/docs/user_guide/tutorial/unit_design.rst new file mode 100644 index 00000000..1aef53a1 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/tutorial/unit_design.rst @@ -0,0 +1,83 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Step 3 — Unit Design +====================== + +A ``unit`` bazel target is defined via its implementation, corresponding tests and design. +So in a first step the class / sequence diagrams for a sw unit need to be defined: + +class_design.puml +------------------ + +.. literalinclude:: ../../examples/minimal/docs/class_design.puml + :language: text + :lines: 14- + +src/my_unit.h +-------------- + +The public interface of the unit can be tied to its source symbols via a ``// trace:`` tag. + +.. literalinclude:: ../../examples/minimal/src/my_unit.h + :language: cpp + :lines: 14- + +src/my_unit.cpp +---------------- + +.. literalinclude:: ../../examples/minimal/src/my_unit.cpp + :language: cpp + :lines: 14- + +BUILD +------ + +Add a ``unit_design`` target, wire up the implementation, and reference both +from the ``unit``: + +.. code-block:: starlark + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "unit", + "unit_design", + ) + + unit_design( + name = "MyUnit_design", + static = ["docs/class_design.puml"], + ) + + cc_library( + name = "my_unit_lib", + srcs = ["src/my_unit.cpp"], + hdrs = ["src/my_unit.h"], + ) + + unit( + name = "MyUnit", + implementation = [":my_unit_lib"], + scope = ["//:my_unit_lib"], + unit_design = [":MyUnit_design"], + tests = [], + ) + +The ``unit_design.static`` attribute accepts PlantUML files (class, state, +object diagrams); use ``dynamic`` for sequence and activity diagrams. +``scope`` declares which targets the unit "owns" — targets outside the scope +that appear in the transitive implementation closure fail the scope check at +build time. + +→ Full guide: :doc:`../unit_design` diff --git a/bazel/rules/rules_score/docs/user_guide/tutorial/validation.rst b/bazel/rules/rules_score/docs/user_guide/tutorial/validation.rst new file mode 100644 index 00000000..f7f872e8 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/tutorial/validation.rst @@ -0,0 +1,66 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Step 4 — Validation +===================== + +Test targets can be defined on different architectural levels. They are attached to ``unit``, ``component``, and +``dependable_element`` via the ``tests`` attribute. On ``component`` and ``dependable_element`` level, the test +should focus more on integration and system testing, while on ``unit`` level, the test should focus on unit testing. + + +``rules_score`` does not require a separate test specification document. +Instead, test intent is captured as a **Given-When-Then** description right +next to the code as record properties in the test name/body itself. The specification will +then be rendered in the traceability report, together with the test results and coverage information. + +test/my_unit_test.cpp +---------------------- + +.. literalinclude:: ../../examples/minimal/test/my_unit_test.cpp + :language: cpp + :lines: 14- + +Each ``RecordProperty("lobster-tracing", "...")`` call names the requirement +identifiers covered by that test case. + +BUILD +------ + +.. code-block:: starlark + + cc_test( + name = "my_unit_test", + srcs = ["test/my_unit_test.cpp"], + deps = [ + ":my_unit_lib", + "@googletest//:gtest_main", + ], + ) + + unit( + name = "MyUnit", + implementation = [":my_unit_lib"], + scope = ["//:my_unit_lib"], + unit_design = [":MyUnit_design"], + tests = [":my_unit_test"], + ) + +Run the tests with: + +.. code-block:: bash + + bazel test //:my_unit_test + +→ Full guide: :doc:`../unit_design` diff --git a/bazel/rules/rules_score/docs/user_guide/unit_design.md b/bazel/rules/rules_score/docs/user_guide/unit_design.md deleted file mode 100644 index 50a13217..00000000 --- a/bazel/rules/rules_score/docs/user_guide/unit_design.md +++ /dev/null @@ -1,26 +0,0 @@ - - -# Software Unit Design - -The `unit_design` rule documents the **internal implementation** of a single software unit — how its source code is structured, what data flows through it, and how it behaves at the code level. This is distinct from the higher-level architectural design diagrams (see {doc}`architectural_design`), which describe the intended component structure of the SEooC as a whole. - -A `unit_design` target is referenced by a `unit` target (see {doc}`architectural_design` — *Implementation Architecture in Bazel*) to attach code-level design artefacts to the unit. - -## `unit_design` — Code-Level Design Diagrams - -The `unit_design` rule attaches PlantUML diagrams to a unit. It uses the same `static` / `dynamic` category split as `architectural_design`, but scoped to a single unit's implementation. - -### `unit_design` Rule Reference - -For the complete `unit_design` attribute reference, see {ref}`unit_design ` in the rule index. diff --git a/bazel/rules/rules_score/docs/user_guide/unit_design.rst b/bazel/rules/rules_score/docs/user_guide/unit_design.rst new file mode 100644 index 00000000..eb5b7664 --- /dev/null +++ b/bazel/rules/rules_score/docs/user_guide/unit_design.rst @@ -0,0 +1,147 @@ +.. + # ******************************************************************************* + # 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 + # ******************************************************************************* + +Software Unit Design +===================== + +The ``unit_design`` rule documents the **internal implementation** of a single +software unit — how its source code is structured, what data flows through it, +and how it behaves at the code level. This is distinct from the higher-level +architectural design diagrams (see :doc:`architectural_design`), which describe +the intended component structure of the SEooC as a whole. + +A ``unit_design`` target is referenced by a ``unit`` target (see +:doc:`architectural_design` — *Implementation Architecture in Bazel*) to attach +code-level design artefacts to the unit. + +``unit_design`` — Code-Level Design Diagrams +----------------------------------------------- + +The ``unit_design`` rule attaches PlantUML diagrams to a unit. It uses the same +``static`` / ``dynamic`` category split as ``architectural_design``, but scoped +to a single unit's implementation. + +PlantUML +~~~~~~~~~ + +The example below is taken from ``examples/seooc``: ``unit_1`` implements a +class ``Foo``, and ``unit_2`` implements a class ``Bar`` that composes +``unit_1::Foo``. + +.. uml:: ../_assets/SeoocExample_UnitClassDiagram.puml + :align: center + :alt: SEooC example unit class diagram + +.. code-block:: text + + @startuml unit_class_diagram + + namespace unit_1 { + class Foo <>{ + -- + + GetNumber() : uint8_t + + SetNumber(value : uint8_t) : void + } + } + + namespace unit_2 { + class Bar <>{ + -- + - foo_ : unique_ptr + -- + + Bar(foo : unique_ptr) + + AssertNumber() : bool + } + } + + Bar --> Foo : uses + + @enduml + +Implementation +~~~~~~~~~~~~~~~ + +The class diagram above is generated from, and validated against, the real +unit implementation. ``foo.h`` declares the interface documented in the +diagram; ``// trace:`` comments tie each symbol to a requirement: + +.. code-block:: cpp + + #ifndef FOO_H + #define FOO_H + + #include + + namespace unit_1 { + + // trace: SampleComponent.REQ_COMP_002 + class Foo final { + public: + // trace: SampleComponent.REQ_COMP_001 SampleLibraryAPI.GetNumber + std::uint8_t GetNumber() const; + // trace: SampleLibraryAPI.SetNumber + void SetNumber(std::uint8_t value); + }; + + } // namespace unit_1 + + #endif // FOO_H + +``foo.cpp`` provides the implementation: + +.. code-block:: cpp + + #include "unit_1/foo.h" + + namespace unit_1 { + + // trace: SampleComponent.REQ_COMP_001 SampleLibraryAPI.GetNumber + std::uint8_t Foo::GetNumber() const { return 42u; } + } // namespace unit_1 + +Bazel +~~~~~~ + +.. code-block:: starlark + + load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "unit", + "unit_design", + ) + + unit_design( + name = "unit_design", + static = glob(["*.puml", "*.rst"]), + ) + + cc_library( + name = "unit_1_lib", + srcs = ["foo.cpp"], + hdrs = ["foo.h"], + ) + + unit( + name = "unit_1", + scope = ["//unit_1:unit_1_lib"], + implementation = [":unit_1_lib"], + unit_design = ["//unit_1/docs:unit_design"], + tests = [":unit_1_test"], + ) + +``unit_design`` Rule Reference +--------------------------------- + +For the complete ``unit_design`` attribute reference, see +:ref:`unit_design ` in the rule index. diff --git a/bazel/rules/rules_score/examples/integrator/.bazelrc b/bazel/rules/rules_score/examples/integrator/.bazelrc new file mode 100644 index 00000000..353114f1 --- /dev/null +++ b/bazel/rules/rules_score/examples/integrator/.bazelrc @@ -0,0 +1,8 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/ +common --registry=https://bcr.bazel.build + +common --extra_toolchains=//bazel/toolchains:integrator_libclang_toolchain diff --git a/bazel/rules/rules_score/examples/integrator/.bazelversion b/bazel/rules/rules_score/examples/integrator/.bazelversion new file mode 100644 index 00000000..f9c71a52 --- /dev/null +++ b/bazel/rules/rules_score/examples/integrator/.bazelversion @@ -0,0 +1 @@ +8.5.1 diff --git a/bazel/rules/rules_score/examples/integrator/BUILD b/bazel/rules/rules_score/examples/integrator/BUILD index 0a58c216..f060dd16 100644 --- a/bazel/rules/rules_score/examples/integrator/BUILD +++ b/bazel/rules/rules_score/examples/integrator/BUILD @@ -28,7 +28,7 @@ # load( - "//bazel/rules/rules_score:rules_score.bzl", + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", "architectural_design", "component", "dependable_element", @@ -40,7 +40,7 @@ cc_library( srcs = [], visibility = ["//visibility:public"], deps = [ - "//bazel/rules/rules_score/examples/seooc:sample_library", + "@seooc//:sample_library", ], ) @@ -51,7 +51,7 @@ architectural_design( unit( name = "integrator_unit", - scope = ["//bazel/rules/rules_score/examples/integrator:__pkg__"], + scope = ["//:__pkg__"], tests = [], unit_design = [], implementation = [":integrator_lib"], @@ -61,7 +61,7 @@ component( name = "integrator_component", components = [":integrator_unit"], requirements = [ - "//bazel/rules/rules_score/examples/integrator/docs/requirements:component_requirements", + "//docs/requirements:component_requirements", ], tags = ["manual"], tests = [], @@ -79,8 +79,8 @@ dependable_element( dependability_analysis = [], integrity_level = "B", requirements = [ - "//bazel/rules/rules_score/examples/integrator/docs/requirements:feature_requirements", + "//docs/requirements:feature_requirements", ], tests = [], - deps = ["//bazel/rules/rules_score/examples/seooc:safety_software_seooc_example"], + deps = ["@seooc//:safety_software_seooc_example"], ) diff --git a/bazel/rules/rules_score/examples/integrator/MODULE.bazel b/bazel/rules/rules_score/examples/integrator/MODULE.bazel new file mode 100644 index 00000000..f5e976c4 --- /dev/null +++ b/bazel/rules/rules_score/examples/integrator/MODULE.bazel @@ -0,0 +1,65 @@ +# ******************************************************************************* +# 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( + name = "integrator", + version = "0.0.0", +) + +bazel_dep(name = "score_tooling", version = "0.0.0") +local_path_override( + module_name = "score_tooling", + path = "../../../../..", +) + +# The integrator depends on safety_software_seooc_example, so it needs the +# seooc example module. See below for why this module registers its own +# libclang toolchain instead of reusing seooc's. +bazel_dep(name = "seooc", version = "0.0.0") +local_path_override( + module_name = "seooc", + path = "../seooc", +) + +# seooc's own MODULE.bazel overrides for its dependencies are only honored +# when seooc is the root module. Since seooc is a transitive dependency here, +# its overrides must be repeated by this (root) module too. +bazel_dep(name = "some_other_library", version = "0.0.0") +local_path_override( + module_name = "some_other_library", + path = "../some_other_library", +) + +bazel_dep(name = "trlc", version = "3.0.0") +bazel_dep(name = "googletest", version = "1.17.0.bcr.2") +bazel_dep(name = "lobster", version = "1.0.3") +git_override( + module_name = "lobster", + commit = "07382c33f95e22992e0f8788c0537ec06877e51f", + remote = "https://github.com/bmw-software-engineering/lobster.git", +) + +# seooc's own llvm toolchain extension is a dev_dependency, so it is only +# honored while seooc itself is the root module — it is stripped when seooc is +# merely a transitive dependency (as it is here). This module must therefore +# register its own libclang toolchain (see bazel/toolchains/BUILD) rather than +# reusing @seooc//bazel/toolchains:seooc_libclang_toolchain. +bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True) + +llvm = use_extension( + "@toolchains_llvm//toolchain/extensions:llvm.bzl", + "llvm", + dev_dependency = True, +) +llvm.toolchain(llvm_version = "19.1.7") +use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") diff --git a/bazel/rules/rules_score/examples/integrator/bazel/toolchains/BUILD b/bazel/rules/rules_score/examples/integrator/bazel/toolchains/BUILD new file mode 100644 index 00000000..022a0f60 --- /dev/null +++ b/bazel/rules/rules_score/examples/integrator/bazel/toolchains/BUILD @@ -0,0 +1,34 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +load( + "@score_tooling//cpp/libclang:libclang_toolchain.bzl", + "libclang_toolchain", +) + +# ============================================================================ +# libclang toolchain for the C++ parser used by score rules +# ============================================================================ +libclang_toolchain( + name = "integrator_libclang", + cxx_builtin_include = "@llvm_toolchain_llvm//:cxx_builtin_include", + extra_config_site = "@llvm_toolchain_llvm//:extra_config_site", + libclang = "@llvm_toolchain_llvm//:lib/libclang.so", +) + +toolchain( + name = "integrator_libclang_toolchain", + toolchain = ":integrator_libclang", + toolchain_type = "@score_tooling//cpp/libclang:libclang_toolchain_type", + visibility = ["//:__subpackages__"], +) diff --git a/bazel/rules/rules_score/examples/integrator/docs/requirements/BUILD b/bazel/rules/rules_score/examples/integrator/docs/requirements/BUILD index 28341d1e..50d8c6e9 100644 --- a/bazel/rules/rules_score/examples/integrator/docs/requirements/BUILD +++ b/bazel/rules/rules_score/examples/integrator/docs/requirements/BUILD @@ -11,7 +11,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -load("//bazel/rules/rules_score:rules_score.bzl", "assumed_system_requirements", "component_requirements", "feature_requirements") +load("@score_tooling//bazel/rules/rules_score:rules_score.bzl", "assumed_system_requirements", "component_requirements", "feature_requirements") assumed_system_requirements( name = "assumed_system_requirements", diff --git a/bazel/rules/rules_score/examples/minimal/.bazelrc b/bazel/rules/rules_score/examples/minimal/.bazelrc new file mode 100644 index 00000000..371cde4e --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/.bazelrc @@ -0,0 +1,8 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/ +common --registry=https://bcr.bazel.build + +common --extra_toolchains=//bazel/toolchains:minimal_libclang_toolchain diff --git a/bazel/rules/rules_score/examples/minimal/.bazelversion b/bazel/rules/rules_score/examples/minimal/.bazelversion new file mode 100644 index 00000000..f9c71a52 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/.bazelversion @@ -0,0 +1 @@ +8.5.1 diff --git a/bazel/rules/rules_score/examples/minimal/BUILD b/bazel/rules/rules_score/examples/minimal/BUILD new file mode 100644 index 00000000..e14bdab4 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/BUILD @@ -0,0 +1,103 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "architectural_design", + "assumed_system_requirements", + "component", + "dependable_element", + "feature_requirements", + "unit", + "unit_design", +) + +# Exposes source files to the parent workspace so that the rules_score_doc +# Sphinx build can reference them via sphinx_docs_library without copies. +filegroup( + name = "doc_sources", + srcs = [ + "docs/class_design.puml", + "docs/static_design.puml", + "requirements/asr.trlc", + "requirements/feature_requirements.trlc", + "src/my_unit.cpp", + "src/my_unit.h", + "test/my_unit_test.cpp", + ], + visibility = ["//bazel/rules/rules_score:__pkg__"], +) + +assumed_system_requirements( + name = "assumed_system_requirements", + srcs = ["requirements/asr.trlc"], + visibility = ["//visibility:public"], +) + +feature_requirements( + name = "feature_requirements", + srcs = ["requirements/feature_requirements.trlc"], + visibility = ["//visibility:public"], + deps = [":assumed_system_requirements"], +) + +architectural_design( + name = "my_arch", + static = ["docs/static_design.puml"], +) + +cc_library( + name = "my_unit_lib", + srcs = ["src/my_unit.cpp"], + hdrs = ["src/my_unit.h"], +) + +cc_test( + name = "my_unit_test", + srcs = ["test/my_unit_test.cpp"], + deps = [ + ":my_unit_lib", + "@googletest//:gtest_main", + ], +) + +unit_design( + name = "MyUnit_design", + static = ["docs/class_design.puml"], +) + +unit( + name = "MyUnit", + scope = ["//:my_unit_lib"], + tests = [":my_unit_test"], + unit_design = [":MyUnit_design"], + implementation = [":my_unit_lib"], +) + +component( + name = "MyComponent", + components = [":MyUnit"], + requirements = [], + tests = [], +) + +dependable_element( + name = "my_element", + architectural_design = [":my_arch"], + assumptions_of_use = [], + components = [":MyComponent"], + dependability_analysis = [], + integrity_level = "B", + requirements = [":feature_requirements"], + tests = [], +) diff --git a/bazel/rules/rules_score/examples/minimal/MODULE.bazel b/bazel/rules/rules_score/examples/minimal/MODULE.bazel new file mode 100644 index 00000000..3e143449 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/MODULE.bazel @@ -0,0 +1,42 @@ +# ******************************************************************************* +# 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( + name = "minimal_requirements", + version = "0.0.0", +) + +bazel_dep(name = "score_tooling", version = "0.0.0") +local_path_override( + module_name = "score_tooling", + path = "../../../../..", +) + +bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True) + +llvm = use_extension( + "@toolchains_llvm//toolchain/extensions:llvm.bzl", + "llvm", + dev_dependency = True, +) +llvm.toolchain(llvm_version = "19.1.7") +use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") + +bazel_dep(name = "trlc", version = "3.0.0") +bazel_dep(name = "googletest", version = "1.17.0.bcr.2") +bazel_dep(name = "lobster", version = "1.0.3") +git_override( + module_name = "lobster", + commit = "07382c33f95e22992e0f8788c0537ec06877e51f", + remote = "https://github.com/bmw-software-engineering/lobster.git", +) diff --git a/bazel/rules/rules_score/examples/minimal/bazel/toolchains/BUILD b/bazel/rules/rules_score/examples/minimal/bazel/toolchains/BUILD new file mode 100644 index 00000000..f69fd8d8 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/bazel/toolchains/BUILD @@ -0,0 +1,31 @@ +# ******************************************************************************* +# 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 +# ******************************************************************************* + +load( + "@score_tooling//cpp/libclang:libclang_toolchain.bzl", + "libclang_toolchain", +) + +libclang_toolchain( + name = "minimal_libclang", + cxx_builtin_include = "@llvm_toolchain_llvm//:cxx_builtin_include", + extra_config_site = "@llvm_toolchain_llvm//:extra_config_site", + libclang = "@llvm_toolchain_llvm//:lib/libclang.so", +) + +toolchain( + name = "minimal_libclang_toolchain", + toolchain = ":minimal_libclang", + toolchain_type = "@score_tooling//cpp/libclang:libclang_toolchain_type", + visibility = ["//:__subpackages__"], +) diff --git a/bazel/rules/rules_score/docs/_assets/MySeooc_FTA.puml b/bazel/rules/rules_score/examples/minimal/docs/class_design.puml similarity index 65% rename from bazel/rules/rules_score/docs/_assets/MySeooc_FTA.puml rename to bazel/rules/rules_score/examples/minimal/docs/class_design.puml index 596187fc..b36a023b 100644 --- a/bazel/rules/rules_score/docs/_assets/MySeooc_FTA.puml +++ b/bazel/rules/rules_score/examples/minimal/docs/class_design.puml @@ -11,15 +11,14 @@ ' SPDX-License-Identifier: Apache-2.0 ' ******************************************************************************* -@startuml MySeooc_FTA +@startuml -!include fta_metamodel.puml +' Class diagram for MyUnit — internal design of the key-value store unit. -$TopEvent("KVS returns stale data after power loss", "MySeooc.FM_001") - -$OrGate("OG_1", "MySeooc.FM_001") - -$BasicEvent("Write not flushed to storage", "MySeooc.RC_001", "OG_1") -$BasicEvent("Corruption on unclean shutdown", "MySeooc.RC_002", "OG_1") +class MyUnit { + - _store : dict[str, str] + + configure(key : str, value : str) : void + + get(key : str) : str +} @enduml diff --git a/bazel/rules/rules_score/examples/minimal/docs/static_design.puml b/bazel/rules/rules_score/examples/minimal/docs/static_design.puml new file mode 100644 index 00000000..29648237 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/docs/static_design.puml @@ -0,0 +1,23 @@ +' ******************************************************************************* +' 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 +' ******************************************************************************* + +@startuml + +' The package alias must match the dependable_element target name. +package "my_element" as my_element <> { + component "MyComponent" as MyComponent <> { + component "MyUnit" as MyUnit <> + } +} + +@enduml diff --git a/bazel/rules/rules_score/examples/minimal/requirements/asr.trlc b/bazel/rules/rules_score/examples/minimal/requirements/asr.trlc new file mode 100644 index 00000000..958db3d9 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/requirements/asr.trlc @@ -0,0 +1,23 @@ +/******************************************************************************** + * 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 + ********************************************************************************/ + +package MinimalExample + +import ScoreReq + +ScoreReq.AssumedSystemReq ASR_001 { + description = "The system shall support configurable key-value parameters accessible at runtime" + safety = ScoreReq.Asil.B + rationale = "Runtime configuration is required so the component can be adapted without recompilation" + version = 1 +} diff --git a/bazel/rules/rules_score/examples/minimal/requirements/feature_requirements.trlc b/bazel/rules/rules_score/examples/minimal/requirements/feature_requirements.trlc new file mode 100644 index 00000000..a6877688 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/requirements/feature_requirements.trlc @@ -0,0 +1,30 @@ +/******************************************************************************** + * 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 + ********************************************************************************/ + +package MinimalExample + +import ScoreReq + +ScoreReq.FeatReq FEAT_001 { + description = "The component shall store configuration parameters persistently across restarts" + safety = ScoreReq.Asil.B + derived_from = [MinimalExample.ASR_001@1] + version = 1 +} + +ScoreReq.FeatReq FEAT_002 { + description = "The component shall provide read access to all stored configuration parameters" + safety = ScoreReq.Asil.B + derived_from = [MinimalExample.ASR_001@1] + version = 1 +} diff --git a/bazel/rules/rules_score/examples/minimal/src/my_unit.cpp b/bazel/rules/rules_score/examples/minimal/src/my_unit.cpp new file mode 100644 index 00000000..7c11009e --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/src/my_unit.cpp @@ -0,0 +1,23 @@ +/******************************************************************************** + * Copyright (c) 2025 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 + ********************************************************************************/ + +#include "src/my_unit.h" + +void MyUnit::configure(const std::string &key, const std::string &value) { + store_[key] = value; +} + +std::string MyUnit::get(const std::string &key) const { + const auto it = store_.find(key); + return it != store_.end() ? it->second : ""; +} diff --git a/bazel/rules/rules_score/examples/minimal/src/my_unit.h b/bazel/rules/rules_score/examples/minimal/src/my_unit.h new file mode 100644 index 00000000..10160d0c --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/src/my_unit.h @@ -0,0 +1,29 @@ +/******************************************************************************** + * 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 + ********************************************************************************/ + +#pragma once + +#include +#include + +class MyUnit { +public: + // trace: MinimalExample.FEAT_001 + void configure(const std::string &key, const std::string &value); + + // trace: MinimalExample.FEAT_002 + std::string get(const std::string &key) const; + +private: + std::unordered_map store_; +}; diff --git a/bazel/rules/rules_score/examples/minimal/test/my_unit_test.cpp b/bazel/rules/rules_score/examples/minimal/test/my_unit_test.cpp new file mode 100644 index 00000000..378489a9 --- /dev/null +++ b/bazel/rules/rules_score/examples/minimal/test/my_unit_test.cpp @@ -0,0 +1,32 @@ +/******************************************************************************** + * Copyright (c) 2025 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 + ********************************************************************************/ + +#include + +#include "src/my_unit.h" + +TEST(MyUnitTest, ConfigureAndGet) { + ::testing::Test::RecordProperty( + "lobster-tracing", "MinimalExample.FEAT_001 MinimalExample.FEAT_002"); + + MyUnit unit; + unit.configure("mode", "fast"); + EXPECT_EQ(unit.get("mode"), "fast"); +} + +TEST(MyUnitTest, MissingKeyReturnsEmpty) { + ::testing::Test::RecordProperty("lobster-tracing", "MinimalExample.FEAT_002"); + + MyUnit unit; + EXPECT_EQ(unit.get("undefined"), ""); +} diff --git a/bazel/rules/rules_score/examples/seooc/BUILD b/bazel/rules/rules_score/examples/seooc/BUILD index 6a1f476b..817383dd 100644 --- a/bazel/rules/rules_score/examples/seooc/BUILD +++ b/bazel/rules/rules_score/examples/seooc/BUILD @@ -32,10 +32,30 @@ component( components = [ "//unit_1:unit_1", "//unit_2:unit_2", + ":sub_component_example", ], + # component_requirements_sub is also listed here (in addition to + # sub_component_example's own requirements below) so its CompReq item is + # visible in the dependable_element-level traceability report -- nested + # components' own `requirements` are not rolled up automatically into + # their parent's Component Requirements tier (see test/BUILD's + # test_nested_component/test_parent_component fixture for the same + # pattern). requirements = [ "//docs/requirements:component_requirements", "//docs/requirements:component_requirements_extra", + "//docs/requirements:component_requirements_sub", + ], + tags = ["manual"], + tests = [], +) + +# Nested component: components can themselves contain further components, +# not just units (see docs/user_guide/architectural_design.rst). +component( + name = "sub_component_example", + requirements = [ + "//docs/requirements:component_requirements_sub", ], tags = ["manual"], tests = [], @@ -58,13 +78,17 @@ dependable_element( dependability_analysis = [ ":sample_dependability_analysis", ], - docs_prefix = "bazel/rules/rules_score/docs/sphinx/", glossary = ["//docs:glossary"], integrity_level = "B", requirements = [ "//docs/requirements:feature_requirements", ], tests = [], - visibility = ["//:__subpackages__"], + # Public: the integrator example depends on this element to demonstrate + # AoU forwarding across module boundaries (see the comment above). + # Cross-repo visibility specs can't reference a dependent module's + # apparent name without introducing a circular bazel_dep, so this is + # public rather than scoped to "@integrator". + visibility = ["//visibility:public"], deps = ["@some_other_library//:other_seooc"], ) diff --git a/bazel/rules/rules_score/examples/seooc/design/static_design.puml b/bazel/rules/rules_score/examples/seooc/design/static_design.puml index d6319e4c..ef85542f 100644 --- a/bazel/rules/rules_score/examples/seooc/design/static_design.puml +++ b/bazel/rules/rules_score/examples/seooc/design/static_design.puml @@ -17,6 +17,7 @@ package "Safety Software SEooC Example" as safety_software_seooc_example <> { component "Unit 1" as unit_1 <> component "Unit 2" as unit_2 <> + component "Sub Component Example" as sub_component_example <> interface "InternalInterface" as InternalInterface unit_1 -l-( InternalInterface diff --git a/bazel/rules/rules_score/examples/seooc/docs/requirements/BUILD b/bazel/rules/rules_score/examples/seooc/docs/requirements/BUILD index b90391c9..d3103306 100644 --- a/bazel/rules/rules_score/examples/seooc/docs/requirements/BUILD +++ b/bazel/rules/rules_score/examples/seooc/docs/requirements/BUILD @@ -63,6 +63,20 @@ component_requirements( ], ) +# Requirements for the nested sub_component_example (a CompReq file is +# assigned to exactly one component, so it lives in its own target/file). +component_requirements( + name = "component_requirements_sub", + srcs = [ + "component_requirements_sub.trlc", + ], + visibility = ["//visibility:public"], + deps = [ + ":assumed_system_requirements", + ":feature_requirements", + ], +) + trlc_requirements_ai_test( name = "component_requirements_ai_test", reqs = [":component_requirements"], diff --git a/bazel/rules/rules_score/examples/seooc/docs/requirements/component_requirements_sub.trlc b/bazel/rules/rules_score/examples/seooc/docs/requirements/component_requirements_sub.trlc new file mode 100644 index 00000000..cd0daf51 --- /dev/null +++ b/bazel/rules/rules_score/examples/seooc/docs/requirements/component_requirements_sub.trlc @@ -0,0 +1,23 @@ +/******************************************************************************** + * 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 + ********************************************************************************/ +package SampleComponent + +import ScoreReq +import SampleSEooC + +ScoreReq.CompReq REQ_COMP_006 { + description = "The numeric value formatter shall convert a validated numeric value manager into a human-readable string representation" + safety = ScoreReq.Asil.B + derived_from = [SampleSEooC.FEAT_002@1] + version = 1 +} diff --git a/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_design.rst b/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_design.rst index cb1d0aa6..9644146e 100644 --- a/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_design.rst +++ b/bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_design.rst @@ -15,6 +15,9 @@ Unit 1 Class Design ^^^^^^^^^^^^^^^^^^^ +``unit_1`` implements ``Foo``, which exposes the ``GetNumber``/``SetNumber`` +accessors declared in ``SampleLibraryAPI`` (see ``foo.h`` / ``foo.cpp``). + .. uml:: unit_1_class_diagram.puml :align: center :alt: Unit 1 Class Diagram diff --git a/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_design.rst b/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_design.rst index 533e21c8..40f43232 100644 --- a/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_design.rst +++ b/bazel/rules/rules_score/examples/seooc/unit_2/docs/unit_2_design.rst @@ -15,6 +15,10 @@ Unit 2 Class Design ^^^^^^^^^^^^^^^^^^^ +``unit_2`` implements ``Bar``, which composes a ``unit_1::Foo`` and validates +its value (see ``bar.h`` / ``bar.cpp``). The diagram also shows ``Foo`` to +make the cross-unit dependency explicit. + .. uml:: unit_2_class_diagram.puml :align: center :alt: Unit 2 Class Diagram