diff --git a/.github/skills/rules-score/SKILL.md b/.github/skills/rules-score/SKILL.md new file mode 100644 index 00000000..62ada196 --- /dev/null +++ b/.github/skills/rules-score/SKILL.md @@ -0,0 +1,230 @@ + + +--- +name: rules-score +description: "Central entry point for building a Safety Element out of Context (SEooC) with the rules_score Bazel rules. USE FOR: creating or assembling a dependable_element end to end, understanding the full requirements → architecture → units → tests → safety-analysis workflow, wiring all rules_score targets together, and deciding which specialized skill to use for each work product. Delegates to score-requirements, score-architecture, score-testing, and score-safety-analysis. Use when scaffolding a new SEooC, adding a component/unit across all layers, or coordinating multi-layer changes." +argument-hint: "the SEooC / dependable element to build or extend" +--- + +# rules_score — SEooC Orchestration Skill + +The central skill for building a **Safety Element out of Context (SEooC)** with the `rules_score` +Bazel rules. It gives the end-to-end picture and the assembly recipe for a `dependable_element`, +then **delegates the details of each work product to a specialized skill**. + +> **Source of truth**: the rule macros under `bazel/rules/rules_score/private/`, the aggregator +> [`bazel/rules/rules_score/rules_score.bzl`](../../../bazel/rules/rules_score/rules_score.bzl), the +> validator specs in [`validation/core/docs/specifications/`](../../../validation/core/docs/specifications), +> and the runnable examples in [`bazel/rules/rules_score/examples/`](../../../bazel/rules/rules_score/examples) +> (`minimal/` and `seooc/`). When source and documentation disagree, the source wins. + +--- + +## Delegation Map + +Use this skill to coordinate; open the specialized skill for the actual work: + +| You are working on… | Use skill | +|---------------------|-----------| +| `.trlc` requirement records, `ScoreReq` model, traceability, `assumed_system_requirements` / `feature_requirements` / `component_requirements` / `assumptions_of_use` | **score-requirements** | +| PlantUML diagrams, `architectural_design` / `unit` / `unit_design` / `component` / `dependable_element` structure, architecture/API/sequence validations | **score-architecture** | +| GoogleTest `lobster-tracing` + Given-When-Then, `test_case_coverage.lock.yaml`, attaching tests | **score-testing** | +| FMEA, `FailureMode` / `ControlMeasure` / FTA, `fmea` / `dependability_analysis` | **score-safety-analysis** | + +--- + +## The Dependable Element + +A `dependable_element` is the top-level SEooC entity. It aggregates every work product and, at +build time, verifies their mutual consistency and assembles them into Sphinx HTML documentation +with a traceability report. + +| Work product | Rule(s) | Skill | +|--------------|---------|-------| +| Assumed System Requirements | `assumed_system_requirements` | score-requirements | +| Feature Requirements | `feature_requirements` | score-requirements | +| Component Requirements | `component_requirements` | score-requirements | +| Assumptions of Use | `assumptions_of_use` | score-requirements | +| Architectural Design | `architectural_design` | score-architecture | +| Units & Components | `unit`, `unit_design`, `component` | score-architecture | +| Tests & Coverage | `tests` attr, `test_case_coverage_lock` | score-testing | +| Dependability Analysis | `fmea`, `dependability_analysis` | score-safety-analysis | +| SEooC assembly | `dependable_element` | this skill | + +### Hierarchy + +``` +dependable_element (SEooC boundary) +└── component (groups units; owns component requirements + integration tests) + ├── unit (implementation + unit design + unit tests) + └── component (nestable to arbitrary depth) + └── unit +``` + +A `unit` must always sit inside a `component`; a `component` may contain units and/or other +components. + +--- + +## End-to-End Recipe + +All rules load from one aggregator: + +```starlark +load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "architectural_design", + "assumed_system_requirements", + "component", + "dependable_element", + "feature_requirements", + "unit", + "unit_design", +) +``` + +The smallest complete SEooC, wired end-to-end in a single BUILD file (verbatim from +[`examples/minimal/BUILD`](../../../bazel/rules/rules_score/examples/minimal/BUILD)): + +```starlark +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 = [], +) +``` + +Note how the diagram alias must equal the target name — `docs/static_design.puml` declares +`package "my_element" ... { component "MyComponent" { component "MyUnit" } }`, matching +`dependable_element(name = "my_element")`, `component(name = "MyComponent")`, and +`unit(name = "MyUnit")`. This is enforced by the `bazel_component` validator (see +**score-architecture**). + +For a fuller SEooC — nested components, public/internal API, sequence diagrams, AoUs, glossary, +FMEA, cross-module `deps`, and test-case coverage — see +[`examples/seooc/`](../../../bazel/rules/rules_score/examples/seooc). + +--- + +## Suggested Order of Work + +1. **Requirements** → write `AssumedSystemReq`, `FeatReq`, then `CompReq`; wire the three rules with + `deps` chaining. *(score-requirements)* +2. **Architecture** → draw the `static` PlantUML tree and add `dynamic`/`public_api`/`internal_api` + as needed; create `unit`, `unit_design`, and `component` targets whose names match the diagram. + *(score-architecture)* +3. **Implementation & tests** → back each `unit` with a `cc_library` + `cc_test`; annotate tests + with `lobster-tracing` + Given-When-Then; add `test_case_coverage_lock` on components. + *(score-testing)* +4. **Safety analysis** → add `fmea` (FailureMode + ControlMeasure + FTA) and wrap it in a + `dependability_analysis`. *(score-safety-analysis)* +5. **Assemble** → allocate `CompReq` to `component(requirements=…)` and `FeatReq` to + `dependable_element(requirements=…)`; wire `architectural_design`, `components`, + `assumptions_of_use`, `dependability_analysis`, `glossary`, and `integrity_level`. + +--- + +## Build, Test, Validate + +```bash +# Build the SEooC docs + run every consistency validation +bazel build //path/to:my_element + +# Run all tests: unit/integration tests, trlc --verify, coverage-drift checks +bazel test //... + +# Refresh a component's coverage lock after intended test changes +bazel run //path/to:MyComponent.update +``` + +`dependable_element(maturity = "development")` downgrades scope- and coverage-violations to +warnings while a design is in progress; switch to `"release"` before certification. + +--- + +## Key Cross-Cutting Facts + +- **ASIL vs. integrity_level**: requirement records use `ScoreReq.Asil` = `QM`/`B`/`D` only; + `dependable_element.integrity_level` uses `A`/`B`/`C`/`D` (D > C > B > A) for the element + hierarchy. +- **Naming**: diagram aliases must equal Bazel target names. `bazel_component` is case-insensitive; + all other validators are case-sensitive. +- **Traceability spine**: `AssumedSystemReq → FeatReq → CompReq` (version-pinned `@`) → + `lobster-tracing` in tests → `test_case_coverage.lock.yaml`; `FailureMode.interface` links safety + analysis to the `public_api` diagram. + +--- + +## References + +- [`examples/minimal/`](../../../bazel/rules/rules_score/examples/minimal) — smallest end-to-end SEooC +- [`examples/seooc/`](../../../bazel/rules/rules_score/examples/seooc) — full-featured SEooC +- [`rules_score.bzl`](../../../bazel/rules/rules_score/rules_score.bzl) — the rule aggregator (all public symbols) +- [`docs/user_guide/general.rst`](../../../bazel/rules/rules_score/docs/user_guide/general.rst) — dependable-element concept + validations +- [`validation/core/docs/specifications/`](../../../validation/core/docs/specifications) — normative validator specs diff --git a/.github/skills/score-architecture/SKILL.md b/.github/skills/score-architecture/SKILL.md new file mode 100644 index 00000000..dd121b5c --- /dev/null +++ b/.github/skills/score-architecture/SKILL.md @@ -0,0 +1,422 @@ + + +--- +name: score-architecture +description: "Software architectural design for S-CORE SEooCs using the rules_score Bazel rules. USE FOR: writing PlantUML static/dynamic/public_api/internal_api diagrams, structuring dependable_element → component → unit hierarchies, wiring architectural_design / unit / unit_design / component / dependable_element targets, PlantUML stereotype and interface/port conventions, the declared-vs-implemented architecture consistency check, integrity levels, certified scope, and requirement allocation to architectural elements. Use when working on architecture, .puml files, component/unit structure, or the rules_score architecture rules." +argument-hint: "component/unit or diagram to model" +--- + +# S-CORE Architecture Skill + +Software architectural design for a **Safety Element out of Context (SEooC)** using the +`rules_score` Bazel rules. Architecture is expressed as PlantUML diagrams **and** as Bazel +targets; `rules_score` automatically verifies that the two stay consistent and assembles them +into Sphinx documentation with a traceability report. + +> **Source of truth**: the rule macros under `bazel/rules/rules_score/private/` +> (`architectural_design.bzl`, `unit.bzl`, `unit_design.bzl`, `component.bzl`, +> `dependable_element.bzl`), the validator specifications in +> [`validation/core/docs/specifications/`](../../../validation/core/docs/specifications) (what is +> checked + which PlantUML notation is valid), and the standalone examples in +> [`bazel/rules/rules_score/examples/`](../../../bazel/rules/rules_score/examples) +> (`seooc/` and `minimal/`). When source and documentation disagree, the source wins. Every +> code block in this skill is quoted verbatim from those examples/specs. + +## When to use + +- Writing PlantUML architecture diagrams (`static`, `dynamic`, `public_api`, `internal_api`) +- Structuring the `dependable_element → component → unit` hierarchy in Bazel +- Wiring `architectural_design`, `unit`, `unit_design`, `component`, `dependable_element` +- Understanding the architecture consistency, certified-scope, and integrity-level checks + +## Not for + +- Requirement records and traceability → **score-requirements** +- FMEA / FailureMode / FTA safety analysis → **score-safety-analysis** +- Test annotation and coverage → **score-testing** +- End-to-end SEooC assembly / choosing which skill to use → **rules-score** + +--- + +## Declared vs. Implemented Architecture + +- **Declared** — the PlantUML diagrams passed to `architectural_design` (`static`, `dynamic`, + `public_api`, `internal_api`). What the architecture is *supposed* to look like. +- **Implemented** — the actual Bazel targets: `unit(implementation = [...])` wraps real source, + `component(components = [...])` groups units, `dependable_element(components = [...])` assembles + the SEooC. What the architecture *actually* is. + +Because both views are authored independently they can drift. `rules_score` runs an **architecture +consistency check** at build time: every component/unit in `dependable_element.components` must +appear, under the same name, in the `static` PlantUML diagram — and vice versa. A mismatch fails +the build. + +--- + +## Hierarchy + +``` +dependable_element (SEooC — complete Safety Element out of Context) +└── component (groups units; owns component requirements + integration tests) + ├── unit (smallest independently verifiable element: implementation + unit tests) + └── component (components can nest for deeper hierarchies) + └── unit +``` + +Two rules: + +- A `unit` must always be wrapped in a `component` — it cannot sit directly under + `dependable_element`. +- A `component` may nest: it can contain other components as well as units, to arbitrary depth. + +--- + +## Static Architecture (PlantUML) + +Write a class/component diagram that names **every** `component` and `unit` from your BUILD file. +The validator identifies elements by their **stereotype**, not by the PlantUML keyword — both +`package` and `component` keywords are accepted at each level. + +| Stereotype | Valid keywords | Meaning | Bazel rule | +|------------|----------------|---------|------------| +| `<>` | `package`, `component` | SEooC boundary | `dependable_element` | +| `<>` | `component`, `package` | Architectural component | `component` | +| `<>` | `component`, `package` | Leaf implementation unit | `unit` | + +```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 + } +} + +interface "SampleLibraryAPI" as SampleLibraryAPI + +safety_software_seooc_example )-d- SampleLibraryAPI + +@enduml +``` + +*(Verbatim from [`examples/seooc/design/static_design.puml`](../../../bazel/rules/rules_score/examples/seooc/design/static_design.puml). The three `<>`/`<>` +names — `component_example`, `unit_1`, `unit_2`, `sub_component_example` — are exactly the Bazel +target names, and `safety_software_seooc_example` matches the `dependable_element` name.)* + +### Interfaces & ports + +Any component-type element (`<>` or `<>`) can bind an interface with lollipop +syntax — `-(` for a **required** (incoming) binding and `)-` for a **provided** (outgoing) one. +The `bazel_component` validator does not check interface bindings themselves, but the API and +sequence validators do (see below). + +When you need an explicitly named, standalone binding point (e.g. to distinguish multiple provided +interfaces), declare a `portin` / `portout` inside the `<>` or `<>` element +(from the `bazel_component` validator spec): + +```text +package "MySeooc" as MySeooc <> { + portin " " as p_in ' required interface port + portout " " as p_out ' provided interface port +} + +interface "IRequired" as IRequired +interface "IProvided" as IProvided + +p_in -( IRequired : requires +p_out )- IProvided : provides +``` + +- `portin` / `portout` must be declared **inside** the `<>` or `<>` element. +- A plain `package` **without** a stereotype cannot carry interface bindings. +- Elements with other stereotypes (`actor`, `database`, …) are not valid on the left of a binding. + +--- + +## Dynamic, Public API, Internal API + +Every diagram kind is checked by one or more validators (see **Active validations** below) — none +of them is "documentation only". `static` is checked against the Bazel structure; the others are +cross-checked against each other and against the implementation. + +| View | Attribute | Cross-checked against | Purpose | +|------|-----------|-----------------------|---------| +| **Static** | `static` | Bazel `dependable_element`/`component`/`unit` tree; internal API; public API; sequences | Structural component/unit tree — the anchor for all other checks | +| **Dynamic** (sequence) | `dynamic` | Static component diagram; internal API | Unit interactions — participant aliases and cross-unit calls | +| **Public API** | `public_api` | Static diagram (top-level interfaces bound from the SEooC) | Interfaces the SEooC exposes; also feeds `FailureMode.interface` traceability | +| **Internal API** | `internal_api` | Static component diagram; sequences | Interfaces between components/units inside the SEooC | + +Real example diagrams (verbatim, from [`examples/seooc/design/`](../../../bazel/rules/rules_score/examples/seooc/design)): + +```text +' dynamic_design.puml — sequence diagram +@startuml +participant "Unit 1" as unit_1 <> +participant "Unit 2" as unit_2 <> + +unit_1 -> unit_2 : GetData() +unit_2 --> unit_1 : return : Data* +@enduml +``` + +```text +' public_api.puml — top-level interface exposed by the SEooC +@startuml +namespace safety_software_seooc_example { + interface "SampleLibraryAPI" as SampleLibraryAPI { + + GetNumber(): int + } +} +@enduml +``` + +```text +' internal_api.puml — interface modeled inside its owning component's namespace +@startuml +namespace safety_software_seooc_example { + namespace component_example { + interface "InternalInterface" as InternalInterface <>{ + {abstract} GetData(BindingType binding): Data* + } + } +} +@enduml +``` + +- **Public API** interfaces must be top-level in the static diagram and bound from the `<>` + (e.g. `safety_software_seooc_example )-d- SampleLibraryAPI`); interfaces nested inside + components/units are treated as *internal* API. +- **Internal API** interfaces are modeled inside the owning element's `namespace` so their + fully-qualified name reflects containment. + +--- + +## Bazel Rules + +Load from the aggregator: + +```starlark +load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "architectural_design", + "unit", + "unit_design", + "component", + "dependable_element", +) +``` + +### `architectural_design` + +One target bundles every diagram kind (from [`examples/seooc/design/BUILD`](../../../bazel/rules/rules_score/examples/seooc/design/BUILD)): + +```starlark +architectural_design( + name = "sample_seooc_design", + static = ["static_design.puml", "arch_design.rst"], + dynamic = ["dynamic_design.puml"], + public_api = ["public_api.puml"], + internal_api = ["internal_api.puml"], + visibility = ["//visibility:public"], + # maturity = "development", # write validation findings without failing the build +) +``` + +`static`/`dynamic` accept `.puml`, `.plantuml`, `.png`, `.svg`, `.rst`, `.md`. To combine a +diagram with prose, add both the RST/Markdown wrapper *and* the referenced `.puml` to the same +list (as `static_design.puml` + `arch_design.rst` above); the wrapper embeds the diagram with +`.. uml:: file.puml`. + +### `unit_design` + +```starlark +# examples/seooc/unit_1/docs/BUILD — globs the class-diagram .puml + its RST wrapper +unit_design( + name = "unit_design", + static = glob(["*.puml", "*.rst"]), + visibility = ["//visibility:public"], +) +``` + +The unit-design class diagram is validated against the C++ implementation (see **Active +validations**). Real class diagram from [`unit_1/docs/unit_1_class_diagram.puml`](../../../bazel/rules/rules_score/examples/seooc/unit_1/docs/unit_1_class_diagram.puml): + +```text +@startuml unit_1_class_diagram +namespace unit_1 { + class Foo { + + GetNumber() : uint8_t + + SetNumber(value : uint8_t) : void + } +} +@enduml +``` + +**RST heading convention**: unit-design RST fragments are `.. include::`-d into the generated unit +page, which already uses `=` and `-` headings. Any title inside the fragment **must** use a +not-yet-used character such as `^` so it becomes a sub-subsection. + +### `unit` + +From [`examples/seooc/unit_1/BUILD`](../../../bazel/rules/rules_score/examples/seooc/unit_1/BUILD): + +```starlark +unit( + name = "unit_1", + unit_design = ["//unit_1/docs:unit_design"], + implementation = [":unit_1_lib"], # cc_library/cc_binary/rust_library/... + scope = ["//unit_1:unit_1_lib"], # extra targets in the certified package tree + tests = [":unit_1_test"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "unit_1_lib", + srcs = ["foo.cpp"], + hdrs = ["foo.h"], + deps = ["@some_other_library"], +) + +cc_test( + name = "unit_1_test", + srcs = ["foo_test.cpp"], + deps = [":unit_1_lib", "@googletest//:gtest_main"], +) +``` + +### `component` + +From [`examples/seooc/BUILD`](../../../bazel/rules/rules_score/examples/seooc/BUILD) — a component can +contain both units and nested components: + +```starlark +component( + name = "component_example", + components = [ + "//unit_1:unit_1", + "//unit_2:unit_2", + ":sub_component_example", # nested component + ], + requirements = ["//docs/requirements:component_requirements"], # component_requirements targets + test_case_coverage_lock = "test_case_coverage.lock.yaml", # see score-testing + tests = [], +) + +component( + name = "sub_component_example", + requirements = ["//docs/requirements:component_requirements_sub"], + tests = [], +) +``` + +### `dependable_element` (SEooC) + +From [`examples/seooc/BUILD`](../../../bazel/rules/rules_score/examples/seooc/BUILD): + +```starlark +dependable_element( + name = "safety_software_seooc_example", + architectural_design = ["//design:sample_seooc_design"], + requirements = ["//docs/requirements:feature_requirements"], # FeatReq targets + assumptions_of_use = ["//docs:sample_aous"], + dependability_analysis = [":sample_dependability_analysis"], + components = [":component_example"], + tests = [], + integrity_level = "B", # A/B/C/D, hierarchy D > C > B > A + glossary = ["//docs:glossary"], + maturity = "development", # scope/coverage violations become warnings + aou_forwarding = "aou_forwarding.yaml", + deps = ["@some_other_library//:other_seooc"], + visibility = ["//visibility:public"], +) +``` + +> `integrity_level` uses `A`/`B`/`C`/`D` for the element hierarchy. Requirement records +> themselves use the `ScoreReq.Asil` enum, which only has `QM`/`B`/`D` (see **score-requirements**). + +For the smallest possible SEooC wired end-to-end in a single BUILD file, see +[`examples/minimal/BUILD`](../../../bazel/rules/rules_score/examples/minimal/BUILD). + +--- + +## Active Validations (build time) + +`rules_score` runs a set of consistency validators at `bazel build`/`bazel test` time. Their +normative behaviour is specified in +[`validation/core/docs/specifications/`](../../../validation/core/docs/specifications) — **this is +the source of truth for what is checked and which notation is valid**. + +| Validator | Spec | Compares | Case | +|-----------|------|----------|------| +| **Bazel ↔ component** | `bazel_component.md` | `dependable_element`/`component`/`unit` targets ↔ `static` PlantUML | insensitive | +| **Component ↔ public API** | `component_public_api.md` | top-level interfaces in `static` ↔ `public_api` class diagram; must be bound from the SEooC | sensitive | +| **Component ↔ internal API** | `component_internal_api.md` | interfaces in `static` ↔ `internal_api` diagram | sensitive | +| **Component ↔ sequence** | `component_sequence.md` | unit aliases + interface connections in `static` ↔ `dynamic` sequence diagrams | sensitive | +| **Sequence ↔ internal API** | `sequence_internal_api.md` | sequence method calls ↔ `internal_api` interfaces (method name, consumer/provider role, interface coverage) | sensitive | +| **Class design ↔ implementation** | `class_design_implementation.md` | `unit_design` class diagram ↔ C++ implementation (entities, methods, variables, enums, relationships, templates) | sensitive + type normalization | + +Additional element-level checks (see [`docs/user_guide/general.rst`](../../../bazel/rules/rules_score/docs/user_guide/general.rst)): + +| Check | Rule | Effect | +|-------|------|--------| +| **Certified scope** | every target reached via `unit.implementation` must lie in the package tree declared by the element's `unit`/`component` targets | non-certified external deps fail the build | +| **Integrity level** | a `dependable_element` must not `deps` on one with a lower `integrity_level` (D > C > B > A) | violation fails the build | + +> **Only `bazel_component` is case-insensitive** — every other validator matches names +> case-sensitively. Keep diagram aliases identical to the code/target names. +> +> `maturity = "development"` downgrades scope and coverage violations to warnings; switch back to +> `"release"` before certification. + +--- + +## Requirement Allocation + +- **`CompReq`** → `component(requirements = [...])` (one component per file). +- **`FeatReq`** → `dependable_element(requirements = [...])`. + +Traceability from a feature requirement down to implementing components runs through the +`FeatReq → CompReq → component` chain. See **score-requirements** for details. + +--- + +## Conventions + +- Diagram aliases must **match the Bazel target name** — `bazel_component` compares + case-insensitively, but every other validator is case-sensitive, so keep them identical. +- Model down to the `unit` level in the static diagram; every implemented unit must appear (and no + extra ones — missing *and* extra elements both fail). +- Sequence diagrams are validated: participant aliases must equal the component-diagram unit + aliases, and every cross-unit call must correspond to an interface connection (and be declared in + the internal API). Keep them at the unit-interaction level. +- Unit-design class diagrams are validated against the C++ implementation — the design is the + contract (implementation-only members are allowed, design-only members are not). +- Prefer `.svg` over `.png` for diagrams checked into git (text-based, diffs cleanly). + +--- + +## References + +- [`examples/seooc/`](../../../bazel/rules/rules_score/examples/seooc) — complete working SEooC (`BUILD`, `design/`, `unit_1/`) +- [`examples/minimal/`](../../../bazel/rules/rules_score/examples/minimal) — smallest end-to-end SEooC in one BUILD file +- [`validation/core/docs/specifications/`](../../../validation/core/docs/specifications) — normative validator specs (source of truth for notation) +- [`docs/user_guide/architectural_design.rst`](../../../bazel/rules/rules_score/docs/user_guide/architectural_design.rst) — narrative guide +- [`docs/user_guide/general.rst`](../../../bazel/rules/rules_score/docs/user_guide/general.rst) — element-level validation reference +- [PlantUML](https://plantuml.com/) — diagram notation diff --git a/.github/skills/score-requirements/SKILL.md b/.github/skills/score-requirements/SKILL.md new file mode 100644 index 00000000..842c4c57 --- /dev/null +++ b/.github/skills/score-requirements/SKILL.md @@ -0,0 +1,342 @@ + + +--- +name: score-requirements +description: "Requirements engineering for S-CORE projects with TRLC and the rules_score Bazel rules. USE FOR: writing .trlc requirement records (AssumedSystemReq, FeatReq, CompReq, AoU), understanding the ScoreReq requirements model (.rsl), traceability chains (AssumedSystemReq → FeatReq → CompReq), version pinning, ASIL classification, wiring assumed_system_requirements / feature_requirements / component_requirements / assumptions_of_use Bazel targets, requirement allocation to components, embedding images/diagrams in descriptions, and validating requirements with bazel test. Use when working on requirements, .trlc/.rsl files, traceability, or safety classifications." +argument-hint: "requirement level (system/feature/component) or record to add" +--- + +# S-CORE Requirements Skill + +Requirements engineering for **S-CORE** projects using [TRLC](https://github.com/bmw-software-engineering/trlc) +(Treat Requirements Like Code) and the `rules_score` Bazel rules. Requirements are written as +code, stored next to the source, version-controlled with Git, and validated automatically by +Bazel build/test rules. + +> **Source of truth**: the `ScoreReq` model in +> [`bazel/rules/rules_score/trlc/config/score_requirements_model.rsl`](../../../bazel/rules/rules_score/trlc/config/score_requirements_model.rsl) +> and the rule macros under `bazel/rules/rules_score/private/`. A complete, standalone working +> example lives in [`bazel/rules/rules_score/examples/seooc/`](../../../bazel/rules/rules_score/examples/seooc). +> When source and documentation disagree, the source wins. + +## When to use + +- Writing `.trlc` requirement records or `.rsl` schema extensions +- Wiring `assumed_system_requirements`, `feature_requirements`, `component_requirements`, + or `assumptions_of_use` Bazel targets +- Establishing or updating traceability (`derived_from`) with version pinning +- Allocating requirements to components / dependable elements +- Validating requirements with `bazel test` + +## Not for + +- Architecture diagrams, `unit` / `component` / `dependable_element` structure → **score-architecture** +- FMEA / FailureMode / ControlMeasure / FTA safety analysis → **score-safety-analysis** +- Test annotation and coverage → **score-testing** +- End-to-end SEooC assembly / choosing which skill to use → **rules-score** + +--- + +## Requirement Hierarchy & Traceability + +``` +AssumedSystemReq → FeatReq → CompReq + (System) (Feature) (Component) + \ ↑ + \________________________/ +``` + +| Type | Description | Traceability | +|------|-------------|-------------| +| **AssumedSystemReq** | System-level requirements the SEooC receives from the wider context. Too high-level for one component. | Root — no parent | +| **FeatReq** | Refined feature/safety requirements. Still require multiple components. | **Must** reference ≥1 `AssumedSystemReq` via `derived_from` | +| **CompReq** | Requirements allocated to exactly one component; directly implementable and testable. | **Optionally** references ≥1 `FeatReq`/`AssumedSystemReq` via `derived_from` | + +Traceability is enforced by the TRLC type system. **Version pinning** (e.g. `@1`) means that when +a parent requirement's content changes (and its `version` is bumped), every downstream reference +must be explicitly updated — a change is never silently absorbed. + +--- + +## The ScoreReq Model (source of truth) + +The schema is defined once in `score_requirements_model.rsl` (package `ScoreReq`). Projects +**import** it — they do not redefine it. Key facts: + +### `Asil` enum — only three values + +``` +QM B D +``` + +There is **no** `A` or `C` in the requirements model. Reference as `ScoreReq.Asil.QM`, +`ScoreReq.Asil.B`, `ScoreReq.Asil.D`. + +> Note: `dependable_element(integrity_level = ...)` in Bazel accepts `A`/`B`/`C`/`D` for the +> element hierarchy, but requirement records themselves only use `QM`/`B`/`D`. + +### Field inheritance + +``` +Requirement → description (Markup_String), version (Integer), + note (optional String), status (frozen = valid) + RequirementSafety → + safety (Asil) + AssumedSystemReq → + rationale (String) + FeatReq → + derived_from (AssumedSystemReqId[1..*]) + CompReq → + derived_from (CompReqSourceId[1..*]) # FeatReq or AssumedSystemReq +``` + +- `description` is a `Markup_String` — it may contain `:term:` references and embedded + directives (see *Images & diagrams* below). +- `status` is **frozen** to `valid` — do not set it. +- `note` is optional and non-normative. +- The model does **not** enforce a "shall/should" keyword check (unlike some downstream + projects). Still, write requirements with "shall" for clarity. + +### Versioned reference tuples + +`AssumedSystemReqId`, `FeatReqId`, `CompReqSourceId`, `CompReqId` all use the form +`Package.RecordId@version`, e.g. `SampleSEooC.ASR_SAMPLE_001@1`. + +--- + +## Writing Requirements + +Package names are **project-specific** (e.g. `SampleSEooC`, `SampleComponent`). Every file +declares its package and imports `ScoreReq` (plus any package it cross-references). + +### AssumedSystemReq + +```trlc +package SampleSEooC +import ScoreReq + +ScoreReq.AssumedSystemReq ASR_SAMPLE_001 { + description = "The system shall provide safe and reliable numeric value management, 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" +} +``` + +**Required**: `description`, `safety`, `version`, `rationale`. + +### FeatReq + +```trlc +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." + safety = ScoreReq.Asil.B + derived_from = [SampleSEooC.ASR_SAMPLE_001@1] + version = 1 +} +``` + +**Required**: `description`, `safety`, `version`, `derived_from` (≥1 version-pinned `AssumedSystemReq`). + +### CompReq + +`derived_from` uses the versioned tuple syntax `[Package.RecordId@version]` and may reference +**more than one** parent (a `FeatReq` or an `AssumedSystemReq`). + +```trlc +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 +} +``` + +**Required**: `description`, `safety`, `version`. `derived_from` is optional — omit it only for +component-internal requirements with no feature-level parent. + +### Assumptions of Use (AoU) + +`AoU` extends `ControlMeasure` and captures conditions the integrating project must satisfy. +The `assumptions_of_use` rule accepts raw `.trlc` **or** `.rst` files carrying `aou_req` +directives (converted to TRLC automatically). + +--- + +## Bazel Rules + +Load from the aggregator: + +```starlark +load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "assumed_system_requirements", + "feature_requirements", + "component_requirements", + "assumptions_of_use", +) +``` + +Each requirement rule takes `name`, `srcs` (the `.trlc` files), and `deps` (other requirement +targets whose records are cross-referenced). All three share the same optional attributes: +`spec` (defaults to the `ScoreReq` model — override only for a custom schema), `lobster_config`, +`ref_package`, and `image_srcs`. + +```starlark +# docs/requirements/BUILD + +assumed_system_requirements( + name = "assumed_system_requirements", + srcs = ["assumed_system_requirements.trlc"], + visibility = ["//visibility:public"], +) + +feature_requirements( + name = "feature_requirements", + srcs = ["feature_requirements.trlc"], + deps = [":assumed_system_requirements"], # resolve derived_from refs + visibility = ["//visibility:public"], +) + +component_requirements( + name = "component_requirements", + srcs = ["component_requirements.trlc"], + deps = [ + ":assumed_system_requirements", + ":feature_requirements", + ], + visibility = ["//visibility:public"], +) +``` + +Every requirement target automatically generates a `_test` target that runs +`trlc --verify`. Because these rules emit `TrlcProviderInfo`, downstream targets can list them +directly in `deps` without any intermediate `trlc_requirements` wrapper. + +### Requirement Allocation to Architecture + +- **`CompReq`** → allocated to exactly one component via the `component(requirements = [...])` + attribute. Because the whole file is assigned to one component, split CompReqs into per-component + files. +- **`FeatReq`** → allocated to the SEooC as a whole via `dependable_element(requirements = [...])`. + Traceability to the implementing components runs through the `FeatReq → CompReq → component` chain. + +```starlark +component( + name = "MyComponent", + components = [":MyUnit"], + requirements = [":component_requirements"], + tests = [], +) + +dependable_element( + name = "my_element", + requirements = [":feature_requirements"], # FeatReq targets + # ... +) +``` + +--- + +## Images & Diagrams in Descriptions + +A `description` can embed images and PlantUML so they render in the generated Sphinx docs next +to the requirement text: + +- **Markdown image** `![alt](path)` → converted to `.. image::`. +- **Raw RST directive** (`.. uml::`, `.. image::`, `.. figure::`) → passed through unchanged. + +The referenced file must also be declared via the `image_srcs` attribute (available on all three +requirement rules) and the path in the directive must match the file's package-relative path. +Prefer `.svg` over `.png` for anything checked into git. + +```trlc +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 +} +``` + +--- + +## Validation + +```bash +# Type-check all requirement .trlc files (build) +bazel build //docs/requirements/... + +# Run trlc --verify on every requirement target (test) +bazel test //docs/requirements/... + +# A single target +bazel test //docs/requirements:feature_requirements_test +``` + +`trlc --verify` catches: syntax errors, type errors (wrong value type for a field), missing +mandatory fields (`description`, `safety`, `version`), broken cross-references (a `derived_from` +pointing at a non-existent record), and unknown fields not defined in the model. + +### AI-Powered Quality Check (optional) + +`trlc_requirements_ai_test` evaluates requirement *quality* (clarity, testability, completeness) +with an LLM. It is non-deterministic — tag it `manual` and do **not** run it in CI. + +```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"], +) +``` + +--- + +## Workflow + +1. **Create or modify** `.trlc` files under your `requirements/` (or `docs/requirements/`) directory. +2. **Wire BUILD targets** — add new `.trlc` files to `srcs`; add cross-referenced targets to `deps`. +3. **Validate locally**: `bazel test //.../requirements/...`. +4. **Commit** on a feature branch and open a PR. + +### Updating an existing requirement + +- **Increment `version`** on every content change. +- **Update all downstream `derived_from` references** to the new version (`@1` → `@2`). +- Version pinning forces a conscious review of every child when a parent changes. + +--- + +## References + +- [`score_requirements_model.rsl`](../../../bazel/rules/rules_score/trlc/config/score_requirements_model.rsl) — the `ScoreReq` schema (source of truth) +- [`examples/seooc/`](../../../bazel/rules/rules_score/examples/seooc) — complete working example +- [`docs/user_guide/requirements.rst`](../../../bazel/rules/rules_score/docs/user_guide/requirements.rst) — narrative guide +- [TRLC](https://github.com/bmw-software-engineering/trlc) — language and tooling diff --git a/.github/skills/score-safety-analysis/SKILL.md b/.github/skills/score-safety-analysis/SKILL.md new file mode 100644 index 00000000..cba14ebe --- /dev/null +++ b/.github/skills/score-safety-analysis/SKILL.md @@ -0,0 +1,164 @@ + + +--- +name: score-safety-analysis +description: "Step-by-step workflow for creating or extending a FMEA-based safety analysis in TRLC format for S-CORE software components. Use when asked to: add failure modes, create FTA diagrams, add control measures, or validate the safety analysis traceability chain. Covers clustering, FailureMode records, FTA PlantUML files, ControlMeasure records, BUILD wiring, and trlc validation." +argument-hint: "interface or component name to analyse" +--- + +# S-CORE Safety Analysis — TRLC Workflow + +## When to Use + +- Adding new failure modes to an existing safety analysis +- Creating FTA diagrams for root-cause decomposition +- Defining ControlMeasure / AoU records for identified root causes +- Validating the full traceability chain before a review of a safety analysis + +## Key Files and Locations + +``` +score//dependability/ +├── safety_analysis/ +│ ├── failure_modes.trlc # FailureMode records (one per unique root-cause cluster) +│ ├── control_measures.trlc # ControlMeasure / PreventiveMeasure / AoU records +│ ├── fta_.puml # One FTA diagram per FailureMode +│ └── BUILD # fmea() rule — must list all .puml in fta_files filegroup +├── assumed_system/ +│ └── aous.trlc # AoU records (caller obligations) +└── requirements/ + └── component_requirements.trlc +``` + +The canonical RSL (type definitions) lives in: +`eclipse-score-tooling/bazel/rules/rules_score/trlc/config/score_requirements_model.rsl` + +## Step 1 — Write FailureMode Records (`failure_modes.trlc`) + +Package: match the existing package declaration in the folder structure + +```trlc +package +import ScoreReq + +ScoreReq.FailureMode { + guideword = ScoreReq.GuideWord. + description = "statement describing the expected behaviour" + failureeffect = "What goes wrong for the caller / system" + potentialcause = "Root cause(s) from the FMEA" + interface = ".[, .]" + version = 1 + safety = ScoreReq.Asil.B +} +``` + +**GuideWord enum values:** `LossOfFunction`, `PartialFunction`, `Corrupted`, `UnintendedFunction`, `TooEarly`, `TooLate`, `Wrong`, `DelayedFunction`, `ExceedingFunction`, `ArbitraryExecution` + +**Rules:** +- One record per FailureMode, not per interface method. +- Same root cause spanning multiple guide words → separate records (trlc only allows one `guideword` per record). +- `interface` may list multiple methods as a comma-separated string when root cause is shared. + +## Step 2 — Create FTA Diagrams (`fta_.puml`) + +One `.puml` file per `FailureMode` record. The `$TopEvent` alias **must** equal the fully-qualified TRLC record name (`.`). + +```plantuml +@startuml + +!include fta_metamodel.puml + +$TopEvent("", ".") + +$OrGate("OG1", ".") + +$BasicEvent("", ".", "OG1") +$BasicEvent("", ".", "OG1") + +@enduml +``` + +**Procedures reference:** + +| Procedure | Purpose | `connection` points to | +|-----------|---------|------------------------| +| `$TopEvent(name, alias)` | Top failure mode | — (root, no connection) | +| `$OrGate(alias, connection)` | Any child sufficient | parent alias | +| `$AndGate(alias, connection)` | All children required | parent alias | +| `$BasicEvent(name, alias, connection)` | Root cause / leaf | enclosing gate alias | +| `$IntermediateEvent(name, alias, connection)` | Intermediate cause | parent gate alias | +| `$TransferInGate(name, alias, connection)` | Link to sub-tree | parent alias | + +**Rules:** +- `$BasicEvent` alias = `.` — this IS the traceability link. +- Build bottom-up in the file: `$TopEvent` first, then gates, then `$BasicEvent` leaves. +- The same `ControlMeasure` alias may appear in multiple FTAs (shared root cause). +- `$OrGate` is the default for independent root causes; use `$AndGate` only when all causes must co-occur. + +## Step 3 — Write ControlMeasure Records (`control_measures.trlc`) + +For every `$BasicEvent` alias in every FTA, define a matching record: + +```trlc +ScoreReq.ControlMeasure { + safety = ScoreReq.Asil.B + description = "Normative measure text" + version = 1 +} +``` + +Other available types (same pattern, different semantics): +- `ScoreReq.PreventiveMeasure` — prevents the failure from occurring +- `ScoreReq.Mitigation` — reduces severity/probability after occurrence +- `ScoreReq.AoU` — assumption the caller must satisfy; add `mitigates = ""` field + +**Rule:** `.` in TRLC must match the `$BasicEvent` alias verbatim. + +## Step 4 — Update BUILD + +Add every new `.puml` to the `fta_files` filegroup **and** keep the list alphabetically sorted: + +```python +filegroup( + name = "fta_files", + srcs = [ + "fta_api_called_before_lifecycle_ready.puml", + "fta_client_connection_failed.puml", + # ... one entry per FTA file, alphabetical + ], + visibility = ["//score//dependability:__pkg__"], +) +``` + +## Step 5 — Validate + +**Pass criteria:** zero errors in `failure_modes.trlc`, `control_measures.trlc`, `aous.trlc`. +Pre-existing RSL union-type errors (`expected identifier, encountered '['`) are a known trlc v2 / RSL version mismatch — ignore if they appear only in the tooling RSL, not in component files. + +**Traceability chain that must be complete:** + +``` +FailureMode.interface → public_api interface name +FailureMode record → $TopEvent alias +$BasicEvent alias → ControlMeasure / AoU record name +``` + +## Common Mistakes + +| Mistake | Fix | +|---------|-----| +| `$BasicEvent` alias does not match any TRLC record | Ensure `.` is spelled identically in both places | +| New `.puml` not in BUILD `fta_files` | Add the file path to the `srcs` list | +| AoU added to `control_measures.trlc` | AoUs belong in `aous.trlc`; both extend `Measure` so the FTA alias still resolves | +| Wrong RSL used for trlc validation | Always pass the tooling RSL as the first directory argument | diff --git a/.github/skills/score-testing/SKILL.md b/.github/skills/score-testing/SKILL.md new file mode 100644 index 00000000..155f2bab --- /dev/null +++ b/.github/skills/score-testing/SKILL.md @@ -0,0 +1,212 @@ + + +--- +name: score-testing +description: "Testing and test-coverage traceability for S-CORE SEooCs using the rules_score Bazel rules. USE FOR: attaching tests to unit/component/dependable_element targets, annotating GoogleTest cases with lobster-tracing and Given-When-Then RecordProperty calls, requirement-to-test traceability, the test_case_coverage.lock.yaml workflow (bazel run .update vs bazel test drift check), maturity-driven enforcement, and running rules_score tests. Use when writing tests, wiring test targets, annotating tests for traceability, or measuring test-case coverage." +argument-hint: "unit/component test or coverage task" +--- + +# S-CORE Testing Skill + +Testing and test-case-coverage traceability for a **Safety Element out of Context (SEooC)** built +with the `rules_score` Bazel rules. Tests are attached to architectural elements, annotated for +requirement traceability, and their coverage is locked and verified automatically at build time. + +> **Source of truth**: the rule macros under `bazel/rules/rules_score/private/` (`unit.bzl`, +> `component.bzl`, `dependable_element.bzl`), the test-case-coverage tooling under +> [`bazel/rules/rules_score/src/test_case_coverage/`](../../../bazel/rules/rules_score/src/test_case_coverage), +> and the runnable examples in +> [`bazel/rules/rules_score/examples/`](../../../bazel/rules/rules_score/examples). +> When source and documentation disagree, the source wins. + +## When to use + +- Attaching tests to `unit`, `component`, or `dependable_element` via the `tests` attribute +- Annotating GoogleTest cases with `lobster-tracing` + Given-When-Then +- Setting up and maintaining `test_case_coverage.lock.yaml` +- Running `rules_score` tests and interpreting coverage-drift failures + +## Not for + +- Requirement records and traceability model → **score-requirements** +- Architecture structure and diagrams → **score-architecture** +- FMEA / safety analysis → **score-safety-analysis** +- End-to-end SEooC assembly / choosing which skill to use → **rules-score** + +--- + +## Where Tests Attach + +Test targets are attached at three architectural levels through the `tests` attribute. Match the +test scope to the level: + +| Level | Attribute | Test focus | +|-------|-----------|------------| +| `unit` | `unit(tests = [...])` | Unit tests — the smallest verifiable element | +| `component` | `component(tests = [...])` | Integration tests across the component's units | +| `dependable_element` | `dependable_element(tests = [...])` | System / integration tests for the whole SEooC | + +`rules_score` does **not** require a separate test-specification document. Test intent is captured +as a **Given-When-Then** description right next to the code, then rendered in the traceability +report together with the test results and coverage. + +--- + +## Annotating Tests (GoogleTest + lobster-tracing) + +Unit tests are written with **GoogleTest** and built with `cc_test`. A test case that covers a +requirement carries `RecordProperty` annotations inside its body: + +```cpp +TEST(MyUnitTest, ConfigureAndGet) { + ::testing::Test::RecordProperty( + "lobster-tracing", "MinimalExample.FEAT_001 MinimalExample.FEAT_002"); + ::testing::Test::RecordProperty("given", "a default-constructed MyUnit instance"); + ::testing::Test::RecordProperty("when", "configure is called with a known key"); + ::testing::Test::RecordProperty("then", "get returns the configured value"); + + MyUnit unit; + unit.configure("mode", "fast"); + EXPECT_EQ(unit.get("mode"), "fast"); +} +``` + +| Property | Required | Description | +|----------|----------|-------------| +| `lobster-tracing` | yes | One or more requirement IDs (`Package.RecordId`), linking the test to `CompReq` records. Multiple IDs are separated by whitespace (the docs also describe comma-separated). | +| `given` | no | Initial state / precondition | +| `when` | no | Action or event under test | +| `then` | no | Expected outcome | + +- A test **without** `lobster-tracing` has no traceability and is excluded from coverage tracking. +- The referenced IDs must resolve to `CompReq` records exposed through the component's + `requirements` targets. + +```starlark +cc_test( + name = "my_unit_test", + srcs = ["test/my_unit_test.cpp"], + deps = [":my_unit_lib", "@googletest//:gtest_main"], +) + +unit( + name = "MyUnit", + unit_design = [":MyUnit_design"], + implementation = [":my_unit_lib"], + tests = [":my_unit_test"], +) +``` + +--- + +## Test-Case Coverage (`test_case_coverage.lock.yaml`) + +Coverage is **declared** through a committed lock file that lists, per requirement, every test +case (uid + Given-When-Then) that covers it. Committing the file is the coverage claim. Link it to +the `component` rule: + +```starlark +component( + name = "my_component", + requirements = [":my_component_requirements"], + components = [":unit_a", ":unit_b"], + test_case_coverage_lock = "test_case_coverage.lock.yaml", +) +``` + +### Lock file format + +```yaml +schema_version: 3 +requirements: + - id: MessagePassing.OsIpcFaultHandling + test_cases: + - uid: "//score/message_passing/ConnectionSuite:OsIpcFaultHandlingTest" + given: a connected client + when: the OS IPC call fails + then: the client receives an error +``` + +- `requirements[].id` — matches the `lobster-tracing` value; extracted from the requirements targets. +- `test_cases[].uid` — `//bazel_package/SuiteName:TestName`, a package-scoped gtest tag. +- `given` / `when` / `then` — the GWT fields from `RecordProperty`; **any** change makes the lock stale. + +### Two workflows keep the lock in sync + +- **`bazel run //:.update`** — reads current test results and **rewrites** + `test_case_coverage.lock.yaml` in the source tree. Review `git diff`, then commit to approve. +- **`bazel test //...`** — a build action recomputes coverage from the same test results and + **compares** it against the committed lock. Any drift (new/removed test, changed GWT text, + version bump) fails the build until the lock is refreshed and re-committed. + +The `.update` target is only generated when `test_case_coverage_lock` is set on the component. + +### Enforcement stringency follows `dependable_element.maturity` + +The coverage check runs inside the enclosing `dependable_element`, and its `maturity` attribute +controls how strict it is: + +| `maturity` | Behavior | +|------------|----------| +| `"development"` | `--allow-check-failures`: lock-drift **and** missing-GWT-annotation errors are downgraded to warnings; the `.lobster` artifact is always produced. | +| `"release"` | A drift or a missing GWT annotation fails the Bazel build action directly. | + +Switch back to `"release"` before certification. + +--- + +## Running Tests + +```bash +# Everything (also runs coverage-drift checks and trlc --verify) +bazel test //... + +# A single test target +bazel test //:my_unit_test + +# Requirement-validation tests only +bazel test //docs/requirements/... + +# Refresh a component's coverage lock after intended test changes +bazel run //:.update +``` + +Useful options: `--test_output=errors` (default), `--test_output=all`, +`--nocache_test_results` (force re-run). + +--- + +## Traceability Flow (how it fits together) + +``` +CompReq (requirements target, .lobster) + ▲ lobster-tracing "Package.CompReq" +GoogleTest case (RecordProperty) + │ subrule_lobster_gtest → gtest.lobster +component(test_case_coverage_lock=…) + │ compute_lock ── compared against committed lock (bazel test) + └─ rendered in the dependable_element traceability report +``` + +Requirement → test coverage is complete when every `CompReq` in the component's `requirements` +appears in the lock file with at least one covering test case. + +--- + +## References + +- [`docs/user_guide/validation.rst`](../../../bazel/rules/rules_score/docs/user_guide/validation.rst) — annotation & coverage guide +- [`docs/tool_reference/test_case_coverage.rst`](../../../bazel/rules/rules_score/docs/tool_reference/test_case_coverage.rst) — lock format, phases, data flow +- [`examples/minimal/`](../../../bazel/rules/rules_score/examples/minimal) — minimal annotated test +- [`examples/seooc/`](../../../bazel/rules/rules_score/examples/seooc) — full SEooC with `test_case_coverage.lock.yaml`