|
| 1 | +# Exploring possibilities for integrating StrictDoc with ELISA’s requirements template approach for the Linux kernel |
| 2 | + |
| 3 | +This demonstrates how to realize the tool-agnostic |
| 4 | +[ELISA Kernel Requirements Template](https://docs.google.com/document/d/1c7S7YAledHP2EEQ2nh26Ibegij-XPNuUFkrFLtJPlzs/edit?tab=t.0) |
| 5 | +proposal by using [StrictDoc](https://strictdoc.readthedocs.io) as requirements |
| 6 | +processing tool. The repository is a copy of the Linux kernel with requirements |
| 7 | +and tests from Alessandro Carminat and Gabriele Paoloni ([^1], [^2]) applied on |
| 8 | +top. ELISA's |
| 9 | +[`SPDX-*` tagging scheme]((https://docs.google.com/document/d/1c7S7YAledHP2EEQ2nh26Ibegij-XPNuUFkrFLtJPlzs/edit?tab=t.0#heading=h.9dudo2y6dlhf)) |
| 10 | +was |
| 11 | +[added](https://github.com/strictdoc-project/linux-strictdoc/commit/a59697d733f2) |
| 12 | +along with a minimal StrictDoc project configuration. |
| 13 | + |
| 14 | +[^1]: https://lore.kernel.org/all/20250910170000.6475-1-gpaoloni@redhat.com/ |
| 15 | +[^2]: https://lore.kernel.org/linux-trace-kernel/20250814122206.109096-1-gpaoloni@redhat.com/#r |
| 16 | + |
| 17 | +Go to [rendered requirements](https://strictdoc-project.github.io/linux-strictdoc/). |
| 18 | + |
| 19 | +## Demonstrated features |
| 20 | + |
| 21 | +- Use `strictdoc export .` to generate a nice |
| 22 | + [static HTML document tree](https://strictdoc-project.github.io/linux-strictdoc/linux-strictdoc/Documentation/requirements/charmisc.html) |
| 23 | + with visual representation of the |
| 24 | + [traceability graph](https://strictdoc-project.github.io/linux-strictdoc/linux-strictdoc/Documentation/requirements/charmisc-TRACE.html#DOC-SUBSYS-CHARMISC), |
| 25 | + validation results and full-text search. Other output formats as e.g. PDF are available. |
| 26 | +- Compile and validate requirements |
| 27 | + [in CI](https://github.com/strictdoc-project/linux-strictdoc/blob/lpc25/.github/workflows/ci.yaml). |
| 28 | +- Parses source code |
| 29 | + [SPDX-Req-* tags proposed by ELISA](https://docs.google.com/document/d/1c7S7YAledHP2EEQ2nh26Ibegij-XPNuUFkrFLtJPlzs/edit?tab=t.0#heading=h.9dudo2y6dlhf) |
| 30 | + and translates them to StrictDocs internal model. |
| 31 | +- Sidecar: Proposed by ELISA to hold additional requirement meta data outside source code. Realized as |
| 32 | + [separate sdoc file](https://github.com/strictdoc-project/linux-strictdoc/blob/lpc25/Documentation/requirements/tracing.sdoc)s |
| 33 | + containing requirement stubs. Stubs are merged with source code tags by matching on `SPDX-Req-ID`. |
| 34 | +- Use `strictdoc manage auto-assign` to generate SPDX-Req-ID and SPDX-Req-HKey as suggested by Linux kernel |
| 35 | + requirements template. The hash generation method is `echo -nE "${PROJECT}${FILE_PATH}${INSTANCE}${CODE}" | sha256sum`. |
| 36 | + See [commit f8fbab99aa42](https://github.com/strictdoc-project/linux-strictdoc/commit/f8fbab99aa42) |
| 37 | + for the auto-generated changes. |
| 38 | +- Tracing: Requirements, tests and functions become individual nodes in the traceability graph and are connected |
| 39 | + by their stable IDs. |
| 40 | +- Semantic [changelog](https://strictdoc-project.github.io/linux-strictdoc/diff_view/changelog.html) and |
| 41 | + [diff](https://strictdoc-project.github.io/linux-strictdoc/diff_view/diff.html): |
| 42 | + Highlight documentation items that have been added, moved, changed. |
| 43 | +- Custom validations: Use plugin API to |
| 44 | + [provide a check](https://github.com/strictdoc-project/linux-strictdoc/blob/lpc25/tools/requirements/validation_plugin.py#L28) |
| 45 | + to see if each requirement has at least one associated test, and each function expectations has at least one dedicated |
| 46 | + test. |
| 47 | +- Drift detection: As kernel development goes on, occasionally rerun `strictdoc manage auto-assign`. If `SPDX-Req-HKey` |
| 48 | + changes, this means that some semantic aspect of the requirement may have changed. |
| 49 | + |
| 50 | +For a thorough documentation of StrictDocs features see |
| 51 | +[StrictDoc User Guide ](https://strictdoc.readthedocs.io/en/stable/stable/docs/strictdoc_01_user_guide.html) |
| 52 | + |
| 53 | +Experiments unrelated to StrictDoc: |
| 54 | +- Semantic search for LLR candidates: |
| 55 | + There should be consensus which functions are "most valuable" to document. |
| 56 | + Coccinelle allows to |
| 57 | + [document that consensus](https://github.com/strictdoc-project/linux-strictdoc/blob/lpc25/scripts/coccinelle/docs/) |
| 58 | + in a machine readable and executable way. |
| 59 | + |
| 60 | +## Tutorial: Add a Requirement |
| 61 | + |
| 62 | +### Install StrictDoc |
| 63 | +```sh |
| 64 | +pipx install strictdoc # note: requires strictdoc >= 0.15.1 |
| 65 | +git clone https://github.com/strictdoc-project/linux-strictdoc |
| 66 | +cd linux-strictdoc |
| 67 | +``` |
| 68 | + |
| 69 | +### Edit |
| 70 | + |
| 71 | +Add requirement statement and temporary identifier to source code comment |
| 72 | + |
| 73 | +`kernel/trace/trace_events.c` |
| 74 | +```c |
| 75 | +/* |
| 76 | + * SPDX-Req-ID: TMP-trace_events_enabled |
| 77 | + * SPDX-Req-Text: |
| 78 | + * This function shall check if there are enabled events in the provided list. |
| 79 | + * |
| 80 | + * Returns: |
| 81 | + * 0 : no events exist? |
| 82 | + * 1 : all events are disabled |
| 83 | + * 2 : all events are enabled |
| 84 | + * 3 : some events are enabled and some are enabled |
| 85 | + */ |
| 86 | +int trace_events_enabled(struct trace_array *tr, const char *system) |
| 87 | +``` |
| 88 | +
|
| 89 | +Add corresponding requirement stub in sidecar file |
| 90 | +
|
| 91 | +`Documentation/requirements/tracing.sdoc` |
| 92 | +``` |
| 93 | +[REQUIREMENT] |
| 94 | +MID: TMP-trace_events_enabled |
| 95 | +TITLE: trace_events_enabled |
| 96 | +``` |
| 97 | +
|
| 98 | +### Finish |
| 99 | +
|
| 100 | +Calculate stable identifier and hash value, will be replaced inline |
| 101 | +```sh |
| 102 | +strictdoc manage auto-uid . |
| 103 | +``` |
| 104 | + |
| 105 | +Verify new hash values were added and no existing requirement was changed |
| 106 | +```sh |
| 107 | +git diff |
| 108 | +``` |
| 109 | + |
| 110 | +```diff |
| 111 | +diff --git a/Documentation/requirements/tracing.sdoc b/Documentation/requirements/tracing.sdoc |
| 112 | +index 8d1dd2b5..2d86384a 100644 |
| 113 | +--- a/Documentation/requirements/tracing.sdoc |
| 114 | ++++ b/Documentation/requirements/tracing.sdoc |
| 115 | +@@ -22,6 +22,11 @@ TITLE: Event Tracing |
| 116 | + MID: 1ac497acf75d497f893006853f85fe86 |
| 117 | + TITLE: Requirements |
| 118 | + |
| 119 | ++[REQUIREMENT] |
| 120 | ++MID: b12884ce9b5b3258f1d28026c8aa1526f94030fd9f61ba583560f472015b1abb |
| 121 | ++HASH: 5949e5bf7ec43ed2c665d4ffe614dfaa285aafbe73a77df55aef0c099637f65b |
| 122 | ++TITLE: trace_events_enabled |
| 123 | ++ |
| 124 | + [REQUIREMENT] |
| 125 | + MID: 77958d2a51762caa727e5751d8dfec127c07cb5385f542d7b2fdf26b2a07c8b3 |
| 126 | + HASH: e8ee84ca42f5626ca9636abb53ded027708fdaabc99c8b935c016dda53130d81 |
| 127 | +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c |
| 128 | +index 16dabd1f..d07db4fa 100644 |
| 129 | +--- a/kernel/trace/trace_events.c |
| 130 | ++++ b/kernel/trace/trace_events.c |
| 131 | +@@ -2062,6 +2062,9 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, |
| 132 | + } |
| 133 | + |
| 134 | + /* |
| 135 | ++ * SPDX-Req-ID: b12884ce9b5b3258f1d28026c8aa1526f94030fd9f61ba583560f472015b1abb |
| 136 | ++ * SPDX-Req-Text: This function shall check if there are enabled events in the provided list. |
| 137 | ++ * |
| 138 | + * Returns: |
| 139 | + * 0 : no events exist? |
| 140 | + * 1 : all events are disabled |
| 141 | +``` |
| 142 | + |
| 143 | +Verify and validate |
| 144 | +```sh |
| 145 | +strictdoc export . |
| 146 | +``` |
| 147 | + |
| 148 | +### Send for Review |
| 149 | + |
| 150 | +```sh |
| 151 | +git add -u && git commit -m "docs: Add LLR for trace_events_enabled" |
| 152 | +git format-patch -n1 |
| 153 | +``` |
| 154 | + |
| 155 | +## Explanation of Content and Processing |
| 156 | + |
| 157 | +``` |
| 158 | +. |
| 159 | +├── Documentation |
| 160 | +│ └── requirements |
| 161 | +│ ├── charmisc.sdoc # sidecar |
| 162 | +│ └── tracing.sdoc # sidecar |
| 163 | +├── drivers |
| 164 | +│ └── char |
| 165 | +│ └── mem.c # Linux code with inlined LLRs |
| 166 | +├── kernel |
| 167 | +│ └── trace |
| 168 | +│ └── trace_events.c # Linux code with inlined LLRs |
| 169 | +├── scripts |
| 170 | +│ └── coccinelle |
| 171 | +│ └── docs |
| 172 | +│ └── *.cocci # SmPL to discover LLR candidates |
| 173 | +├── strictdoc_config.py # StrictDoc project configuration |
| 174 | +└── tools |
| 175 | + ├── requirements |
| 176 | + │ └── validation_plugin.py # custom requirement validations |
| 177 | + └── testing |
| 178 | + └── selftests |
| 179 | + └── devmem |
| 180 | + └── tests.c # tests for /dev/mem LLRs |
| 181 | +``` |
| 182 | + |
| 183 | +StrictDoc performs the following notable process steps: |
| 184 | +- parse \*.sdoc files to create the initial traceability index (a DAG structure) |
| 185 | +- parse \*.c files using tree-sitter, read SPDX tags from it and merge it into the DAG |
| 186 | +- perform built-in validations and calculate built-in statistics |
| 187 | +- perform custom validations |
| 188 | + * check if all requirements have at least one related test |
| 189 | + * check if all function expectations are mentioned by one related test |
| 190 | +- render the DAG into a HTML document tree where all nodes are traceable, including |
| 191 | + requirements text, visual graph representation and source code view |
| 192 | + |
| 193 | +## Handling Fields with Special Meaning but Different Name in StrictDoc / ELISA |
| 194 | + |
| 195 | +The StrictDoc model assigns special meaning to some reserved field names: |
| 196 | +- `UID` Unique, human-readable. May change during requirement life-cycle. Used to refer to child/parents by default. |
| 197 | +- `MID`: Unique, not human-readable, stable. Optionally used to refer to child/parents. |
| 198 | + Supports changing the human-readable UID during the requirement life-cycle. |
| 199 | +- `HASH`: Hash sum over predefined requirement content. Can be auto-calculated. |
| 200 | +- `STATEMENT`: Some document views and import/export formats require to select a "most important" |
| 201 | + field from the many fields. |
| 202 | +- `COMMENT`: Can occur multiple times within one requirement. |
| 203 | + |
| 204 | +The ELISA requirements template defines similar special meaning for fields, but under different name. |
| 205 | +This is solved by two StrictDoc features: |
| 206 | +- `ProjectConfig(source_nodes=[SourceNodesEntry(sdoc_to_source_map={<sdoc_name>: <elisa_name>, ...})])` let's you define |
| 207 | + a mapping for fields that appearing under a different name in source code tags. |
| 208 | + Example: The stable ID appears as `SPDX-Req-ID` in source code comments, but must be named `MID` in sdoc. |
| 209 | +- Setting `HUMAN_TITLE` in the grammar lets you define a different display name for a field that has special |
| 210 | + StrictDoc meaning. Example: ELISA wants `HASH` to be named `SPDX-Req-HKey`. Since the field appears only in sdoc, |
| 211 | + but not in source code, it's enough to define `HUMAN_TITLE: SPDX-Req-HKey` for the `HASH` field. |
| 212 | + `sdoc_to_source_map` is not needed in this case. |
0 commit comments