From a18612b62fba72229c7675263f34ce1279d82760 Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:34:14 +0000 Subject: [PATCH 01/14] docs: add rust test traces --- test/rust/integration-tests.bats | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/rust/integration-tests.bats b/test/rust/integration-tests.bats index 53109ab9..752e366f 100644 --- a/test/rust/integration-tests.bats +++ b/test/rust/integration-tests.bats @@ -26,6 +26,7 @@ teardown() { } @test "valid code input should result in working executable targeting the host architecture" { + # @sbdl test-comp-0008 is test { custom:title is [[[[@-LINE]]]]; requirement is req-comp-0001 } rustc --out-dir build rust/hello.rs run build/hello @@ -34,6 +35,7 @@ teardown() { } @test "using cargo run should result in working executable" { + # @sbdl test-comp-0009 is test { custom:title is [[[[@-LINE]]]]; requirement is req-comp-0001 } pushd cargo run cargo run @@ -44,12 +46,14 @@ teardown() { } @test "invalid code input should result in failing build" { + # @sbdl test-comp-0010 is test { custom:title is [[[[@-LINE]]]]; requirement is req-comp-0001 } run rustc rust/fail.rs assert_failure assert_output --partial "error: " } @test "running clippy should result in warning diagnostics" { + # @sbdl test-sda-0008 is test { custom:title is [[[[@-LINE]]]]; requirement is req-sda-0002 } pushd clippy run cargo clippy @@ -60,6 +64,7 @@ teardown() { } @test "running rustfmt should result in re-formatted code" { + # @sbdl test-sda-0009 is test { custom:title is [[[[@-LINE]]]]; requirement is req-sda-0001 } run rustfmt --color=never --check rust/unformatted.rs assert_failure assert_output --partial - < Date: Tue, 27 Oct 2026 11:46:26 +0000 Subject: [PATCH 02/14] docs: expose verification procedure sources Show full source references in the SVP and RTM and distinguish declared traceability from execution evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../templates/requirements-traceability-matrix.md.j2 | 12 ++++++------ docs/templates/software-verification-plan.md.j2 | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/templates/requirements-traceability-matrix.md.j2 b/docs/templates/requirements-traceability-matrix.md.j2 index 00ad60ec..ad41cb52 100644 --- a/docs/templates/requirements-traceability-matrix.md.j2 +++ b/docs/templates/requirements-traceability-matrix.md.j2 @@ -26,7 +26,7 @@ footer-right: "\\thepage \\hspace{1pt} of \\pageref*{lastpage}" ## Purpose -This document provides a requirements traceability matrix (RTM) for amp-devcontainer. It maps each requirement to its associated verification tests, providing evidence of test coverage across the system. +This document provides a requirements traceability matrix (RTM) for amp-devcontainer. It maps each requirement to its declared verification tests and their source locations. A trace link does not establish that a test was executed or passed. ## Abstract @@ -45,8 +45,8 @@ The authoritative source of change history is the [Git log](https://github.com/p ## {{ utils.reencode(utils.strip_gherkin_prefix(item['custom:title'])) }} -| Requirement | Test | Status | -|-------------|------|--------| +| Requirement | Test | Source | Traceability | +|-------------|------|--------|--------------| {%- if 'requirement' in item %} {%- for req_ref in item.requirement %} @@ -68,10 +68,10 @@ The authoritative source of change history is the [Git log](https://github.com/p {%- if ns_tests.test_list -%} {%- for test_id in ns_tests.test_list %} {%- set test_name = utils.strip_bats_syntax(sbdl[test_id]['custom:title']) | trim %} -| {{ utils.display_short(req_name) }} | {{ test_id }}: {{ utils.display_short(test_name) }} | Traced | +| {{ utils.display_short(req_name) }} | {{ test_id }}: {{ utils.display_short(test_name) }} | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | {%- endfor -%} {%- else %} -| {{ utils.display_short(req_name) }} | — | **Not covered** | +| {{ utils.display_short(req_name) }} | — | — | **Untraced** | {%- endif -%} {%- endfor %} @@ -79,7 +79,7 @@ The authoritative source of change history is the [Git log](https://github.com/p {%- endif %} {%- endfor %} -# Coverage Summary +# Declared Traceability Summary {%- set ns_summary = namespace(total_reqs=0, covered_reqs=0, total_tests=0) -%} diff --git a/docs/templates/software-verification-plan.md.j2 b/docs/templates/software-verification-plan.md.j2 index 86091a02..4cc9d2cb 100644 --- a/docs/templates/software-verification-plan.md.j2 +++ b/docs/templates/software-verification-plan.md.j2 @@ -164,6 +164,7 @@ _Verification activities_ {%- for test_req_ref in test_elem.requirement if test_req_ref.identifier == req_ref.identifier -%} {%- set ns_tests.has_tests = true %} - **{{ test_id }}**: {{ utils.reencode(utils.strip_bats_syntax(test_elem['custom:title'])) }} + Source: {% if test_elem.reference is defined and test_elem.reference %}`{{ test_elem.reference }}`{% else %}Unavailable{% endif %} {%- endfor -%} {%- endif -%} {%- endif -%} From ece76b42339a14fa5cf0b8a8d4e043fad50e86fa Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 11:56:02 +0000 Subject: [PATCH 03/14] docs: link compact RTM test identifiers to verification plan Keep full procedure descriptions in the SVP and link to unique requirement/procedure anchors from the RTM. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/templates/requirements-traceability-matrix.md.j2 | 3 +-- docs/templates/software-verification-plan.md.j2 | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/templates/requirements-traceability-matrix.md.j2 b/docs/templates/requirements-traceability-matrix.md.j2 index ad41cb52..ceef14a8 100644 --- a/docs/templates/requirements-traceability-matrix.md.j2 +++ b/docs/templates/requirements-traceability-matrix.md.j2 @@ -67,8 +67,7 @@ The authoritative source of change history is the [Git log](https://github.com/p {%- if ns_tests.test_list -%} {%- for test_id in ns_tests.test_list %} -{%- set test_name = utils.strip_bats_syntax(sbdl[test_id]['custom:title']) | trim %} -| {{ utils.display_short(req_name) }} | {{ test_id }}: {{ utils.display_short(test_name) }} | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | +| {{ utils.display_short(req_name) }} | [{{ test_id }}](software-verification-plan.md#{{ req_ref.identifier }}-{{ test_id }}) | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | {%- endfor -%} {%- else %} | {{ utils.display_short(req_name) }} | — | — | **Untraced** | diff --git a/docs/templates/software-verification-plan.md.j2 b/docs/templates/software-verification-plan.md.j2 index 4cc9d2cb..34f8e5d4 100644 --- a/docs/templates/software-verification-plan.md.j2 +++ b/docs/templates/software-verification-plan.md.j2 @@ -163,7 +163,7 @@ _Verification activities_ {%- if 'requirement' in test_elem -%} {%- for test_req_ref in test_elem.requirement if test_req_ref.identifier == req_ref.identifier -%} {%- set ns_tests.has_tests = true %} -- **{{ test_id }}**: {{ utils.reencode(utils.strip_bats_syntax(test_elem['custom:title'])) }} +- **{{ test_id }}**: {{ utils.reencode(utils.strip_bats_syntax(test_elem['custom:title'])) }} Source: {% if test_elem.reference is defined and test_elem.reference %}`{{ test_elem.reference }}`{% else %}Unavailable{% endif %} {%- endfor -%} {%- endif -%} From 49220f6331eeab960b20597c845c6be138468931 Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:00:05 +0000 Subject: [PATCH 04/14] docs: use PDF-safe verification references Use stable test IDs and a textual SVP reference instead of Markdown cross-document links and HTML anchors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/templates/requirements-traceability-matrix.md.j2 | 5 ++++- docs/templates/software-verification-plan.md.j2 | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/templates/requirements-traceability-matrix.md.j2 b/docs/templates/requirements-traceability-matrix.md.j2 index ceef14a8..ddb6f878 100644 --- a/docs/templates/requirements-traceability-matrix.md.j2 +++ b/docs/templates/requirements-traceability-matrix.md.j2 @@ -40,6 +40,9 @@ This document is generated from a formal model defined in [sbdl](https://sbdl.de The authoritative source of change history is the [Git log](https://github.com/philips-software/amp-devcontainer/commits/) of the source material from which the model is built. # Traceability Matrix + +Tests are identified by their stable IDs. Full test descriptions are listed under the corresponding requirement in the *Software Verification Plan (SVP)*. + {%- for id, item in sbdl.items() %} {%- if item.type == 'aspect' and 'custom:title' in item %} @@ -67,7 +70,7 @@ The authoritative source of change history is the [Git log](https://github.com/p {%- if ns_tests.test_list -%} {%- for test_id in ns_tests.test_list %} -| {{ utils.display_short(req_name) }} | [{{ test_id }}](software-verification-plan.md#{{ req_ref.identifier }}-{{ test_id }}) | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | +| {{ utils.display_short(req_name) }} | {{ test_id }} | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | {%- endfor -%} {%- else %} | {{ utils.display_short(req_name) }} | — | — | **Untraced** | diff --git a/docs/templates/software-verification-plan.md.j2 b/docs/templates/software-verification-plan.md.j2 index 34f8e5d4..4cc9d2cb 100644 --- a/docs/templates/software-verification-plan.md.j2 +++ b/docs/templates/software-verification-plan.md.j2 @@ -163,7 +163,7 @@ _Verification activities_ {%- if 'requirement' in test_elem -%} {%- for test_req_ref in test_elem.requirement if test_req_ref.identifier == req_ref.identifier -%} {%- set ns_tests.has_tests = true %} -- **{{ test_id }}**: {{ utils.reencode(utils.strip_bats_syntax(test_elem['custom:title'])) }} +- **{{ test_id }}**: {{ utils.reencode(utils.strip_bats_syntax(test_elem['custom:title'])) }} Source: {% if test_elem.reference is defined and test_elem.reference %}`{{ test_elem.reference }}`{% else %}Unavailable{% endif %} {%- endfor -%} {%- endif -%} From da4d14609ac04b9b75b002e6c44b98cb3aa67510 Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:13:12 +0000 Subject: [PATCH 05/14] docs: identify RTM requirements by stable IDs Keep full requirement descriptions in the SRS and preserve capability headings for context. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/templates/requirements-traceability-matrix.md.j2 | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/templates/requirements-traceability-matrix.md.j2 b/docs/templates/requirements-traceability-matrix.md.j2 index ddb6f878..fe6b9258 100644 --- a/docs/templates/requirements-traceability-matrix.md.j2 +++ b/docs/templates/requirements-traceability-matrix.md.j2 @@ -41,20 +41,18 @@ The authoritative source of change history is the [Git log](https://github.com/p # Traceability Matrix -Tests are identified by their stable IDs. Full test descriptions are listed under the corresponding requirement in the *Software Verification Plan (SVP)*. +Requirements and tests are identified by their stable IDs. Full requirement descriptions are listed in the *Software Requirements Specification (SRS)*. Full test descriptions are listed under the corresponding requirement in the *Software Verification Plan (SVP)*. {%- for id, item in sbdl.items() %} {%- if item.type == 'aspect' and 'custom:title' in item %} ## {{ utils.reencode(utils.strip_gherkin_prefix(item['custom:title'])) }} -| Requirement | Test | Source | Traceability | +| Requirement ID | Test ID | Source | Traceability | |-------------|------|--------|--------------| {%- if 'requirement' in item %} {%- for req_ref in item.requirement %} -{%- set req = sbdl[req_ref.identifier] %} -{%- set req_name = utils.reencode(utils.strip_gherkin_prefix(req['custom:title'])) | trim %} {%- set ns_tests = namespace(test_list=[]) -%} @@ -70,10 +68,10 @@ Tests are identified by their stable IDs. Full test descriptions are listed unde {%- if ns_tests.test_list -%} {%- for test_id in ns_tests.test_list %} -| {{ utils.display_short(req_name) }} | {{ test_id }} | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | +| {{ req_ref.identifier }} | {{ test_id }} | {% if sbdl[test_id].reference is defined and sbdl[test_id].reference %}`{{ sbdl[test_id].reference }}`{% else %}Unavailable{% endif %} | Traced | {%- endfor -%} {%- else %} -| {{ utils.display_short(req_name) }} | — | — | **Untraced** | +| {{ req_ref.identifier }} | — | — | **Untraced** | {%- endif -%} {%- endfor %} From b0c68b15d39512d19bbf9c0e942b1d40ec6013c8 Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:21:20 +0000 Subject: [PATCH 06/14] docs: bound supplier model extraction inputs Compile the SBDL model from product feature/test sources and the two annotated workflows instead of recursively ingesting the repository, keeping the documentation fixture out of the supplier model. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/wc-document-generation.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/wc-document-generation.yml b/.github/workflows/wc-document-generation.yml index a4349dca..574e49e5 100644 --- a/.github/workflows/wc-document-generation.yml +++ b/.github/workflows/wc-document-generation.yml @@ -27,7 +27,14 @@ jobs: with: persist-credentials: false - name: Build & Validate SBDL model - run: sbdl -m compile -r . > amp-devcontainer.sbdl + run: | + sbdl -m compile -r \ + test/cpp \ + test/embedded-cpp \ + test/rust/integration-tests.bats \ + .github/workflows/wc-build-push-test.yml \ + .github/workflows/wc-build-push.yml \ + > amp-devcontainer.sbdl - name: Create document control context env: GITHUB_REF_NAME: ${{ github.ref_name }} From 46df98c5acf701a9d2063982b396652537b4b728 Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:25:54 +0000 Subject: [PATCH 07/14] docs: retain full test source model Enumerate all test and workflow source files while excluding only the standalone sample SBDL fixture. Preserve the test model instead of narrowing directory roots. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/wc-document-generation.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/wc-document-generation.yml b/.github/workflows/wc-document-generation.yml index 574e49e5..2514257f 100644 --- a/.github/workflows/wc-document-generation.yml +++ b/.github/workflows/wc-document-generation.yml @@ -28,13 +28,19 @@ jobs: persist-credentials: false - name: Build & Validate SBDL model run: | - sbdl -m compile -r \ - test/cpp \ - test/embedded-cpp \ - test/rust/integration-tests.bats \ - .github/workflows/wc-build-push-test.yml \ - .github/workflows/wc-build-push.yml \ - > amp-devcontainer.sbdl + mapfile -d '' -t sbdl_sources < <( + find test .github/workflows \ + -type f \ + ! -path 'test/docs/workspace/sample.sbdl' \ + -print0 | sort -z + ) + + if ((${#sbdl_sources[@]} == 0)); then + echo "error: no SBDL source files found" >&2 + exit 1 + fi + + sbdl -m compile "${sbdl_sources[@]}" > amp-devcontainer.sbdl - name: Create document control context env: GITHUB_REF_NAME: ${{ github.ref_name }} From 8f5ee527e18f651bf607783b583a10573acf571c Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:28:51 +0000 Subject: [PATCH 08/14] docs: preserve recursive SBDL source discovery Remove only the documentation fixture from the ephemeral checkout before invoking the SBDL compiler recursively. Keep compiler output outside the scanned tree until compilation succeeds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/wc-document-generation.yml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/wc-document-generation.yml b/.github/workflows/wc-document-generation.yml index 2514257f..6c4aba7e 100644 --- a/.github/workflows/wc-document-generation.yml +++ b/.github/workflows/wc-document-generation.yml @@ -28,19 +28,11 @@ jobs: persist-credentials: false - name: Build & Validate SBDL model run: | - mapfile -d '' -t sbdl_sources < <( - find test .github/workflows \ - -type f \ - ! -path 'test/docs/workspace/sample.sbdl' \ - -print0 | sort -z - ) - - if ((${#sbdl_sources[@]} == 0)); then - echo "error: no SBDL source files found" >&2 - exit 1 - fi + set -Eeuo pipefail - sbdl -m compile "${sbdl_sources[@]}" > amp-devcontainer.sbdl + rm test/docs/workspace/sample.sbdl + sbdl -m compile -r . > "${RUNNER_TEMP}/amp-devcontainer.sbdl" + mv "${RUNNER_TEMP}/amp-devcontainer.sbdl" amp-devcontainer.sbdl - name: Create document control context env: GITHUB_REF_NAME: ${{ github.ref_name }} From f024e555ffcfe5d8e61aace63998aa47c60c1ded Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:50:31 +0000 Subject: [PATCH 09/14] docs: remove sample.sbdl before rendering the model --- .github/workflows/wc-document-generation.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/wc-document-generation.yml b/.github/workflows/wc-document-generation.yml index 6c4aba7e..97d2b134 100644 --- a/.github/workflows/wc-document-generation.yml +++ b/.github/workflows/wc-document-generation.yml @@ -31,8 +31,7 @@ jobs: set -Eeuo pipefail rm test/docs/workspace/sample.sbdl - sbdl -m compile -r . > "${RUNNER_TEMP}/amp-devcontainer.sbdl" - mv "${RUNNER_TEMP}/amp-devcontainer.sbdl" amp-devcontainer.sbdl + sbdl -m compile -r . > amp-devcontainer.sbdl - name: Create document control context env: GITHUB_REF_NAME: ${{ github.ref_name }} From 28494ac75179bca2035aabc18708d038063e094c Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:52:23 +0000 Subject: [PATCH 10/14] docs: move shared requirement sources out of test suites Relocate requirement-only compatibility, maintainability, security, and debugging feature sources into docs/requirements while leaving executable scenarios under test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- {test/cpp/features => docs/requirements}/compatibility.feature | 0 {test/cpp/features => docs/requirements}/debugging.feature | 0 .../requirements/embedded-debugging.feature | 0 {test/cpp/features => docs/requirements}/maintainability.feature | 0 {test/cpp/features => docs/requirements}/security.feature | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {test/cpp/features => docs/requirements}/compatibility.feature (100%) rename {test/cpp/features => docs/requirements}/debugging.feature (100%) rename test/embedded-cpp/features/debugging.feature => docs/requirements/embedded-debugging.feature (100%) rename {test/cpp/features => docs/requirements}/maintainability.feature (100%) rename {test/cpp/features => docs/requirements}/security.feature (100%) diff --git a/test/cpp/features/compatibility.feature b/docs/requirements/compatibility.feature similarity index 100% rename from test/cpp/features/compatibility.feature rename to docs/requirements/compatibility.feature diff --git a/test/cpp/features/debugging.feature b/docs/requirements/debugging.feature similarity index 100% rename from test/cpp/features/debugging.feature rename to docs/requirements/debugging.feature diff --git a/test/embedded-cpp/features/debugging.feature b/docs/requirements/embedded-debugging.feature similarity index 100% rename from test/embedded-cpp/features/debugging.feature rename to docs/requirements/embedded-debugging.feature diff --git a/test/cpp/features/maintainability.feature b/docs/requirements/maintainability.feature similarity index 100% rename from test/cpp/features/maintainability.feature rename to docs/requirements/maintainability.feature diff --git a/test/cpp/features/security.feature b/docs/requirements/security.feature similarity index 100% rename from test/cpp/features/security.feature rename to docs/requirements/security.feature From 42bea68614f815bffe6c1e723e152d1f77d42dfb Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 12:56:35 +0000 Subject: [PATCH 11/14] docs: move remaining requirements to shared sources Keep flavor-specific BDD scenarios and their tags under test while moving compilation and analysis declarations to docs/requirements. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/requirements/compilation.feature | 79 +++++++++++++ .../static-dynamic-analysis.feature | 98 ++++++++++++++++ test/cpp/features/compilation.feature | 63 ---------- .../features/static-dynamic-analysis.feature | 108 +----------------- .../embedded-cpp/features/compilation.feature | 18 --- 5 files changed, 183 insertions(+), 183 deletions(-) create mode 100644 docs/requirements/compilation.feature create mode 100644 docs/requirements/static-dynamic-analysis.feature delete mode 100644 test/embedded-cpp/features/compilation.feature diff --git a/docs/requirements/compilation.feature b/docs/requirements/compilation.feature new file mode 100644 index 00000000..9d58a247 --- /dev/null +++ b/docs/requirements/compilation.feature @@ -0,0 +1,79 @@ +Feature: Compilation + # @sbdl-begin + compilation is aspect { + custom:title is "[@-LINE]" + description is + "As a software developer, + to generate a working product, when using compiled languages, + source code needs to be compiled into working software." + } + + using { aspect is compilation } + # @sbdl-end + + Rule: Compile for container host architecture and operating system + # @sbdl-begin + req-comp-0001 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *SHALL* be able to compile valid source code into a + working executable targeting the container host architecture and operating system." + remark is + "Compiling valid source code into working software, able to run on the container host + architecture and operating system, can be necessary in several scenarios; for example when:\n\n + + - the container host is the deployment target\n + - running tests on the container host\n + - building plug-ins, extensions, code generators, or other additional tools that need to + run on the container host" + } + # @sbdl-end + + Rule: Compile for ARM Cortex target architecture + # @sbdl-begin + req-comp-0002 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *SHOULD* be able to compile valid source-code into a working ELF + executable targeting the ARM Cortex architecture." + remark is + "Compiling valid source-code into working ELF executables, able to run on the ARM Cortex + architecture, is a primary function for amp-devcontainer. It enables building firmware for + micro-controllers based on the ARM Cortex architecture." + } + # @sbdl-end + + Rule: Compile for Microsoft® Windows operating system + # @sbdl-begin + req-comp-0003 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *SHOULD* be able to compile valid source-code into a working executable + targeting the Microsoft® Windows operating system." + remark is + "Compiling valid source-code into working executables, able to run on the Microsoft® Windows + operating system, can be necessary in several scenarios e.g.\n\n + + - Cross platform code is written and needs to be compiled and deployed\n + - Executables need to be deployed outside of container context to a host running the + Microsoft® Windows operating system" + } + # @sbdl-end + + Rule: Compilation cache + # @sbdl-begin + req-comp-0004 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *MAY* be able to cache the results of a compilation to speed-up subsequent + compilations." + remark is + "Maintaining a compilation cache can be useful in both local and ci development scenarios. + A compilation cache can provide benefits like:\n\n + + - Reduce developer waiting time and context switches, + [maintaining flow-state](https://azure.microsoft.com/en-us/blog/quantifying-the-impact-of-developer-experience/)\n + - Reduce CPU usage at the cost of more storage usage, potentially reducing energy + consumption and cost for metered ci-systems" + } + # @sbdl-end diff --git a/docs/requirements/static-dynamic-analysis.feature b/docs/requirements/static-dynamic-analysis.feature new file mode 100644 index 00000000..44428890 --- /dev/null +++ b/docs/requirements/static-dynamic-analysis.feature @@ -0,0 +1,98 @@ +Feature: Static and dynamic analysis + # @sbdl-begin + static-and-dynamic-analysis is aspect { + custom:title is "[@-LINE]" + description is + "As a software craftsperson, + to maintain consistent, high-quality and bug-free code, + I want my source code to be statically and dynamically analyzed." + } + + using { aspect is static-and-dynamic-analysis } + # @sbdl-end + + Rule: Code formatting + # @sbdl-begin + req-sda-0001 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *MAY* provide code formatting tools for the primary programming language(s) + used within the container." + remark is + "Providing code formatting tools helps maintain a consistent coding style across the + codebase, improving readability and reducing friction during code reviews. It also helps + catch potential issues early by enforcing coding standards and best practices. By + integrating code formatting tools into the development environment, developers can easily + format their code according to predefined rules, ensuring that the code adheres to the + project's style guidelines." + } + # @sbdl-end + + Rule: Static analysis + # @sbdl-begin + req-sda-0002 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *MAY* provide static analysis tools for the primary programming language(s) + used within the container." + remark is + "Providing static analysis tools helps identify potential issues in the code before it is + executed, improving code quality and reducing the likelihood of runtime errors. These tools + can analyze the code for common pitfalls, coding standards violations, and potential bugs, + providing developers with valuable feedback early in the development process. By integrating + static analysis tools into the development environment, developers can catch issues before + they become more significant problems, streamlining the development workflow and improving + overall code quality." + } + # @sbdl-end + + Rule: Coverage analysis + # @sbdl-begin + req-sda-0003 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *SHOULD* provide code coverage analysis tools for the primary programming + language(s) used within the container." + remark is + "Providing code coverage analysis tools helps assess the effectiveness of the existing test + suite by measuring how much of the code is exercised by the tests. This information can + help identify gaps in test coverage, ensuring that critical parts of the code are + adequately tested. By integrating code coverage analysis tools into the development + environment, developers can improve their test suites, leading to higher code quality and + increased confidence in the software's correctness." + } + # @sbdl-end + + Rule: Mutation testing + # @sbdl-begin + req-sda-0004 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *MAY* provide mutation testing tools for the primary programming + language(s) used within the container." + remark is + "Providing mutation testing tools helps assess the effectiveness of the existing test suite + by introducing small changes (mutations) to the code and checking if the tests can detect + these changes. This process helps identify gaps in test coverage and ensures that the tests + are robust enough to catch potential issues in the code. By integrating mutation testing + tools into the development environment, developers can improve their test suites, leading + to higher code quality and increased confidence in the software's correctness." + } + # @sbdl-end + + Rule: Fuzz testing + # @sbdl-begin + req-sda-0005 is requirement { + custom:title is "[@-LINE]" + description is + "amp-devcontainer *MAY* provide fuzz testing tools for the primary programming language(s) + used within the container." + remark is + "Providing fuzz testing tools helps identify potential security vulnerabilities and + robustness issues in the code by automatically generating and executing a large number of + random inputs. This process can uncover edge cases and unexpected behaviors that may not be + covered by traditional testing methods. By integrating fuzz testing tools into the + development environment, developers can improve the overall security and reliability of + their software, reducing the risk of vulnerabilities being exploited in production." + } + # @sbdl-end diff --git a/test/cpp/features/compilation.feature b/test/cpp/features/compilation.feature index ed3053ad..76e0e54e 100644 --- a/test/cpp/features/compilation.feature +++ b/test/cpp/features/compilation.feature @@ -1,72 +1,9 @@ Feature: Compilation - # @sbdl-begin - compilation is aspect { - custom:title is "[@-LINE]" - description is - "As a software developer, - to generate a working product, when using compiled languages, - source code needs to be compiled into working software." - } - - using { aspect is compilation } - # @sbdl-end Rule: Compile for container host architecture and operating system - # @sbdl-begin - req-comp-0001 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *SHALL* be able to compile valid source code into a - working executable targeting the container host architecture and operating system." - remark is - "Compiling valid source code into working software, able to run on the container host - architecture and operating system, can be necessary in several scenarios; for example when:\n\n - - - the container host is the deployment target\n - - running tests on the container host\n - - building plug-ins, extensions, code generators, or other additional tools that need to - run on the container host" - } - # @sbdl-end - @flavor:cpp Scenario: Compile valid source code into working software targeting the container host architecture Given build configuration "gcc" is selected And build preset "gcc" is selected When the selected target is built Then the output should contain "Build finished with exit code 0" - - Rule: Compile for Microsoft® Windows operating system - # @sbdl-begin - req-comp-0003 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *SHOULD* be able to compile valid source-code into a working executable - targeting the Microsoft® Windows operating system." - remark is - "Compiling valid source-code into working executables, able to run on the Microsoft® Windows - operating system, can be necessary in several scenarios e.g.\n\n - - - Cross platform code is written and needs to be compiled and deployed\n - - Executables need to be deployed outside of container context to a host running the - Microsoft® Windows operating system" - } - # @sbdl-end - - Rule: Compilation cache - # @sbdl-begin - req-comp-0004 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *MAY* be able to cache the results of a compilation to speed-up subsequent - compilations." - remark is - "Maintaining a compilation cache can be useful in both local and ci development scenarios. - A compilation cache can provide benefits like:\n\n - - - Reduce developer waiting time and context switches, - [maintaining flow-state](https://azure.microsoft.com/en-us/blog/quantifying-the-impact-of-developer-experience/)\n - - Reduce CPU usage at the cost of more storage usage, potentially reducing energy - consumption and cost for metered ci-systems" - } - # @sbdl-end diff --git a/test/cpp/features/static-dynamic-analysis.feature b/test/cpp/features/static-dynamic-analysis.feature index ad083478..be17be6a 100644 --- a/test/cpp/features/static-dynamic-analysis.feature +++ b/test/cpp/features/static-dynamic-analysis.feature @@ -1,105 +1,9 @@ Feature: Static and dynamic analysis - # @sbdl-begin - static-and-dynamic-analysis is aspect { - custom:title is "[@-LINE]" - description is - "As a software craftsperson, - to maintain consistent, high-quality and bug-free code, - I want my source code to be statically and dynamically analyzed." - } - - using { aspect is static-and-dynamic-analysis } - # @sbdl-end Rule: Code formatting - # @sbdl-begin - req-sda-0001 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *MAY* provide code formatting tools for the primary programming language(s) - used within the container." - remark is - "Providing code formatting tools helps maintain a consistent coding style across the - codebase, improving readability and reducing friction during code reviews. It also helps - catch potential issues early by enforcing coding standards and best practices. By - integrating code formatting tools into the development environment, developers can easily - format their code according to predefined rules, ensuring that the code adheres to the - project's style guidelines." - } - # @sbdl-end - - @flavor:cpp @fixme - Scenario: Format source code according to a formatting style - Given the file "clang-tools/unformatted.cpp" is opened in the editor - When the active document is formatted - And the active document is saved - Then the contents of "clang-tools/unformatted.cpp" should match the contents of "clang-tools/formatted.cpp" - - Rule: Static analysis - # @sbdl-begin - req-sda-0002 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *MAY* provide static analysis tools for the primary programming language(s) - used within the container." - remark is - "Providing static analysis tools helps identify potential issues in the code before it is - executed, improving code quality and reducing the likelihood of runtime errors. These tools - can analyze the code for common pitfalls, coding standards violations, and potential bugs, - providing developers with valuable feedback early in the development process. By integrating - static analysis tools into the development environment, developers can catch issues before - they become more significant problems, streamlining the development workflow and improving - overall code quality." - } - # @sbdl-end - - Rule: Coverage analysis - # @sbdl-begin - req-sda-0003 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *SHOULD* provide code coverage analysis tools for the primary programming - language(s) used within the container." - remark is - "Providing code coverage analysis tools helps assess the effectiveness of the existing test - suite by measuring how much of the code is exercised by the tests. This information can - help identify gaps in test coverage, ensuring that critical parts of the code are - adequately tested. By integrating code coverage analysis tools into the development - environment, developers can improve their test suites, leading to higher code quality and - increased confidence in the software's correctness." - } - # @sbdl-end - - Rule: Mutation testing - # @sbdl-begin - req-sda-0004 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *MAY* provide mutation testing tools for the primary programming - language(s) used within the container." - remark is - "Providing mutation testing tools helps assess the effectiveness of the existing test suite - by introducing small changes (mutations) to the code and checking if the tests can detect - these changes. This process helps identify gaps in test coverage and ensures that the tests - are robust enough to catch potential issues in the code. By integrating mutation testing - tools into the development environment, developers can improve their test suites, leading - to higher code quality and increased confidence in the software's correctness." - } - # @sbdl-end - - Rule: Fuzz testing - # @sbdl-begin - req-sda-0005 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *MAY* provide fuzz testing tools for the primary programming language(s) - used within the container." - remark is - "Providing fuzz testing tools helps identify potential security vulnerabilities and - robustness issues in the code by automatically generating and executing a large number of - random inputs. This process can uncover edge cases and unexpected behaviors that may not be - covered by traditional testing methods. By integrating fuzz testing tools into the - development environment, developers can improve the overall security and reliability of - their software, reducing the risk of vulnerabilities being exploited in production." - } - # @sbdl-end + @flavor:cpp @fixme + Scenario: Format source code according to a formatting style + Given the file "clang-tools/unformatted.cpp" is opened in the editor + When the active document is formatted + And the active document is saved + Then the contents of "clang-tools/unformatted.cpp" should match the contents of "clang-tools/formatted.cpp" diff --git a/test/embedded-cpp/features/compilation.feature b/test/embedded-cpp/features/compilation.feature deleted file mode 100644 index 041a4588..00000000 --- a/test/embedded-cpp/features/compilation.feature +++ /dev/null @@ -1,18 +0,0 @@ -Feature: Compilation - # @sbdl-begin - using { aspect is compilation } - # @sbdl-end - - Rule: Compile for ARM Cortex target architecture - # @sbdl-begin - req-comp-0002 is requirement { - custom:title is "[@-LINE]" - description is - "amp-devcontainer *SHOULD* be able to compile valid source-code into a working ELF - executable targeting the ARM Cortex architecture." - remark is - "Compiling valid source-code into working ELF executables, able to run on the ARM Cortex - architecture, is a primary function for amp-devcontainer. It enables building firmware for - micro-controllers based on the ARM Cortex architecture." - } - # @sbdl-end From 8f0e6b98844709835fddff1aba672d2b6f332c10 Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:03:40 +0000 Subject: [PATCH 12/14] docs: co-locate flavor scenarios with requirements Keep flavor-tagged Gherkin scenarios alongside their requirement declarations and filter acceptance test generation using the target flavor tag. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/build-push-test.yml | 1 + .github/workflows/wc-acceptance-test.yml | 18 +++++++++++++++--- .github/workflows/wc-build-push-test.yml | 5 +++++ docs/adr/0000-record-architecture-decisions.md | 2 +- docs/requirements/compilation.feature | 7 +++++++ .../static-dynamic-analysis.feature | 7 +++++++ test/cpp/features/compilation.feature | 9 --------- test/cpp/features/playwright.config.ts | 4 +++- .../features/static-dynamic-analysis.feature | 9 --------- 9 files changed, 39 insertions(+), 23 deletions(-) delete mode 100644 test/cpp/features/compilation.feature delete mode 100644 test/cpp/features/static-dynamic-analysis.feature diff --git a/.github/workflows/build-push-test.yml b/.github/workflows/build-push-test.yml index 9bbb314d..0889323a 100644 --- a/.github/workflows/build-push-test.yml +++ b/.github/workflows/build-push-test.yml @@ -63,6 +63,7 @@ jobs: permissions: *build-push-test-permissions with: acceptance-test-path: ${{ (github.actor != 'dependabot[bot]' && matrix.flavor == 'cpp') && 'test/cpp/features' || '' }} + acceptance-test-tag: '@flavor:${{ matrix.flavor }}' acceptance-test-devcontainer-file: .devcontainer/${{ matrix.flavor }}-test/devcontainer.json base-image: ${{ needs.build-push-test-base.outputs.fully-qualified-image-name }}@${{ needs.build-push-test-base.outputs.digest }} build-args: | diff --git a/.github/workflows/wc-acceptance-test.yml b/.github/workflows/wc-acceptance-test.yml index 4df3cdef..4bddb3a2 100644 --- a/.github/workflows/wc-acceptance-test.yml +++ b/.github/workflows/wc-acceptance-test.yml @@ -4,13 +4,16 @@ name: Acceptance Test on: workflow_call: inputs: - image-basename: + acceptance-test-path: + required: true + type: string + acceptance-test-tag: required: true type: string devcontainer-file: required: true type: string - acceptance-test-path: + image-basename: required: true type: string secrets: @@ -94,9 +97,18 @@ jobs: done env: GH_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} - - run: cd "${ACCEPTANCE_TEST_PATH}" && npm test + - name: Run matching acceptance scenarios + run: | + set -Eeuo pipefail + if [[ -z "${ACCEPTANCE_TEST_TAG}" ]]; then + echo "ACCEPTANCE_TEST_TAG must identify the target flavor." >&2 + exit 1 + fi + cd "${ACCEPTANCE_TEST_PATH}" + npm test env: ACCEPTANCE_TEST_PATH: ${{ inputs.acceptance-test-path }} + ACCEPTANCE_TEST_TAG: ${{ inputs.acceptance-test-tag }} GITHUB_USER: ${{ secrets.TEST_GITHUB_USER }} GITHUB_PASSWORD: ${{ secrets.TEST_GITHUB_PASSWORD }} GITHUB_TOTP_SECRET: ${{ secrets.TEST_GITHUB_TOTP_SECRET }} diff --git a/.github/workflows/wc-build-push-test.yml b/.github/workflows/wc-build-push-test.yml index 4438312c..e0fc98de 100644 --- a/.github/workflows/wc-build-push-test.yml +++ b/.github/workflows/wc-build-push-test.yml @@ -12,6 +12,10 @@ on: description: Path to the Playwright acceptance tests (directory that contains playwright.config.ts). required: false type: string + acceptance-test-tag: + description: Playwright-BDD tag expression used to select acceptance scenarios. + required: false + type: string base-image: description: >- Reference of the image this build is based on (the image the Dockerfile builds FROM). @@ -197,3 +201,4 @@ jobs: image-basename: ${{ needs.build-push.outputs.image-basename }} devcontainer-file: ${{ inputs.acceptance-test-devcontainer-file }} acceptance-test-path: ${{ inputs.acceptance-test-path }} + acceptance-test-tag: ${{ inputs.acceptance-test-tag }} diff --git a/docs/adr/0000-record-architecture-decisions.md b/docs/adr/0000-record-architecture-decisions.md index d07c1792..2bf390a9 100644 --- a/docs/adr/0000-record-architecture-decisions.md +++ b/docs/adr/0000-record-architecture-decisions.md @@ -8,7 +8,7 @@ The project makes architectural, process, and supply-chain decisions — such as how packages are pinned or how the threat model is expressed — whose rationale is easily lost over time. Commit messages and pull-request discussions are hard to discover after the fact, yet new contributors and auditors need to understand *why* a decision was made, not only *what* the code does. -The container's own maintainability requirement states that amp-devcontainer *SHOULD* document its architectural decisions (see [test/cpp/features/maintainability.feature](../../test/cpp/features/maintainability.feature)). The project therefore needs a lightweight, durable, and discoverable way to capture significant decisions together with their context and consequences. +The container's own maintainability requirement states that amp-devcontainer *SHOULD* document its architectural decisions (see [req-maint-0004](../requirements/maintainability.feature)). The project therefore needs a lightweight, durable, and discoverable way to capture significant decisions together with their context and consequences. ## Decision Drivers diff --git a/docs/requirements/compilation.feature b/docs/requirements/compilation.feature index 9d58a247..84f3a6df 100644 --- a/docs/requirements/compilation.feature +++ b/docs/requirements/compilation.feature @@ -43,6 +43,13 @@ Feature: Compilation } # @sbdl-end + @flavor:cpp + Scenario: Compile valid source code into working software targeting the container host architecture + Given build configuration "gcc" is selected + And build preset "gcc" is selected + When the selected target is built + Then the output should contain "Build finished with exit code 0" + Rule: Compile for Microsoft® Windows operating system # @sbdl-begin req-comp-0003 is requirement { diff --git a/docs/requirements/static-dynamic-analysis.feature b/docs/requirements/static-dynamic-analysis.feature index 44428890..ad083478 100644 --- a/docs/requirements/static-dynamic-analysis.feature +++ b/docs/requirements/static-dynamic-analysis.feature @@ -28,6 +28,13 @@ Feature: Static and dynamic analysis } # @sbdl-end + @flavor:cpp @fixme + Scenario: Format source code according to a formatting style + Given the file "clang-tools/unformatted.cpp" is opened in the editor + When the active document is formatted + And the active document is saved + Then the contents of "clang-tools/unformatted.cpp" should match the contents of "clang-tools/formatted.cpp" + Rule: Static analysis # @sbdl-begin req-sda-0002 is requirement { diff --git a/test/cpp/features/compilation.feature b/test/cpp/features/compilation.feature deleted file mode 100644 index 76e0e54e..00000000 --- a/test/cpp/features/compilation.feature +++ /dev/null @@ -1,9 +0,0 @@ -Feature: Compilation - - Rule: Compile for container host architecture and operating system - @flavor:cpp - Scenario: Compile valid source code into working software targeting the container host architecture - Given build configuration "gcc" is selected - And build preset "gcc" is selected - When the selected target is built - Then the output should contain "Build finished with exit code 0" diff --git a/test/cpp/features/playwright.config.ts b/test/cpp/features/playwright.config.ts index 011d8cb5..afde4e18 100644 --- a/test/cpp/features/playwright.config.ts +++ b/test/cpp/features/playwright.config.ts @@ -7,8 +7,10 @@ require('dotenv').config({ path: path.join(__dirname, '..', '..', '..', '.env') export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json'); const testDir = defineBddConfig({ - features: "*.feature", + featuresRoot: path.resolve(__dirname, "../../../docs/requirements"), + features: path.join(__dirname, "../../../docs/requirements/*.feature"), steps: ["steps/*.ts"], + tags: process.env.ACCEPTANCE_TEST_TAG, }); export default defineConfig({ diff --git a/test/cpp/features/static-dynamic-analysis.feature b/test/cpp/features/static-dynamic-analysis.feature deleted file mode 100644 index be17be6a..00000000 --- a/test/cpp/features/static-dynamic-analysis.feature +++ /dev/null @@ -1,9 +0,0 @@ -Feature: Static and dynamic analysis - - Rule: Code formatting - @flavor:cpp @fixme - Scenario: Format source code according to a formatting style - Given the file "clang-tools/unformatted.cpp" is opened in the editor - When the active document is formatted - And the active document is saved - Then the contents of "clang-tools/unformatted.cpp" should match the contents of "clang-tools/formatted.cpp" From ae6032e9fab09131791c36f8fb865d2fa8d8035e Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:30:47 +0000 Subject: [PATCH 13/14] test: watch shared requirements during BDD generation Update the BDD watcher to monitor docs/requirements and the actual Playwright harness paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85051f78..e66ef3c4 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ }, "scripts": { "test": "cd $INIT_CWD && npx bddgen && npx playwright test", - "watch:bdd-gen": "cd $INIT_CWD && nodemon -L -w features -w steps -w pages -e feature,ts -x 'npx bddgen'", + "watch:bdd-gen": "cd $INIT_CWD && nodemon -L -w ../../../docs/requirements -w steps -w pages -w playwright.config.ts -e feature,ts -x 'npx bddgen'", "watch:playwright": "cd $INIT_CWD && playwright test --ui", "watch": "cd $INIT_CWD && npm run watch:bdd-gen & npm run watch:playwright" } From 23bd4e7ac79f382056491d9645d5794c6b5ae4ea Mon Sep 17 00:00:00 2001 From: Ron <45816308+rjaegers@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:42:43 +0000 Subject: [PATCH 14/14] docs: move test under the correct rule --- docs/requirements/compilation.feature | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/requirements/compilation.feature b/docs/requirements/compilation.feature index 84f3a6df..352c1381 100644 --- a/docs/requirements/compilation.feature +++ b/docs/requirements/compilation.feature @@ -29,6 +29,13 @@ Feature: Compilation } # @sbdl-end + @flavor:cpp + Scenario: Compile valid source code into working software targeting the container host architecture + Given build configuration "gcc" is selected + And build preset "gcc" is selected + When the selected target is built + Then the output should contain "Build finished with exit code 0" + Rule: Compile for ARM Cortex target architecture # @sbdl-begin req-comp-0002 is requirement { @@ -43,13 +50,6 @@ Feature: Compilation } # @sbdl-end - @flavor:cpp - Scenario: Compile valid source code into working software targeting the container host architecture - Given build configuration "gcc" is selected - And build preset "gcc" is selected - When the selected target is built - Then the output should contain "Build finished with exit code 0" - Rule: Compile for Microsoft® Windows operating system # @sbdl-begin req-comp-0003 is requirement {