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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .github/skills/rules-score/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ with a traceability report.
| 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 | `safety_analysis`, `dependability_analysis` | score-safety-analysis |
| Dependability Analysis | `failure_modes`, `fault_trees`, `safety_analysis`, `dependability_analysis` | score-safety-analysis |
| SEooC assembly | `dependable_element` | this skill |

### Hierarchy
Expand Down Expand Up @@ -151,7 +151,6 @@ component(
dependable_element(
name = "my_element",
architectural_design = [":my_arch"],
assumptions_of_use = [],
components = [":MyComponent"],
dependability_analysis = [],
integrity_level = "B",
Expand Down Expand Up @@ -182,11 +181,14 @@ FMEA, cross-module `deps`, and test-case coverage — see
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 `safety_analysis` (FailureMode + SafetyMeasure + FTA) and wrap it in a
`dependability_analysis`. *(score-safety-analysis)*
4. **Safety analysis** → add `failure_modes`, `fault_trees` (FTA, `deps = [failure_modes]`) and
`safety_analysis` (`safety_measures`: Mitigation files + AoU / `component_requirements`
targets) and wrap it in a `dependability_analysis`. AoU targets and
`component_requirements` list `fault_trees` in `deps`; AoU targets passed as `safety_measures`
are the element's own AoUs (derived, deduplicated, forwarded to dependees). *(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`.
`dependability_analysis`, `glossary`, and `integrity_level`.

---

Expand Down
1 change: 0 additions & 1 deletion .github/skills/score-architecture/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,6 @@ 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 = [],
Expand Down
12 changes: 8 additions & 4 deletions .github/skills/score-requirements/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,14 @@ component-internal requirements with no feature-level parent.

### Assumptions of Use (AoU)

`AoU` extends `RequirementSafety` (not `SafetyMeasure`) and captures conditions the integrating
project must satisfy, via its own independent, optional `root_causes` field.
The `assumptions_of_use` rule accepts raw `.trlc` **or** `.rst` files carrying `aou_req`
directives (converted to TRLC automatically).
`AoU` extends `SafetyMeasure` and captures conditions the integrating project must satisfy.
`root_causes` is mandatory: every AoU references the fault-tree root causes it addresses
(`<fta_package>.<RootCause>`), so the `assumptions_of_use` target lists the `fault_trees` target
in `deps`. The `assumptions_of_use` rule accepts raw `.trlc` **or** `.rst` files carrying `aou_req`
directives (converted to TRLC automatically; RST directives take `:root_causes: <fta_package>.<RootCause>, ...`).
Pass the target as `safety_measures` to `safety_analysis`: that makes it an own AoU of the
`dependable_element` (there is no AoU attribute on the element). Forwarding YAML
entries name received AoUs with their version (`Package.Name@1`).

---

Expand Down
26 changes: 15 additions & 11 deletions .github/skills/score-safety-analysis/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ argument-hint: "interface or component name to analyse"
score/<component>/dependability/
├── safety_analysis/
│ ├── failure_modes.trlc # FailureMode records (one per unique root-cause cluster)
│ ├── safetymeasures.trlc # Mitigation / AoU / CompReq records
│ ├── safetymeasures.trlc # Mitigation records
│ ├── fta_<failure_mode>.puml # One FTA diagram per FailureMode
│ └── BUILD # safety_analysis() rule — must list all .puml in fta_files filegroup
│ └── BUILD # failure_modes() + fault_trees() + safety_analysis() rules — must list all .puml in fta_files filegroup
├── assumed_system/
│ └── aous.trlc # AoU records (caller obligations)
│ └── aous.trlc # AoU records (caller obligations, each with root_causes)
└── requirements/
└── component_requirements.trlc
```
Expand Down Expand Up @@ -93,7 +93,7 @@ until each `$RootCause` is something you can place a measure on.
|------|--------------|------------|
| `Mitigation` | the SEooC itself provides a dedicated safety measure (with a mandatory `justification`) | `root_causes` |
| `CompReq` | a normal, implemented-and-tested component requirement already closes it | `derived_from` |
| `AoU` | can only be guaranteed by the **integrator/caller** | `root_causes` (optional) |
| `AoU` | can only be guaranteed by the **integrator/caller** | `root_causes` (mandatory) |

Use an `AoU` to **push an obligation outward** when the SEooC cannot close a cause itself; it must
be forwarded to the integrating project. Record *why* a measure is sufficient (AND-gate argument,
Expand Down Expand Up @@ -159,7 +159,7 @@ $RootCause("<Root cause label 2>", "<RootCauseAlias2>", "OG1")
| `$TransferInGate(name, alias, connection)` | Link to sub-tree | parent alias |

**Rules:**
- `$RootCause` alias is a plain identifier; the `puml_cli` FTA parser auto-generates a `fta_events.trlc` stub (imported as `<name>_fta`) containing a `RootCause` record named after that alias (its `failure_modes` lists the `FailureMode`s of the tree's `$FailureMode` root) — `Mitigation`/`CompReq`/`AoU` records reference it explicitly (e.g. `root_causes = [sample_safety_analysis_fta.JustBadLuck]`); there is no implicit name-matching.
- `$RootCause` alias is a plain identifier; the `puml_cli` FTA parser auto-generates a `fta_events.trlc` stub (imported as `<fta_package>`, default derived from the target label) containing a `RootCause` record named after that alias (its `failure_modes` lists the `FailureMode`s of the tree's `$FailureMode` root) — `Mitigation`/`CompReq`/`AoU` records reference it explicitly (e.g. `root_causes = [sample_safety_analysis_fta.JustBadLuck]`); there is no implicit name-matching.
- Build top-down in the file: `$FailureMode` first, then gates, then `$RootCause` leaves.
- The same `$RootCause` 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.
Expand All @@ -182,13 +182,16 @@ ScoreReq.Mitigation <RecordName> {

Other ways to close a root cause:
- `ScoreReq.CompReq` — closes it via `derived_from`, referencing the `RootCause` stub alongside any `FeatReq`/`AssumedSystemReq` it also derives from. An `AoU` in `derived_from` is only for an AoU **received** from another dependable element; the element's own AoUs are never a `derived_from` source
- `ScoreReq.AoU` — own assumption the caller must satisfy; does **not** extend `SafetyMeasure` and has its own independent, optional `root_causes` field (no `justification` required)
- `ScoreReq.AoU` — own assumption the caller must satisfy; extends `SafetyMeasure`, so `root_causes` is **mandatory** (no `justification` required)

**Rule:** every `$RootCause` alias must be referenced by at least one `Mitigation.root_causes`, `CompReq.derived_from`, or `AoU.root_causes`. This is checked by lobster in the traceability report of the enclosing `dependable_element` (Root Causes are covered via the Safety Measures level **or** the Component Requirements level; uncovered ones are reported as `missing reference to Component Requirements or Safety Measures`, and fail `bazel test <dependable_element>` with `maturity = "release"`). Only files passed as `safety_analysis.safetymeasures` form the Safety Measures level, so an AoU file with `root_causes` must be listed there **and** the `assumptions_of_use` target must list the `safety_analysis` target in `deps` (the generated `<fta_package>` package resolves only through it). Every AoU in a `safetymeasures` file must reference a root cause, otherwise it is reported as `missing up reference`; keep AoUs without `root_causes` in a separate file passed only to `assumptions_of_use`:
**Rule:** every `$RootCause` alias must be referenced by at least one `Mitigation.root_causes`, `CompReq.derived_from`, or `AoU.root_causes`. This is checked by lobster in the traceability report of the enclosing `dependable_element` (Root Causes are covered via the Safety Measures level **or** the Component Requirements level; uncovered ones are reported as `missing reference to Component Requirements or Safety Measures`, and fail `bazel test <dependable_element>` with `maturity = "release"`). The safety analysis is three rules: `failure_modes` (the `FailureMode` records), `fault_trees` (`srcs` = FTA diagrams, `deps` = the `failure_modes` targets; generates the `<fta_package>` root causes) and `safety_analysis` (`failure_modes`, `fault_trees` and `safety_measures`: `Mitigation` `.trlc` files plus `assumptions_of_use` / `component_requirements` targets; only their own records are rendered, targets in their `deps` just resolve references; raw `.trlc` files may only hold `Mitigation` records, and every failure mode a root cause references must be in `failure_modes`). Any target whose records reference `<fta_package>.<RootCause>` (`assumptions_of_use`, `component_requirements`) must list the `fault_trees` target in `deps`. Every `assumptions_of_use` target passed as `safety_measures` is an own AoU of the enclosing `dependable_element` (derived, deduplicated by label, forwarded to dependees); one no `safety_analysis` lists is neither rendered nor forwarded:

```python
safety_analysis(name = "sa", safetymeasures = ["aou.trlc"], ...)
assumptions_of_use(name = "aous", srcs = ["aou.trlc"], deps = [":sa"])
failure_modes(name = "fm", srcs = ["failure_modes.trlc"])
fault_trees(name = "ft", srcs = [":fta_files"], deps = [":fm"])
assumptions_of_use(name = "aous", srcs = ["aous.trlc"], deps = [":ft"])
safety_analysis(name = "sa", arch_design = ":arch", failure_modes = [":fm"], fault_trees = ":ft",
safety_measures = [":aous", "mitigations.trlc"])
```

## Step 4 — Update BUILD
Expand Down Expand Up @@ -228,7 +231,8 @@ $RootCause alias → Mitigation.root_causes / CompReq.derived_from / AoU.r
| `$FailureMode` fm1..fm8 argument does not match any TRLC record | Ensure `<Pkg>.<RecordName>` is spelled identically in both places |
| A root cause (`$RootCause`) is not referenced by any `Mitigation`/`CompReq`/`AoU` | Add an explicit reference to the generated `<fta_package>.<Alias>` `RootCause` stub |
| New `.puml` not in BUILD `fta_files` | Add the file path to the `srcs` list |
| AoU added to `safetymeasures.trlc` | AoUs belong in `aous.trlc`; `AoU` does not extend `SafetyMeasure`, it has its own independent `root_causes` field. If the AoU closes a root cause, pass `aous.trlc` as `safety_analysis.safetymeasures` (coverage) and add the `safety_analysis` target to `assumptions_of_use.deps` |
| AoU added to `safetymeasures.trlc` | AoUs belong in `aous.trlc` and are passed to `safety_analysis` via `safety_measures` (the `assumptions_of_use` target), not inside the `Mitigation` `.trlc` file (the assembler rejects non-`Mitigation` records there). Each AoU needs `root_causes`. |
| `CompReq.derived_from` references an own `AoU` | Only AoUs received from another dependable element belong there; own AoUs close root causes via `AoU.root_causes` |
| Unknown symbol `<fta_package>` when parsing `aous.trlc` | Add the `safety_analysis` target to the `assumptions_of_use` `deps` |
| Unknown symbol `<fta_package>` when parsing `aous.trlc` or component requirements | Add the `fault_trees` target to the `deps` of the `assumptions_of_use` / `component_requirements` |
| `safety_analysis` fails: root cause references a failure mode not in `failure_modes` | Add the `failure_modes` target holding it to `safety_analysis.failure_modes` |
| Wrong RSL used for trlc validation | Always pass the tooling RSL as the first directory argument |
10 changes: 10 additions & 0 deletions bazel/rules/rules_score/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ py_binary(
],
)

# Merges lobster files, collapsing the same item arriving via several paths
py_binary(
name = "merge_lobster_items",
srcs = ["src/merge_lobster_items.py"],
imports = ["src"],
main = "src/merge_lobster_items.py",
visibility = ["//visibility:public"],
deps = ["@lobster//lobster/common"],
)

# HTML merge tool
py_library(
name = "sphinx_html_merge_lib",
Expand Down
61 changes: 47 additions & 14 deletions bazel/rules/rules_score/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ for safety related automotive software.
| `architectural_design` | `ArchitecturalDesignInfo` |
| `unit` | `UnitInfo`, `CertifiedScope` |
| `component` | `ComponentInfo` |
| `safety_analysis` | `AnalysisInfo` |
| `failure_modes` | `FailureModesInfo`, `TrlcProviderInfo` |
| `fault_trees` | `FaultTreesInfo`, `TrlcProviderInfo` |
| `safety_analysis` | `AnalysisInfo`, `SafetyAnalysisProviderInfo` |
| `glossary` | `SphinxSourcesInfo` |
| `dependability_analysis` | `DependabilityAnalysisInfo` |
| `dependable_element` | HTML documentation zip (Sphinx) |
Expand Down Expand Up @@ -71,9 +73,11 @@ assumptions_of_use(
```

**`bazel build`** — renders the AoU TRLC/RST sources and exposes their
LOBSTER traceability file via `AssumptionsOfUseInfo.aou_lobster`. Tracing to
feature/assumed-system requirements is established at the `dependable_element`
level (via its own `requirements` attribute), not here.
LOBSTER traceability file via `AssumptionsOfUseInfo.aou_lobster`. Every `AoU`
references the fault-tree root cause(s) it addresses (`root_causes`, mandatory);
list the `fault_trees` target in `deps` so `<fta_package>.<RootCause>` resolves.
Tracing to feature/assumed-system requirements is established at the
`dependable_element` level (via its own `requirements` attribute), not here.

---

Expand Down Expand Up @@ -137,23 +141,53 @@ and collects requirement + architecture + test lobster sources.

---

## `safety_analysis`
## `failure_modes` / `fault_trees` / `safety_analysis`

Three stages avoid a dependency cycle: the fault trees reference the failure
modes, the measures (AoUs, component requirements) reference root causes, and
the safety analysis lists the failure modes and the measures.

```starlark
failure_modes(
name = "my_failure_modes",
srcs = ["failure_modes.trlc"],
)

fault_trees(
name = "my_fault_trees",
srcs = ["fta.puml"],
deps = [":my_failure_modes"],
)

assumptions_of_use(
name = "my_aou",
srcs = ["aous.trlc"],
deps = [":my_fault_trees"],
)

safety_analysis(
name = "my_safety_analysis",
failuremodes = [":failure_modes"],
root_causes = ["fta.puml"],
safetymeasures = [":safetymeasures"],
arch_design = ":my_design",
failure_modes = [":my_failure_modes"],
fault_trees = ":my_fault_trees",
safety_measures = [":my_aou", "mitigations.trlc"],
)
```

**`bazel build`** — generates `safety_analysis.rst` (failure modes with their root causes and measures, fault trees, safety measures),
runs `lobster-trlc` on TRLC inputs, and extracts FTA events from `.puml`
diagrams into `fta_events.trlc` (generated `RootCause` records, usable via the
target's `TrlcProviderInfo`). Build-only; traceability validation is done
by the wrapping `dependability_analysis` test.
**`bazel build` (`failure_modes`)** — runs `lobster-trlc` on the `FailureMode`
records.

**`bazel build` (`fault_trees`)** — extracts FTA events from `.puml` diagrams
into `fta_events.trlc` (generated `RootCause` records, usable via the target's
`TrlcProviderInfo`) and runs `lobster-trlc` on the root causes.

**`bazel build` (`safety_analysis`)** — generates `safety_analysis.rst` (failure
modes with their root causes and measures, fault trees) and runs `lobster-trlc`
on the measures. Raw `.trlc` files in `safety_measures` may only hold
`Mitigation` records; a root cause whose failure mode is not in `failure_modes`
fails the build. Build-only; traceability validation is done by the wrapping
`dependability_analysis` test. The `dependable_element` derives its own AoUs
from the `assumptions_of_use` targets passed as `safety_measures`.

---

Expand Down Expand Up @@ -244,7 +278,6 @@ dependable_element(
dependability_analysis = [":my_da"],
components = [":my_component"],
glossary = [":project_glossary"],
assumptions_of_use = [],
tests = [],
)
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ rectangle "dependency_a\ndefines AoU_1" <<dep>> as dep_a
rectangle "dependency_b\ndefines AoU_2" <<dep>> as dep_b

rectangle "one_seooc" <<seooc>> as seooc {
rectangle "received AoUs\n(each dep's own_aou_trlc +\nall_received_trlc, merged)" <<received>> as received
rectangle "received AoUs\n(each dep's own_aou_lobster +\nchain_forwarded_lobster, merged)" <<received>> as received
rectangle "AoU_1 -- handled locally\n(CompReq.derived_from)" <<handled>> as handled
rectangle "AoU_2 -- chain-forwarded\n(aou_forwarding.yaml)" <<forwarded>> as forwarded
rectangle "own AoU_3\n(auto-forwarded)" <<forwarded>> as own
Expand Down
11 changes: 9 additions & 2 deletions bazel/rules/rules_score/docs/_assets/rules_score_overview.puml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ component "unit" <<implementation>> as unit
component "component" <<implementation>> as comp

' ── Safety Analysis rules ─────────────────────────────────────────────────────
component "failure_modes" <<analysis>> as failure_modes
component "fault_trees" <<analysis>> as fault_trees
component "safety_analysis" <<analysis>> as safety_analysis
component "dependability_analysis" <<analysis>> as da

Expand All @@ -65,10 +67,15 @@ feat_req --> de : <<FeatureRequirementsInfo>>
comp_req --> comp : <<ComponentRequirementsInfo>>
comp_req --> aou : <<ComponentRequirementsInfo>>

safety_analysis --> da : <<AnalysisInfo>>
failure_modes --> fault_trees : <<TrlcProviderInfo>>
failure_modes --> safety_analysis : <<FailureModesInfo>>
fault_trees --> safety_analysis : <<FaultTreesInfo>>
fault_trees --> aou : <<TrlcProviderInfo>>
fault_trees --> comp_req : <<TrlcProviderInfo>>
safety_analysis --> da : <<AnalysisInfo>>\n<<SafetyAnalysisProviderInfo>>
da --> de : <<DependabilityAnalysisInfo>>

aou --> de : <<AssumptionsOfUseInfo>>
aou --> safety_analysis : <<AssumptionsOfUseInfo>>
unit --> comp : <<UnitInfo>>
comp --> de : <<ComponentInfo>>

Expand Down
Loading
Loading