diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml
index ae13e2b..e6d6103 100644
--- a/.github/workflows/deploy-pages.yml
+++ b/.github/workflows/deploy-pages.yml
@@ -25,149 +25,10 @@ concurrency:
jobs:
docs-deploy:
- name: Deploy documentation to GitHub Pages
if: github.event.workflow_run.conclusion == 'success'
+ uses: eclipse-score/cicd-workflows/.github/workflows/docs-publish.yml@dev
permissions:
- actions: read
pages: write
id-token: write
contents: write
pull-requests: write
- runs-on: ubuntu-latest
- steps:
- - name: Download build metadata
- uses: actions/download-artifact@v8.0.1
- with:
- name: build-metadata
- run-id: ${{ github.event.workflow_run.id }}
- github-token: ${{ github.token }}
-
- - name: Parse build metadata
- id: metadata
- run: |
- EVENT_NAME=$(jq -r '.event_name' build-info.json)
- PR_NUMBER=$(jq -r '.pr_number // empty' build-info.json)
- REF_NAME=$(jq -r '.ref_name' build-info.json)
-
- case "$EVENT_NAME" in
- pull_request|push|merge_group|release) ;;
- *)
- echo "::error::Unexpected event_name: $EVENT_NAME"
- exit 1
- ;;
- esac
-
- if [[ -n "$PR_NUMBER" && ! "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
- echo "::error::Invalid pr_number: $PR_NUMBER"
- exit 1
- fi
-
- if [[ ! "$REF_NAME" =~ ^[a-zA-Z0-9._/-]+$ ]]; then
- echo "::error::Invalid ref_name: $REF_NAME"
- exit 1
- fi
-
- if [[ "$EVENT_NAME" == "merge_group" ]]; then
- echo "should_deploy=false" >> "$GITHUB_OUTPUT"
- else
- echo "should_deploy=true" >> "$GITHUB_OUTPUT"
- fi
-
- echo "event_name=$EVENT_NAME" >> "$GITHUB_OUTPUT"
- echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
- echo "ref_name=$REF_NAME" >> "$GITHUB_OUTPUT"
-
- - name: Determine target folder
- if: steps.metadata.outputs.should_deploy == 'true'
- id: target
- run: |
- EVENT_NAME="${{ steps.metadata.outputs.event_name }}"
- if [[ "$EVENT_NAME" == "pull_request" ]]; then
- echo "folder=pr-${{ steps.metadata.outputs.pr_number }}" >> "$GITHUB_OUTPUT"
- else
- echo "folder=${{ steps.metadata.outputs.ref_name }}" >> "$GITHUB_OUTPUT"
- fi
-
- - name: Checkout gh-pages
- if: steps.metadata.outputs.should_deploy == 'true'
- uses: actions/checkout@v6
- with:
- ref: gh-pages
- path: gh-pages-content
-
- - name: Clean up old documentation
- if: steps.metadata.outputs.should_deploy == 'true'
- run: |
- rm -rf "gh-pages-content/${{ steps.target.outputs.folder }}"
-
- - name: Download documentation artifact
- uses: actions/download-artifact@v8.0.1
- with:
- name: github-pages
- run-id: ${{ github.event.workflow_run.id }}
- github-token: ${{ github.token }}
- path: gh-pages-content/${{ steps.target.outputs.folder }}
-
- - name: Ensure .nojekyll exists
- if: steps.metadata.outputs.should_deploy == 'true'
- run: touch gh-pages-content/.nojekyll
-
- - name: Extend versions.json
- if: steps.metadata.outputs.should_deploy == 'true'
- run: |
- TARGET="${{ steps.target.outputs.folder }}"
-
- # if versions.json does not exist, create it with an empty array as content
- if [ ! -f gh-pages-content/versions.json ]; then
- echo '[]' > gh-pages-content/versions.json
- fi
-
- # Add new version entry to versions.json if it doesn't already exist
- if jq -e --arg v "$TARGET" 'map(select(.version == $v)) | length > 0' gh-pages-content/versions.json > /dev/null; then
- echo "Version '$TARGET' already exists in versions.json"
- else
- REPO_NAME=$(basename "${{ github.repository }}")
- OWNER_NAME="${{ github.repository_owner }}"
- PAGES_URL="https://${OWNER_NAME}.github.io/${REPO_NAME}"
- jq --arg v "$TARGET" --arg u "${PAGES_URL}/${TARGET}/" \
- '. + [{"version": $v, "url": $u}]' gh-pages-content/versions.json > gh-pages-content/tmp.json && mv gh-pages-content/tmp.json gh-pages-content/versions.json
- fi
-
- - name: Commit and push changes to gh-pages
- if: steps.metadata.outputs.should_deploy == 'true'
- run: |
- cd gh-pages-content
- git config user.name "github-actions[bot]"
- git config user.email "github-actions[bot]@users.noreply.github.com"
- git add .
- git commit -m "Update documentation for ${{ steps.target.outputs.folder }}" || echo "No changes to commit"
- git push
-
- - name: Create artifact from gh-pages
- if: steps.metadata.outputs.should_deploy == 'true'
- uses: actions/upload-pages-artifact@v3
- with:
- path: gh-pages-content
-
- - name: Deploy artifact to GitHub Pages
- if: steps.metadata.outputs.should_deploy == 'true'
- id: deploy-pages
- uses: actions/deploy-pages@v4
-
- - name: Find existing PR comment
- if: steps.metadata.outputs.should_deploy == 'true' && steps.metadata.outputs.event_name == 'pull_request' && steps.metadata.outputs.pr_number != ''
- uses: peter-evans/find-comment@v3
- id: fc
- with:
- issue-number: ${{ steps.metadata.outputs.pr_number }}
- comment-author: 'github-actions[bot]'
- body-includes: Documentation preview for this pull request
-
- - name: Comment on PR with preview link
- if: steps.metadata.outputs.should_deploy == 'true' && steps.metadata.outputs.event_name == 'pull_request' && steps.metadata.outputs.pr_number != '' && steps.fc.outputs.comment-id == ''
- uses: peter-evans/create-or-update-comment@v4
- with:
- issue-number: ${{ steps.metadata.outputs.pr_number }}
- body: |
- Documentation preview for this pull request is available at:
- **${{ steps.target.outputs.folder }}**: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ steps.target.outputs.folder }}/
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index b38a8e7..879b4dd 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -13,56 +13,21 @@
name: PR
-permissions:
- contents: read
-
on:
pull_request:
types: [opened, reopened, synchronize]
push:
branches:
- - main # docs are built only on push to main branch, for feature branches there are PR builds
+ - main
merge_group:
types: [checks_requested]
release:
types: [created]
+permissions:
+ contents: read
+
jobs:
docs-build:
name: Build documentation
- runs-on: ubuntu-latest
- steps:
- - uses: eclipse-score/more-disk-space@v1
-
- - name: Check out
- uses: actions/checkout@v6
-
- - name: Build documentation
- run: |
- bazel run //:docs -- --github_user=${{ github.repository_owner }} --github_repo=${{ github.event.repository.name }}
-
- - name: Upload documentation artifact
- uses: actions/upload-artifact@v7.0.1
- with:
- name: github-pages
- path: _build
- retention-days: 1
- if-no-files-found: error
-
- - name: Create build metadata
- run: |
- cat > build-info.json <<'EOF'
- {
- "event_name": "${{ github.event_name }}",
- "pr_number": "${{ github.event.pull_request.number }}",
- "ref_name": "${{ github.ref_name }}",
- "head_sha": "${{ github.sha }}"
- }
- EOF
-
- - name: Upload build metadata
- uses: actions/upload-artifact@v7.0.1
- with:
- name: build-metadata
- path: build-info.json
- retention-days: 1
+ uses: eclipse-score/cicd-workflows/.github/workflows/docs.yml@dev
diff --git a/.gitignore b/.gitignore
index b18772e..e2c2324 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,10 @@ bazel-*
/_build*
docs/ubproject.toml
+# Python
+__pycache__/
+.ruff_cache/
+
# AI
/.claude
/.codex
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..bbf7386
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,28 @@
+repos:
+ - repo: local
+ hooks:
+ - id: aggregate-status
+ name: Aggregate chapter statuses
+ entry: python3 scripts/aggregate_status.py
+ language: system
+ pass_filenames: false
+ files: ^(docs/explanation/.*\.md|scripts/aggregate_status\.py)$
+ exclude: ^docs/explanation/index\.md$
+ - id: generate-mindmap
+ name: Generate infrastructure chapter map
+ entry: python3 scripts/generate_mindmap.py
+ language: system
+ pass_filenames: false
+ files: ^(docs/explanation/[0-9][0-9]-.*\.md|docs/explanation/index\.md|scripts/generate_mindmap\.py)$
+ - id: ruff-check
+ name: ruff-check
+ entry: scripts/run_tool.sh ruff check --fix
+ language: system
+ require_serial: true
+ types: [python]
+ - id: ruff-format
+ name: ruff-format
+ entry: scripts/run_tool.sh ruff format
+ language: system
+ require_serial: true
+ types: [python]
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..e683602
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,101 @@
+@CONTRIBUTING.md
+
+# Repository
+
+S-CORE infrastructure documentation site. Published at
/gi, " ")
+ .replace(/&/gi, " and ")
+ .replace(/[^0-9a-z]+/g, "");
+ }
+
+ function hasNodeShape(group) {
+ return Boolean(group.querySelector("rect, circle, ellipse, polygon, path"));
+ }
+
+ function candidateGroups(svg, wantedText) {
+ const wanted = canonicalText(wantedText);
+ if (!wanted) {
+ return [];
+ }
+
+ const matches = new Set();
+ for (const element of svg.querySelectorAll("*")) {
+ if (canonicalText(element.textContent) !== wanted) {
+ continue;
+ }
+
+ let current = element;
+ while (current && current !== svg) {
+ if (current.tagName && current.tagName.toLowerCase() === "g" && hasNodeShape(current)) {
+ matches.add(current);
+ break;
+ }
+ current = current.parentElement;
+ }
+ }
+
+ return Array.from(matches).sort(
+ (left, right) => left.querySelectorAll("*").length - right.querySelectorAll("*").length
+ );
+ }
+
+ function bindLink(group, link) {
+ if (group.dataset.chapterMapHref === link.href) {
+ return;
+ }
+
+ group.dataset.chapterMapHref = link.href;
+ group.dataset.chapterMapKind = link.kind || "section";
+ group.classList.add("chapter-map-node-link", `chapter-map-node-${group.dataset.chapterMapKind}`);
+ group.setAttribute("role", "link");
+ group.setAttribute("tabindex", "0");
+
+ const open = function () {
+ window.location.assign(link.href);
+ };
+
+ group.addEventListener("click", function (event) {
+ event.preventDefault();
+ open();
+ });
+
+ group.addEventListener("keydown", function (event) {
+ if (event.key !== "Enter" && event.key !== " ") {
+ return;
+ }
+ event.preventDefault();
+ open();
+ });
+ }
+
+ function enhanceDiagram(diagram, links) {
+ const svg = diagram.querySelector("svg");
+ if (!svg) {
+ return false;
+ }
+
+ let boundCount = 0;
+ for (const link of links) {
+ const texts = Array.isArray(link.match_texts) ? link.match_texts : [link.title];
+ let target = null;
+
+ for (const text of texts) {
+ const candidates = candidateGroups(svg, text);
+ if (candidates.length > 0) {
+ target = candidates[0];
+ break;
+ }
+ }
+
+ if (!target) {
+ continue;
+ }
+
+ bindLink(target, link);
+ boundCount += 1;
+ }
+
+ diagram.classList.toggle("chapter-map-enhanced", boundCount > 0);
+ return boundCount > 0;
+ }
+
+ function diagramForScript(script) {
+ let current = script.previousElementSibling;
+ while (current) {
+ if (current.classList && current.classList.contains("mermaid")) {
+ return current;
+ }
+ current = current.previousElementSibling;
+ }
+ return null;
+ }
+
+ function waitForSvg(diagram, callback) {
+ const existing = diagram.querySelector("svg");
+ if (existing) {
+ callback();
+ return;
+ }
+
+ const observer = new MutationObserver(function () {
+ if (!diagram.querySelector("svg")) {
+ return;
+ }
+ observer.disconnect();
+ callback();
+ });
+
+ observer.observe(diagram, { childList: true, subtree: true });
+ }
+
+ function scheduleRetry() {
+ window.setTimeout(initializeMindmaps, 250);
+ window.setTimeout(initializeMindmaps, 1000);
+ }
+
+ function initializeMindmaps() {
+ for (const script of document.querySelectorAll(".chapter-map-links-data")) {
+ if (script.dataset.chapterMapInitialized === "true") {
+ continue;
+ }
+
+ const diagram = diagramForScript(script);
+ if (!diagram) {
+ continue;
+ }
+
+ let links;
+ try {
+ links = JSON.parse(script.textContent || "[]");
+ } catch (_error) {
+ continue;
+ }
+
+ if (diagram.querySelector("svg")) {
+ if (enhanceDiagram(diagram, links)) {
+ script.dataset.chapterMapInitialized = "true";
+ } else {
+ scheduleRetry();
+ }
+ continue;
+ }
+
+ if (script.dataset.chapterMapWaiting === "true") {
+ continue;
+ }
+
+ script.dataset.chapterMapWaiting = "true";
+ waitForSvg(diagram, function () {
+ script.dataset.chapterMapWaiting = "false";
+ if (enhanceDiagram(diagram, links)) {
+ script.dataset.chapterMapInitialized = "true";
+ } else {
+ scheduleRetry();
+ }
+ });
+ }
+ }
+
+ if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", initializeMindmaps);
+ } else {
+ initializeMindmaps();
+ }
+
+ window.addEventListener("load", initializeMindmaps);
+ window.setTimeout(initializeMindmaps, 250);
+ window.setTimeout(initializeMindmaps, 1000);
+})();
diff --git a/docs/conf.py b/docs/conf.py
index c428eb9..54deb67 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -15,6 +15,8 @@
project_url = "https://eclipse-score.github.io/infrastructure"
version = "0.1"
-extensions = [
- "score_sphinx_bundle",
-]
+extensions = ["score_sphinx_bundle"]
+
+html_static_path = ["_static"]
+html_css_files = ["css/custom.css"]
+html_js_files = ["js/mindmap.js"]
diff --git a/docs/explanation/01-source-code-infrastructure.md b/docs/explanation/01-source-code-infrastructure.md
new file mode 100644
index 0000000..eed20e9
--- /dev/null
+++ b/docs/explanation/01-source-code-infrastructure.md
@@ -0,0 +1,123 @@
+# 1 Source Code Infrastructure 🟠
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure for hosting and governing repositories consistently across the S-CORE project.*
+
+```{mermaid}
+graph TD
+ eclipsefdn["`.eclipsefdn`\notterdog config"]
+ otterdog["otterdog"]
+ github_org["eclipse-score\nGitHub organization"]
+ repos["Module repositories"]
+ template["`eclipse-score/module_template`"]
+ github_profile["`.github`\norg profile & conformance"]
+
+ eclipsefdn -->|defines org policy| otterdog
+ otterdog -->|applies: branch protection,\nrequired checks, Actions allowlist| github_org
+ github_org -->|hosts| repos
+ template -->|bootstraps new| repos
+ github_profile -.->|discovery surface| github_org
+```
+
+## 1.1 Hosting & Organization ⚪
+
+*Provide a stable, discoverable, and scalable hosting foundation for all S-CORE repositories.*
+
+All S-CORE repositories are hosted on GitHub at [github.com/eclipse-score](https://github.com/eclipse-score), aligned with Eclipse Foundation governance. A shared organization enables organization-level settings, applications, and automation to be managed centrally. The organization profile page ([eclipse-score/.github](https://github.com/eclipse-score/.github)) serves as a discovery surface that links to shared repository inventories, standards, and cross-project guidance.
+
+Discoverability depends not only on hosting location but on repository naming, metadata, topics, and consistent descriptions. Without a shared standard, repositories drift in how they present themselves, which increases onboarding friction as the repository landscape grows.
+
+**Biggest gap**: there is no shared discoverability standard for how S-CORE repositories should present themselves in GitHub.
+
+
+## 1.2 Repository Provisioning & Lifecycle 🟡
+
+*Infrastructure for creating, initializing, updating, and archiving repositories and executing lifecycle operations.*
+
+**S-CORE**
+
+Repository provisioning in S-CORE starts with creating the repository itself and attaching it to the shared organizational governance model. The infrastructure concern here is the durable repository state around creation, ownership, protection, archival, and other lifecycle transitions, not the detailed engineering baseline inside the repository.
+
+Organization-level repository state is still managed centrally. Desired settings such as applications, branch protection, and required checks are defined through the infrastructure-as-code tool [otterdog](https://otterdog.readthedocs.io/en/latest/userguide/) in the [S-CORE configuration file](https://github.com/eclipse-score/.eclipsefdn/blob/main/otterdog/eclipse-score.jsonnet), and lifecycle transitions are configuration changes instead of one-off admin actions.
+
+**Biggest gap**: ownership and approval of repository lifecycle changes are still not clearly defined end to end.
+
+---
+
+## 1.3 Repository Policy Management 🔴
+
+*Infrastructure for managing and synchronizing repository policies such as branch protection, and application thereof at scale.*
+
+**S-CORE**
+
+Repository policy covers the organization-level settings that govern how repositories behave: branch protection rules, required status checks, merge strategies, and which GitHub Actions are allowed to run. The infrastructure concern is not each individual rule but the system that makes policy intent explicit, reviewable, and enforceable at scale rather than hidden in per-repository admin pages.
+
+In S-CORE, policy intent is expressed centrally via the infrastructure-as-code tool [otterdog](https://otterdog.readthedocs.io/en/latest/userguide/) in the [S-CORE configuration file](https://github.com/eclipse-score/.eclipsefdn/blob/main/otterdog/eclipse-score.jsonnet). That makes policy changes reviewable as pull requests and exceptions explicit rather than silent. The same mechanism can restrict which GitHub Actions are allowed to run in the organization — an important supply-chain concern because third-party actions execute with the permissions of the workflow that calls them. An allowlist strategy classifies actions as approved, under review, or blocked, and the enforcement mechanism should prevent unapproved actions from running rather than merely warning about them.
+
+**Biggest gap**: there is no common policy definition or enforcement strategy, and the current state of policy across repositories is not well documented or visible. GitHub Actions allowlisting is not yet implemented or documented as a security baseline.
+---
+
+## 1.4 Repository Standards 🟠
+
+*Define, propagate, and measure standard repository elements to reduce unnecessary variation.*
+
+Standards reduce unnecessary variation across the S-CORE repository landscape. To be effective, they need to be centrally defined, technically synchronized into repositories, and measurably adopted. These three concerns — definition, propagation, and conformance visibility — form a complete system only when they are all in place together.
+
+S-CORE has the beginnings of central standards but has not yet closed the loop to synchronized enforcement and visible conformance. The [module_template](https://github.com/eclipse-score/module_template) provides a bootstrap baseline for new Bazel-module repositories, and shared tooling and policy modules define some common expectations. However, these elements do not yet add up to a coherent cross-repository standardization system with automated rollout and drift detection.
+
+**Biggest gap**: standards, synchronization, and conformance visibility are not yet operationalized as one coherent system.
+
+### 1.4.1 Repository Metadata 🟡
+
+*Define standard project metadata such as LICENSE, README, and governance files.*
+
+**S-CORE**
+
+Metadata expectations exist, but rollout is not yet complete across repositories. Discoverability and governance depend on consistent metadata being present and kept current.
+
+For Bazel modules, [eclipse-score/module_template](https://github.com/eclipse-score/module_template) partially addresses this by giving new repositories a common starting set of metadata and governance files instead of requiring each maintainer to assemble them from scratch. That is useful as a bootstrap baseline, but it only covers repositories that fit the template and it does not by itself keep existing repositories aligned over time.
+
+**Biggest gap**: metadata standards exist only partially in enforceable form, and the current bootstrap support is limited to Bazel-module-style repositories.
+
+### 1.4.2 Tooling Configuration Standards 🟠
+
+*Define shared configuration for linters and development tools.*
+
+**S-CORE**
+
+Shared conventions are starting to emerge, but not yet synchronized.
+
+The same template also gives Bazel modules a partial starter baseline for repository-local tooling configuration, such as the initial Bazel wiring, editor settings, and starter workflow files. That helps new Bazel-based repositories begin from a more consistent shape, but it is still only a bootstrap aid for one repository class rather than a cross-project standardization mechanism.
+
+Repository-local tooling configuration is only one part of the broader repository-standard surface. Cross-repository collection and publication of repository facts, adoption, and drift belong with [conformance reporting](#conformance-reporting), not as a tooling-only concern.
+
+**Biggest gap**: no clearly enforced baseline/override model exists across repository classes, and the current template-based help is limited to Bazel modules.
+
+### 1.4.3 Synchronization Mechanisms 🔴
+
+*Applying shared standards into repositories through repeatable technical mechanisms.*
+
+**S-CORE**
+
+Synchronization can be driven by central configuration, reusable templates, generated repository settings, or other automation rather than manual copying. The infrastructure concern is not a single mandated mechanism, but that shared standards can be propagated predictably, reviewed, and rolled out at scale.
+
+Migration support matters alongside synchronization, because existing repositories will not all converge at the same speed. New-repository templates can help with bootstrap, but they are not the same thing as synchronization once repositories already exist and start to drift.
+
+**Biggest gap**: no alignment on a synchronization mechanism.
+
+### 1.4.4 Conformance Reporting 🔴
+
+*Showing which repositories follow the shared baseline and where drift remains.*
+
+**S-CORE**
+
+- Conformance visibility is necessary if synchronization is meant to be measurable rather than aspirational.
+- Adoption and drift should be tracked so migration work can be prioritized instead of discovered reactively.
+- Cross-repository reporting should make deviations visible early enough to support planned migration rather than reactive cleanup.
+- Cross-repository consistency of standards and related policy expectations is not yet reliably measured.
+- A practical reporting tool should be able to collect structured repository facts such as the Bazel version or module baseline in use, whether central reusable workflows such as `cicd-workflows/daily.yml` are consumed, whether `pre-commit` is configured, and where repositories intentionally diverge from the shared baseline.
+- One suitable delivery model is generated Markdown stored in [eclipse-score/.github](https://github.com/eclipse-score/.github) and linked from the organization start page at [github.com/eclipse-score](https://github.com/eclipse-score/), so the conformance view becomes part of the normal project discovery surface rather than a hidden internal report.
+- **Biggest gap**: no shared conformance dashboard or report currently shows adoption and drift across the repository landscape.
\ No newline at end of file
diff --git a/docs/explanation/02-developer-environment.md b/docs/explanation/02-developer-environment.md
new file mode 100644
index 0000000..6a9a400
--- /dev/null
+++ b/docs/explanation/02-developer-environment.md
@@ -0,0 +1,94 @@
+# 2 Developer Environment 🟡
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure that provides the local development layer across S-CORE repositories.*
+
+```{mermaid}
+graph LR
+ contributor["Contributor\n(VS Code / terminal)"]
+ dc["`ghcr.io/eclipse-score/devcontainer\n(Bazel · Python · pre-commit\nlanguage servers · doc tools)`"]
+ bazel["bazel build / test"]
+ precommit["pre-commit hooks"]
+ ci["`CI runners\n(same image)`"]
+
+ contributor -->|"Reopen in Container"| dc
+ dc --> bazel
+ dc --> precommit
+ bazel --> ci
+ precommit --> ci
+```
+
+S-CORE needs local infrastructure beyond its main software build flows. IDE integration, language servers, formatters, YAML and workflow linters, documentation helpers, and lightweight validation before CI all need a shared home or they drift from repository to repository.
+
+From a contributor's perspective, the developer environment is the entry point to every other infrastructure capability. A new contributor opens a devcontainer, gets a working editor and shell, and from there reaches into the build system ([chapter 3](03-build-infrastructure.md)), runs tests ([chapter 4](04-testing-infrastructure.md)), triggers local analysis ([chapter 5](05-static-analysis-infrastructure.md)), and eventually pushes a change that CI validates ([chapter 7](07-automation-integration.md)). Each of those chapters owns its own deep tooling, but the developer environment is where they all surface as a day-to-day experience. If the environment does not present those capabilities in a discoverable, consistent way, contributors end up reading CI logs to learn what they could have caught locally.
+
+In S-CORE, Bazel is the central build system for the actual software stack, but many repositories do not use Bazel as their primary local execution model. This chapter therefore documents the shared local layer that spans both repository types, centered on the common [eclipse-score/devcontainer](https://github.com/eclipse-score/devcontainer). The central devcontainer gives S-CORE a clear anchor for this area, but the repository-facing conventions around it are not yet fully standardized.
+
+## 2.1 Central Devcontainer 🟠
+
+*Common local environment for shared development tooling across repository types.*
+
+Multi-repository development needs one repeatable local environment for the tools that are not naturally delivered by each repository's own build or test flow. Without that, editor support, formatting, documentation tooling, YAML or workflow linting, and similar surrounding capabilities become repository-specific setup problems instead of shared infrastructure.
+
+S-CORE solves this primarily through the central [eclipse-score/devcontainer](https://github.com/eclipse-score/devcontainer) repository. It builds, tests, and publishes pre-built development-container images, with pinned and preconfigured tools, so repositories can consume one shared local environment instead of maintaining their own setup stacks.
+
+The design decision behind this approach is documented in [DR-003](https://eclipse-score.github.io/score/main/design_decisions/DR-003-infra.html). The key tradeoff is between a single monolithic image that carries all shared tools and a multi-container setup using Docker Compose where each concern (build toolchain, documentation, linting) gets its own image. S-CORE chose the monolithic path because it keeps the contributor entry point simple — one container, one `devcontainer.json` — and avoids the orchestration complexity of managing multiple containers for what is ultimately a development-time convenience layer. The tradeoff is that the image is larger than any individual contributor needs, but pre-built images and layer caching keep startup fast enough in practice.
+
+The same container image also serves as a CI execution environment, which is important because it means the tools a contributor runs locally and the tools CI runs remotely are the same versions. That alignment is not automatic — it requires that CI workflows explicitly pull the devcontainer image rather than assembling their own tool stack — but when it works, it eliminates a class of "works on my machine" failures.
+
+### 2.1.1 Shared Tool Baseline 🟠
+
+*Defining which surrounding tools are present by default.*
+
+The shared base should contain the local-only and supporting tools that recur across the S-CORE repository landscape. Typical examples are language servers, formatters, YAML and Markdown validators, workflow checks, documentation helpers, and other tools that improve development ergonomics but do not belong to the primary build toolchain model.
+
+In S-CORE, that baseline is currently expressed through the published `ghcr.io/eclipse-score/devcontainer` image family. The central devcontainer repository defines the included tools, pins their versions, and preconfigures them for Eclipse S-CORE development.
+
+### 2.1.2 Repository Consumption 🟡
+
+*Connecting individual repositories to the common environment.*
+
+A central environment only helps if repositories consume it in a predictable way. The infrastructure concern here is not only that an image exists, but that repositories expose the same basic entry path and do not each reinvent how contributors attach to it.
+
+In S-CORE, the concrete mechanism is a checked-in `.devcontainer/devcontainer.json` that points to a versioned image from the central devcontainer. That gives repositories a practical way to consume the shared environment today, but adoption is still uneven across repository classes.
+
+The rollout dimension matters as much as the initial setup. When the central devcontainer publishes a new image version — adding a tool, updating a formatter, fixing a bug — each consuming repository needs to update its `.devcontainer/devcontainer.json` reference. Without automation, that update becomes a manual pull request in every repository, which tends to drift. Automated version bumps through Dependabot or a similar mechanism can keep repositories tracking the latest image, but the rollout must still be staged so that a broken image update does not simultaneously break every repository's development environment.
+
+Repository integration of the central devcontainer is still inconsistent enough that contributors cannot always assume the same entry path everywhere.
+
+### 2.1.3 IDE And Shell Integration 🟠
+
+*Making the environment usable from editors and terminals.*
+
+The environment is only useful if editors and shells can consume its tools directly. This matters especially for language servers, formatters, and non-build linters, because these integrations often expect real executables and preconfigured settings rather than wrappers around deeper build commands.
+
+In S-CORE, the clearest supported path today is the devcontainer-based workflow in VS Code, and the central devcontainer is explicitly documented for Dev Containers usage. The same containerized environment is also the intended terminal path, so local work does not depend on a separate host setup. Other devcontainer-capable IDEs are possible, but the support story is less explicitly defined. The supported baseline for editor-visible tools and shell entry points is still clearer in practice than it is in project-wide documentation.
+
+## 2.2 Local Auxiliary Tooling 🟡
+
+*Lightweight local checks and helpers that complement repository-specific build flows and CI.*
+
+Not every useful local check should be expressed as part of the main build. Fast repository hygiene checks, text and YAML validation, formatting checks, and similar surrounding tasks benefit from lightweight local delivery instead of waiting for a full build or CI round trip. That is true both for Bazel-based software repositories and for repositories that use different local workflows.
+
+In S-CORE, this auxiliary tooling is currently delivered through a combination of tools present in the central devcontainer and shared hook-based validation. That gives the project a local feedback layer around repository work in general rather than forcing all such checks into Bazel. This local auxiliary layer exists, but it is not yet described and standardized as one coherent cross-repository capability.
+
+### 2.2.1 Pre-commit And Fast Checks 🟠
+
+*Providing quick validation for repository hygiene and non-build assets.*
+
+[pre-commit](https://pre-commit.com/) is a good fit for checks that should fail quickly and early: formatting, text hygiene, YAML validation, workflow checks, and similar lightweight tasks. This is important because such checks are often the first things to drift when repositories have no shared local enforcement path.
+
+In S-CORE, custom hooks are published through [eclipse-score/tooling](https://github.com/eclipse-score/tooling/blob/main/.pre-commit-hooks.yaml) and combined with standard ecosystem hooks. Together with the central devcontainer, that gives repositories a shared mechanism for lightweight local validation before CI. Adoption, hook coverage, and enforcement expectations for these fast checks are still inconsistent across the repository landscape.
+
+### 2.2.2 Boundary To Bazel And CI 🟡
+
+*Clarifying what stays local, what belongs in Bazel, and what remains CI-only.*
+
+The local auxiliary layer needs a clear boundary or repositories will duplicate checks, force unsuitable tasks through lightweight hooks, or blur the line between convenience and authoritative enforcement. The infrastructure question here is not to make every check identical, but to define the right delivery layer for each kind of check.
+
+In S-CORE, the current practical split is that surrounding-tool checks run directly in the shared devcontainer or via pre-commit, while deeper repository-native validation stays with the repository's main build or test flow and final enforcement stays in CI. For "dependable element" repositories that usually means Bazel, but other repositories may use different local execution paths.
+
+Where repositories use dependency lock files such as `uv.lock` or `MODULE.bazel.lock`, the practical local refresh step may still happen through `pre-commit`, but the lock state itself belongs to the repository's dependency model and is therefore described in [chapter 3](03-build-infrastructure.md#lock-files).
\ No newline at end of file
diff --git a/docs/explanation/03-build-infrastructure.md b/docs/explanation/03-build-infrastructure.md
new file mode 100644
index 0000000..8422282
--- /dev/null
+++ b/docs/explanation/03-build-infrastructure.md
@@ -0,0 +1,389 @@
+# 3 Build & Dependencies ⚪
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Deterministic, reproducible builds across S-CORE repositories using Bazel as the shared build system, including the dependency and evidence model around those builds.*
+
+:::{warning} Draft
+This chapter has not been fully reviewed. Content may be incomplete or inaccurate.
+:::
+
+**S-CORE**
+
+- Bazel is the standard build system direction for S-CORE middleware repositories.
+- Shared build rules and toolchain definitions are intended to reduce per-repository configuration duplication.
+- Internal Bazel modules are expected to be distributed through the shared S-CORE registry at [eclipse-score/bazel_registry](https://github.com/eclipse-score/bazel_registry/).
+- Remote caching is available to reduce repeated build work across CI pipelines.
+- Dependency governance, SBOMs, and provenance belong here because they should be derived from normal builds rather than added only at release time.
+- The end-to-end compliance interpretation of those outputs, including license enrichment, development-versus-product SBOM scope, and later monitoring, belongs in [chapter 6](06-compliance-infrastructure.md), not in the build chapter itself.
+- This scope includes not only middleware outputs, but also self-developed tooling and environment artifacts such as Python tooling packages and devcontainer images when they are built and published by S-CORE.
+- Contributor onboarding, IDE support, and surrounding local tooling guidance for those environments belongs in [chapter 2](02-developer-environment.md); this chapter owns the build-time model behind them.
+- **Biggest gap**: shared build rule libraries, toolchain baselines, dependency policy, and build evidence are not yet consistently available across all S-CORE repositories.
+
+```{mermaid}
+graph LR
+ module["MODULE.bazel\n(bazel_dep declarations)"]
+ score_reg["`S-CORE registry\neclipse-score/bazel_registry`"]
+ bcr["Bazel Central Registry\nbcr.bazel.build"]
+ build["bazel build //..."]
+ cache["Remote build cache"]
+ toolchains["Toolchain modules\nbazel_cpp_toolchains\ntoolchains_rust"]
+ policies["Policy modules\nscore_cpp_policies\nscore_rust_policies"]
+
+ module -->|"1st: resolve S-CORE deps"| score_reg
+ module -->|"2nd: fallback"| bcr
+ score_reg --> build
+ bcr --> build
+ toolchains --> build
+ policies --> build
+ build <-->|"cache hits / writes"| cache
+```
+
+## 3.1 Build System ⚪
+
+*Core build tooling and workspace conventions shared across S-CORE repositories.*
+
+**S-CORE**
+
+- Bazel workspaces are the standard unit of build organization across S-CORE middleware repositories.
+- Shared Bazel rules are provided via the [eclipse-score/tooling](https://github.com/eclipse-score/tooling) repository.
+- **Biggest gap**: workspace structure conventions and target naming standards are not formally defined or enforced cross-repository.
+
+### 3.1.1 Project Structure
+
+*Standard organization of Bazel workspaces across S-CORE repositories.*
+
+**S-CORE**
+
+- Repository layout conventions emerge from shared rule usage but are not yet formally standardized.
+- **Biggest gap**: no centrally enforced or documented reference workspace structure exists.
+
+### 3.1.2 Build Rule Libraries
+
+*Reusable Bazel rules and macros shared across S-CORE repositories.*
+
+**S-CORE**
+
+- Shared Bazel macros and rules are provided via [eclipse-score/tooling](https://github.com/eclipse-score/tooling).
+- **Biggest gap**: rule coverage is incomplete; not all repository types have suitable shared rules.
+
+### 3.1.3 Build Conventions
+
+*Shared target naming and repository layout conventions.*
+
+**S-CORE**
+
+- Naming and layout conventions are expected from shared rule usage but not yet formally documented.
+- **Biggest gap**: no cross-repository convention enforcement mechanism exists.
+
+## 3.2 Dependency Management ⚪
+
+*Managing external and internal dependencies in a consistent, auditable way across S-CORE repositories.*
+
+**S-CORE**
+
+- External dependencies are declared per repository in Bazel workspace files; pinning strategies vary.
+- Internal S-CORE Bazel modules should be consumed through the shared registry instead of ad hoc repository wiring.
+- Build-generated dependency inventories are needed to support licensing, SBOM generation, and the later compliance flow described in [chapter 6](06-compliance-infrastructure.md).
+- The same dependency-governance expectations should apply to product code, self-developed tooling, and environment artifacts.
+- **Biggest gap**: no unified dependency policy or cross-repository version alignment standard exists.
+
+### 3.2.1 Third-Party Dependencies
+
+*Integration and management of external libraries via Bazel.*
+
+**S-CORE**
+
+- External libraries are imported via Bazel Central Registry; apart from the shared internal S-CORE registry for first-party modules, no shared third-party registry or approved source list exists.
+- **Biggest gap**: duplicate declarations and version drift across repositories are unmitigated.
+
+### 3.2.2 Internal Module Dependencies
+
+*Managing build-time dependencies between S-CORE repositories.*
+
+**S-CORE**
+
+S-CORE repositories are expected to exchange Bazel modules through the shared registry at [eclipse-score/bazel_registry](https://github.com/eclipse-score/bazel_registry/). From the build perspective, this section is only about consumption: a repository should resolve first-party modules through the registry rather than through ad hoc repository overrides or manual source wiring. The full publication flow, including the coupling between registry entries and GitHub Releases, is described in [chapter 8](08-artifact-distribution.md#registry-based-distribution).
+
+For consumers, the practical step is to tell Bazel where to look for modules. The same registry configuration described in [chapter 8](08-artifact-distribution.md#consumer-guidance) applies here:
+
+```text
+common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/
+common --registry=https://bcr.bazel.build
+```
+
+Once that is in place, dependencies are declared in `MODULE.bazel` with Bazel's normal module mechanism such as `bazel_dep(...)`. That is enough for the build side. Module discovery, release mechanics, and service ownership are intentionally documented in [chapter 8](08-artifact-distribution.md#registry-based-distribution) and [chapter 10](10-infrastructure-operations.md#shared-registry-services) instead of being repeated here.
+
+
+### 3.2.3 Dependency Policies
+
+*Rules governing allowed dependencies across S-CORE.*
+
+**S-CORE**
+
+- No formal cross-repository dependency policy currently exists.
+- This should cover allowed sources, pinning expectations, version alignment, and license handling.
+- **Biggest gap**: dependency choices are inconsistent and unaudited without policy guardrails.
+
+### 3.2.4 Dependency Inventories
+
+*Tracking the dependencies present in builds and why they are there.*
+
+**S-CORE**
+
+- Dependency inventories should be derived from the real build graph rather than maintained manually.
+
+### 3.2.5 Tooling and Environment Dependencies
+
+*Managing dependencies of self-developed tooling and environment artifacts with the same rigor as product builds.*
+
+**S-CORE**
+
+- S-CORE-developed tooling, especially Python-based tooling, is also part of the build and dependency landscape even when it is not product code.
+- The same is true for build-relevant environment artifacts such as the devcontainer, because they package dependencies, licenses, and supply-chain choices into something contributors and CI consume directly.
+- **Biggest gap**: tooling repositories and environment artifacts are not yet described as first-class citizens of the shared dependency-governance model.
+
+### 3.2.6 Lock Files
+
+*Capturing the resolved dependency graph in version control for reproducible Bazel and `uv` inputs.*
+
+**S-CORE**
+
+Lock files such as `MODULE.bazel.lock` and `uv.lock` make the resolved dependency graph explicit instead of leaving each machine to rediscover it from the high-level declarations. From the build and dependency perspective, that matters because reproducibility depends not only on the declared inputs, but also on the exact resolved result that Bazel or `uv` will consume.
+
+In the S-CORE repository landscape, this pattern already exists in practice, but not yet consistently across all repositories. Where lock files are used, the practical refresh step is typically handled locally through `pre-commit` and committed together with the dependency declaration change rather than being edited by hand. CI should then treat the committed lock state as authoritative for both Bazel and `uv` flows and fail when the declarations and the lock file no longer match. Current automated updates are also split by source: `renovate-bot` updates dependencies that come through the local S-CORE registry, while Dependabot updates dependencies that come from public registries.
+
+### 3.2.7 Known-Good Integration Sets
+
+*Capturing the explicit cross-repository integration manifest and metadata used to assemble one S-CORE stack.*
+
+The `known_good` manifest identifies which component revisions belong together in one validated S-CORE stack. It sits one level above ordinary Bazel lock files: a lock file captures the resolved dependency graph inside a workspace, while `known_good` is the curated integration selection from which those inputs are generated.
+
+The architectural context and decision background for this mechanism are documented separately: see [Infrastructure Design Decisions → `known_good` Architecture Note](decisions.md#known-good-architecture-note).
+
+## 3.3 Toolchain Management ⚪
+
+*Compiler and runtime toolchain configuration for C++, Rust, and Python across S-CORE builds.*
+
+**S-CORE**
+
+- Toolchain versions and build-time configuration are owned here, even when contributors access the surrounding local tooling through the shared environment described in [chapter 2](02-developer-environment.md).
+- Shared toolchain baselines are the main link between the Bazel build model and automated build execution.
+
+S-CORE is increasingly using a deliberate split between language toolchain modules and language policy modules. Toolchain repositories answer "how do we build this language in Bazel?" and therefore own compiler integration, sysroots, templates, registration, and other mechanics needed for reproducible builds. Separate policy repositories answer "which shared rules should repositories follow?" and package lint, warning, formatting, sanitizer, and safety-profile defaults that consumers can adopt without being forced onto a particular compiler rollout at the same time. That separation matters because toolchain upgrades and policy changes have different ownership and should be able to evolve on different cadences. **Biggest gap**: the pattern now exists in the S-CORE repository landscape, but it is not yet documented and adopted consistently enough that consumers can rely on it as the default model.
+
+### 3.3.1 C++ Toolchains
+
+*Compiler and build configuration for C++ components.*
+
+**S-CORE**
+
+The emerging C++ structure follows that split directly. [eclipse-score/bazel_cpp_toolchains](https://github.com/eclipse-score/bazel_cpp_toolchains) is the build-facing module: it provides the Bazel C/C++ toolchain configuration layer, templates, package descriptors, and registration logic for Linux and QNX builds. [eclipse-score/score_cpp_policies](https://github.com/eclipse-score/score_cpp_policies) is the policy-facing companion: it centralizes reusable `cc_feature` and flag selections such as ASan, UBSan, LSan, and TSan support, `debug_symbols`, runtime environment templates, constraint targets such as `no_tsan` and `any_sanitizer`, and the flag infrastructure that repositories can use in `select()` expressions. That same policy layer is also the natural home for shared warning baselines and later ASIL-oriented safety configurations. The point of the split is that a module should be able to adopt shared C++ policies without being forced onto one specific toolchain release. The runtime purpose and rollout of sanitizers themselves belong in [chapter 4](04-testing-infrastructure.md#sanitizers-runtime-checks); this subsection only owns the reusable build-side mechanism that makes those checks selectable. **Biggest gap**: the repository split now exists, but common adoption and governance of shared C++ toolchain and policy baselines are still incomplete across S-CORE.
+
+### 3.3.2 Rust Toolchains
+
+*Toolchain configuration for Rust components.*
+
+**S-CORE**
+
+Rust already shows the same separation more explicitly. [eclipse-score/toolchains_rust](https://github.com/eclipse-score/toolchains_rust) packages the actual Rust toolchains for Bazel, including prebuilt Ferrocene toolchains and the helper extension used to register them. [eclipse-score/score_rust_policies](https://github.com/eclipse-score/score_rust_policies) separately packages the shared Clippy and rustfmt defaults that S-CORE projects are expected to consume. In other words, one repository answers how Bazel gets a Rust compiler, while the other answers which Rust lint and formatting rules S-CORE wants to enforce. Keeping those concerns decoupled allows toolchain upgrades and policy tightening to evolve independently instead of being forced into one release stream. **Biggest gap**: the split is already visible in the repository landscape, but consistent rollout and governance of those shared Rust baselines are still not project-wide.
+
+### 3.3.3 Python Toolchains
+
+*Python runtime and tooling configuration for build and test.*
+
+**S-CORE**
+
+- Python toolchains vary per repository; no shared Python version baseline is defined.
+- **Biggest gap**: no cross-repository Python toolchain standard is enforced.
+
+### 3.3.4 Toolchain Governance
+
+*Managing how shared toolchain baselines are selected and rolled out.*
+
+**S-CORE**
+
+- Shared toolchains need visible ownership and an upgrade cadence or repositories will drift again.
+- **Biggest gap**: no cross-repository process clearly defines who owns toolchain baselines and how changes propagate.
+
+### 3.3.5 QNX SDP Provisioning
+
+*How the QNX Software Development Platform is obtained and made available to Bazel C++ builds.*
+
+The QNX SDP — the compiler, headers, and libraries required for QNX cross-compilation — is a commercial artifact distributed separately from the toolchain configuration. Its provisioning path is distinct from the Bazel toolchain registration in `bazel_cpp_toolchains` and determines how reliably builds can acquire the SDP in CI and in local developer environments.
+
+License on CI: A separate [`setup-qnx-sdp`](https://github.com/eclipse-score/cicd-actions) composite action handles license activation only; it does not fetch or unpack the SDP
+
+License locally: License credentials are injected through environment variables.
+
+#### Today
+
+The SDP is downloaded as a tar archive from QNX.com via a hardcoded dependency URL in Bazel. Forks may overwrite this dependency.
+
+```{mermaid}
+flowchart LR
+ qnxcom(["QNX.com"])
+ sdp_tar["`QNX SDP
+〈artefact: tar〉`"]
+ env_cfg(["Local Environment variables"])
+ license(["License"])
+ action_setup["`setup-qnx-sdp
+(license only)`"]
+ bazel["Bazel build C++"]
+
+ qnxcom --> sdp_tar
+ sdp_tar -->|"hardcoded dependency URL"| bazel
+ action_setup --> license
+ env_cfg --> license
+
+ license -->|"activates license only"| bazel
+```
+
+The license and the SDP fetch are deliberately separate.
+
+#### Soon (planned)
+
+The target model does not rely on QMX.com, but rather uses the QNX CLI distributed with QNX Software Center to produce a local SDP. That SDP is then stored in bazel cache, on your local computer, in ci cache, on protected eclipse artefact storage, or on company-internal artefact storage — and Bazel receives a user-defined flag that tells it where to find the SDP. For local developer environments the intended invocation is:
+
+```text
+bazel run //:local_qnx_sdp -- --path=/opt/qnx_sdp
+# or
+local_qnx_sdp.sh --path=/opt/qnx_sdp
+```
+
+```{mermaid}
+flowchart TD
+ qnx_sc(["QNX Software Center"])
+ qnx_cli["`QNX CLI
+〈tool〉`"]
+ sdp_dir["`QNX SDP
+〈artefact: directory tree〉`"]
+ art_store[("Artefact storage
+eclipse · company-internal · local")]
+ bazel["Bazel build C++"]
+
+ qnx_sc -.-> qnx_cli
+ qnx_cli -.-> sdp_dir
+ sdp_dir -.-> art_store
+ art_store -.->|"user-defined flag"| bazel
+```
+
+The central unsolved problem in this model is how we can provide this SDP as a true bazel dependency to qnx-related builds, as it has a **non-deterministic SDP output**. So building the SDP on the fly produces a different archive hash on every invocation. Bazel treats a changed hash as a changed dependency, which invalidates the **entire** C++ build cache and forces a full recompilation of all downstream targets on every run. Until the SDP can be built deterministically using it as a bazel dependency is not practical.
+
+
+## 3.4 Build Reproducibility & Evidence ⚪
+
+*Ensuring builds are deterministic and produce trustworthy evidence from the same inputs.*
+
+**S-CORE**
+
+- Bazel's hermetic execution model is the foundation for reproducibility across S-CORE.
+- SBOMs and provenance should be normal build outputs, while publication of that evidence belongs in [chapter 8](08-artifact-distribution.md).
+- Once generated, those SBOMs become inputs to the compliance flow in [chapter 6](06-compliance-infrastructure.md), which decides their scope, enriches them, and feeds later monitoring.
+- The same expectation should hold for self-developed tooling and dev environment artifacts where S-CORE builds and distributes them.
+- This evidence model belongs here because it is about built artifacts, not the contributor workflow described in [chapter 2](02-developer-environment.md).
+- **Biggest gap**: hermetic build compliance, reproducibility verification, and build-derived evidence are not yet generated or enforced uniformly across repositories.
+
+### 3.4.1 Hermetic Builds
+
+*Isolating builds from host environments to ensure reproducibility.*
+
+**S-CORE**
+
+- The devcontainer provides a stable, isolated build environment for CI and local builds.
+- **Biggest gap**: full hermetic compliance (no host toolchain leakage) is not uniformly verified.
+
+### 3.4.2 Deterministic Artifacts
+
+*Ensuring builds produce identical artifacts from the same inputs.*
+
+**S-CORE**
+
+- Bazel's action graph model is designed for determinism; actual reproducibility is not validated at scale.
+- **Biggest gap**: no cross-repository determinism validation pipeline exists.
+
+### 3.4.3 Build Traceability
+
+*Tracking build inputs, outputs, and provenance metadata.*
+
+**S-CORE**
+
+- Build provenance and SBOM generation are target capabilities and should become routine outputs of normal builds so that later release and compliance steps consume real build evidence instead of reconstructed paperwork.
+- In cross-repository integration flows, that provenance should identify not only the local repository revision but also the `known_good` set or equivalent manifest that defined the integrated stack.
+- **Biggest gap**: no build pipeline currently produces SBOMs and provenance consistently across repository types.
+
+### 3.4.4 Tooling, Environment SBOMs & License Evidence
+
+*Generating SBOMs and license/compliance evidence for S-CORE-developed tooling and environment artifacts.*
+
+**S-CORE**
+
+- Internally developed tools and dev environment artifacts also need SBOMs and license visibility, not only the main product build outputs.
+- For contributors and CI, a devcontainer image is effectively a distributed engineering artifact and should therefore carry the same evidence expectations around dependencies and license compliance.
+- Once those artifacts have been built, [chapter 6](06-compliance-infrastructure.md) should treat them the same way as other compliance inputs, including scope decisions and monitoring, rather than leaving them outside the shared flow.
+- The fact that contributors enter that environment through the workflow described in [chapter 2](02-developer-environment.md) does not change that its evidence model belongs with the other build outputs here.
+- **Biggest gap**: SBOM and license-compliance treatment for tooling artifacts and environment images is not yet described as part of the normal build-evidence flow.
+
+### 3.4.5 Rebuild Verification
+
+*Checking whether reproducibility claims hold over time and across execution contexts.*
+
+**S-CORE**
+
+- Rebuild verification would expose hidden toolchain changes, archive drift, and environmental assumptions.
+- **Biggest gap**: reproducibility is desirable, but not yet verified through a shared repeatable process.
+
+## 3.5 Build Execution Infrastructure ⚪
+
+*Infrastructure for executing Bazel builds efficiently across local work and CI pipelines.*
+
+**S-CORE**
+
+- Builds run on GitHub Actions using GitHub-hosted and self-hosted runners.
+- A shared Bazel remote cache reduces redundant compile work across pipeline runs.
+- **Biggest gap**: remote build execution and shared performance visibility are not yet available project-wide.
+
+### 3.5.1 Remote Cache
+
+*Sharing Bazel build outputs between pipeline runs to reduce rebuild time.*
+
+**S-CORE**
+
+- A shared Bazel remote cache is available to S-CORE CI pipelines.
+- **Biggest gap**: remote cache connectivity and configuration are not uniformly set up across all repositories.
+
+### 3.5.2 Remote Build Execution
+
+*Executing Bazel build actions on remote compute resources.*
+
+**S-CORE**
+
+Remote Build Execution (RBE) offloads Bazel's action graph to a cluster of workers so that parallelism is no longer bound by the CPU and memory of a single runner. For S-CORE, the practical value is twofold: CI builds that currently serialize on a single GitHub Actions runner could fan out across remote workers, and developers running Bazel locally could optionally delegate heavy compilations to remote infrastructure while keeping the edit-build-test cycle on their own machine.
+
+The infrastructure involves three layers. First, a backend service that implements the Bazel Remote Execution API — candidates range from open-source solutions such as Buildbarn and BuildBuddy Community to managed commercial services. Second, the CI and local `.bazelrc` configuration that enables remote execution for the right subset of actions without breaking platform-specific builds. Third, authentication and access control so that the backend serves authorized S-CORE builds without exposing the cluster to uncontrolled workloads.
+
+A related Bazel mechanism is dynamic execution, which lets Bazel race a local and a remote execution of the same action and take whichever finishes first. This can smooth the transition period where some actions run faster locally and others benefit from remote workers, but it adds complexity to the configuration and requires the backend to tolerate speculative cancellations.
+
+For hardware-oriented testing, RBE intersects with the hardware runner story in [section 7.1.2](07-automation-integration.md#hardware-test-runners). If lab-attached devices such as Raspberry Pi boards are registered as RBE workers, Bazel could schedule test execution on real hardware as part of a normal `bazel test` invocation, avoiding a separate deployment step. This is an advanced pattern that depends on both the RBE backend and the hardware provisioning model being in place.
+
+**Biggest gap**: no RBE backend is available; builds are constrained to single-runner execution. Provider evaluation criteria, architecture decisions, and authentication model are not yet documented.
+
+### 3.5.3 Build Resource Scheduling
+
+*Scheduling and allocating compute resources for build workloads.*
+
+**S-CORE**
+
+- CI runner allocation is handled via GitHub-hosted and self-hosted runner scheduling.
+- **Biggest gap**: no build-aware resource scheduling or prioritization mechanism is in place.
+
+### 3.5.4 Build Performance Visibility
+
+*Understanding where build time goes and where infrastructure work has the highest payoff.*
+
+**S-CORE**
+
+- Shared visibility should include queue times, cache effectiveness, and critical-path behavior.
+- **Biggest gap**: build performance data is not yet aggregated into a shared view for project-wide prioritization.
\ No newline at end of file
diff --git a/docs/explanation/04-testing-infrastructure.md b/docs/explanation/04-testing-infrastructure.md
new file mode 100644
index 0000000..db5add4
--- /dev/null
+++ b/docs/explanation/04-testing-infrastructure.md
@@ -0,0 +1,283 @@
+# 4 Testing 🟠
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure supporting automated testing across S-CORE repositories, including dynamic analysis and verification evidence generation.*
+
+**S-CORE**
+
+Testing infrastructure in S-CORE is centered on executable Bazel test targets, shared framework integration, traceability metadata, and reporting that can be consumed as verification evidence. The verification process may still use named levels such as unit, component integration, feature integration, and platform tests, but that taxonomy belongs to process guidance rather than this chapter. From the infrastructure perspective, the practical distinction is simpler: lower-level tests usually live in module repositories, while broader scenario-driven and target-oriented execution increasingly collects around shared environments such as `reference_integration` and ITF.
+
+That scope also explains why coverage, sanitizers, fuzzing, and profiling belong here. They are runtime techniques that depend on executing software, even when their outputs are later consumed by documentation, compliance, or CI chapters. **Biggest gap**: testing capability already exists in several strong islands, but shared conventions for framework packaging, traceability, aggregation, dashboards, and advanced runtime analysis are still incomplete across S-CORE.
+
+## 4.1 Test Framework Integration 🟠
+
+*Integrating language-specific and target-specific test frameworks with the Bazel build system.*
+
+**S-CORE**
+
+S-CORE already has a workable multi-language testing base. Repositories define Bazel `*_test` targets for C++, Rust, and Python, and higher-level integration environments layer scenario support and target orchestration on top. What is still missing is a clearer shared baseline for how those frameworks are packaged, versioned, and reused so that repositories converge on similar patterns instead of each building a local interpretation. **Biggest gap**: no single shared framework baseline or packaging model is yet defined across all S-CORE repositories.
+
+### 4.1.1 C++ Test Frameworks 🟡
+
+*Infrastructure supporting C++ testing frameworks.*
+
+**S-CORE**
+
+C++ testing is one of the most mature paths today. Bazel-integrated frameworks such as GoogleTest already support ordinary unit-style execution well, and existing C++ flows are also ahead on coverage and evidence generation. The remaining issue is consistency: framework versions and Bazel rule setup still vary per repository. **Biggest gap**: framework versioning and Bazel rule configuration are not yet aligned across S-CORE.
+
+### 4.1.2 Rust Test Frameworks 🟠
+
+*Infrastructure supporting Rust testing frameworks.*
+
+**S-CORE**
+
+Rust tests typically use the native Rust test model through `rules_rust`, which fits well with the Bazel-centered infrastructure direction. The capability exists, but it is less even than the established C++ path, especially around reporting, coverage integration, and traceability metadata. **Biggest gap**: consistent `rules_rust` versioning and reporting support are not yet uniformly available.
+
+### 4.1.3 Python Test Frameworks 🟠
+
+*Infrastructure supporting Python testing frameworks.*
+
+**S-CORE**
+
+Python tests generally rely on pytest-style execution integrated through Bazel's Python rules. Python also matters beyond unit tests because it often acts as the orchestration layer for higher-level scenarios and target interaction, which is why ITF ([section 4.1.5](#itf-framework)) is itself pytest-based.
+
+For repositories that use pytest, the infrastructure question is not whether pytest works — it does — but whether repositories converge on a shared baseline for plugin selection, fixture patterns, and result output. Without that, each repository assembles its own pytest configuration, and shared tooling that consumes test results (reporting in [section 4.4](#test-reporting), traceability in [section 4.2](#test-traceability)) has to account for divergent output formats and metadata conventions. A shared pytest baseline would define which plugins are expected by default, how results are formatted for downstream consumption, and how system-level tests that need target interaction relate to the ITF plugin model.
+
+The rollout challenge is that pytest is used at multiple levels: lightweight unit-style tests in module repositories, orchestration-heavy system tests in integration environments, and ITF-based target tests. A shared baseline must be useful across those levels without forcing a one-size-fits-all configuration. **Biggest gap**: there is no shared Python test framework and plugin baseline across repositories, and the boundary between plain pytest usage and ITF-managed execution is not yet clearly drawn.
+
+### 4.1.4 Scenario Test Framework 🟠
+
+*Infrastructure supporting scenario-based testing for C++ and Rust.*
+
+**S-CORE**
+
+Scenario-style execution matters once testing spans modules, services, or richer system behavior. S-CORE already uses scenario-based approaches to exercise common flows across languages and repositories, which is especially relevant when `reference_integration` assembles modules into shared environments. The tradeoff is that scenario logic can be split across orchestration code and implementation-specific backends, which makes ownership and failure diagnosis harder. **Biggest gap**: scenario support exists, but it is not yet packaged as a uniformly reusable cross-repository capability.
+
+### 4.1.5 ITF Framework 🟡
+
+*Infrastructure supporting target-oriented integration and system-like testing.*
+
+**S-CORE**
+
+[ITF](https://github.com/eclipse-score/itf) is the clearest example of target-oriented higher-level testing infrastructure in the current landscape. It is pytest-based, designed for ECU-oriented testing, and built around a target-agnostic plugin model covering environments such as Docker, QEMU, and real hardware, along with concerns like DLT handling.
+
+The execution pipeline for ITF tests follows a layered model. Bazel invokes a pytest runner through the `py_itf_test` symbolic macro, which uses ITF plugins to manage the target environment — starting a Docker container, launching a QEMU instance, or connecting to a hardware device. The test code then interacts with the system under test through the environment that the plugin provides. Results flow back through pytest into Bazel's test result model as JUnit XML written to `$XML_OUTPUT_FILE`. This pipeline means that ITF tests can be triggered as ordinary `bazel test` targets while the execution complexity is hidden inside the plugin layer. Because the `py_itf_test` macro produces a standard `py_test` binary that bundles test code and all plugin dependencies, ITF tests participate fully in Bazel's incremental build and caching: a test is only re-run if its source, dependencies, or configuration changes.
+
+```{mermaid}
+graph TD
+ bazel["bazel test //path:my_itf_test"]
+ pytest["`pytest runner
+(py_itf_test macro)`"]
+ plugin["`ITF Plugin
+(Docker / QEMU / Hardware)`"]
+ target["`Target environment
+(container / VM / device)`"]
+ caps["`@requires_capabilities
+skip if not available`"]
+ results["`JUnit XML
+($XML_OUTPUT_FILE)`"]
+ trace["`@add_test_properties
+traceability metadata`"]
+
+ bazel --> pytest
+ pytest --> plugin
+ plugin --> target
+ plugin --> caps
+ caps -->|skip| pytest
+ target --> results
+ trace --> results
+```
+
+The central abstraction is the capability-based `Target` model. Each target exposes capabilities such as `exec`, `file_transfer`, `restart`, `ssh`, and `sftp`. Tests declare which capabilities they require using the `@requires_capabilities` decorator, and the framework skips tests when the active target does not provide them. This design lets the same test code run against different target environments — a Docker container locally, a QEMU image in CI, a real board in the lab — with the plugin determining which capabilities are available.
+
+The plugin model is what makes ITF extensible. Plugins fall into two categories:
+
+```{mermaid}
+graph TB
+ CORE["ITF Core Framework"]
+
+ subgraph "Target Plugins"
+ QEMU["QEMU Plugin"]
+ DOCKER["Docker Plugin"]
+ FUTURE_T["..."]
+ end
+
+ subgraph "Non-Target Plugins"
+ DLT["DLT Plugin"]
+ FUTURE_NT["..."]
+ end
+
+ CORE --- QEMU
+ CORE --- DOCKER
+ CORE --- FUTURE_T
+ CORE --- DLT
+ CORE --- FUTURE_NT
+
+ style CORE fill:#4a90d9,color:#fff,stroke:#2a6cb8
+ style QEMU fill:#7cb342,color:#fff,stroke:#5a8f2a
+ style DOCKER fill:#7cb342,color:#fff,stroke:#5a8f2a
+ style FUTURE_T fill:#7cb342,color:#fff,stroke:#5a8f2a
+ style DLT fill:#f4a460,color:#fff,stroke:#d4845a
+ style FUTURE_NT fill:#f4a460,color:#fff,stroke:#d4845a
+```
+
+**Target plugins** override the `target_init` fixture to yield a `Target` subclass — they determine what environment the test runs against. Only one target plugin is active at a time. **Non-target plugins** (like DLT) provide independent fixtures and compose freely with any target plugin. Four built-in plugins cover the current scope:
+
+| Plugin | Bazel label | Purpose |
+|---|---|---|
+| Docker | `@score_itf//score/itf/plugins:docker_plugin` | Container targets with `exec`, `file_transfer`, `restart` capabilities |
+| QEMU | `@score_itf//score/itf/plugins:qemu_plugin` | VM targets adding `ssh`, `sftp`, and network testing |
+| DLT | `@score_itf//score/itf/plugins:dlt_plugin` | Diagnostic Log and Trace message capture and query |
+| Attribute | `@score_itf//score/itf/plugins:attribute_plugin` | Requirement traceability metadata in JUnit XML |
+
+New target types can be added by implementing the `Target` abstract class and a `target_init` pytest fixture in a new plugin — the ITF core and existing tests require no changes.
+
+The capability abstraction is what makes the same test file portable across environments:
+
+```{mermaid}
+graph LR
+ TEST["Test Code"]
+ CAP["Capabilities\nexecute, upload,\ndownload, restart"]
+ PLUGIN["Plugin"]
+ TARGET["Concrete Target"]
+
+ TEST -->|"calls"| CAP
+ CAP -->|"dispatches to"| PLUGIN
+ PLUGIN -->|"controls"| TARGET
+
+ style TEST fill:#4a90d9,color:#fff,stroke:#2a6cb8
+ style CAP fill:#f4a460,color:#fff,stroke:#d4845a
+ style PLUGIN fill:#7cb342,color:#fff,stroke:#5a8f2a
+ style TARGET fill:#888,color:#fff,stroke:#666
+```
+
+ITF runs entirely on the host. It never communicates with the target directly — the plugin handles all provisioning, communication, and teardown. Adding support for a new hardware target (Raspberry Pi, Qualcomm board, etc.) requires only a new plugin:
+
+```{mermaid}
+graph LR
+ subgraph "Host"
+ ITF["ITF + pytest"]
+ PLUGIN["Target Plugin"]
+ end
+
+ ITF --> PLUGIN
+
+ PLUGIN -->|"today"| QEMU["QEMU VM"]
+ PLUGIN -->|"today"| DOCKER["Docker Container"]
+ PLUGIN -.->|"future"| RASPI["Raspberry Pi"]
+ PLUGIN -.->|"future"| QUALCOMM["Qualcomm Board"]
+
+ style ITF fill:#4a90d9,color:#fff,stroke:#2a6cb8
+ style PLUGIN fill:#7cb342,color:#fff,stroke:#5a8f2a
+ style QEMU fill:#f4a460,color:#fff,stroke:#d4845a
+ style DOCKER fill:#f4a460,color:#fff,stroke:#d4845a
+ style RASPI fill:#ccc,color:#666,stroke:#999,stroke-dasharray: 5 5
+ style QUALCOMM fill:#ccc,color:#666,stroke:#999,stroke-dasharray: 5 5
+```
+
+ITF is structured across three Bazel modules. `score_itf` is the open-source core (plugin contract, Bazel rules, pytest integration). Private or proprietary plugins live in separate repositories (e.g. `vsps_itf_plugins` for ETAS-internal targets) and are consumed via `git_override` or `archive_override` in the test consumer's `MODULE.bazel`. This separation means the open-source core can evolve independently from private plugin implementations.
+
+For traceability, the attribute plugin provides an `@add_test_properties` decorator that writes metadata such as `fully_verifies`, `test_type`, and `derivation_technique` into JUnit XML output. This connects ITF test results to the traceability model described in [section 4.2](#test-traceability).
+
+**Biggest gap**: the ITF plugin model and capability system are established, but onboarding guidance for module teams adopting ITF is still thin. The Bazel-side integration for passing traceability metadata from build targets into the attribute plugin is not yet streamlined.
+
+## 4.2 Test Traceability 🟠
+
+*Infrastructure for tracking traceability between test cases, requirements, and verification evidence.*
+
+**S-CORE**
+
+Test traceability is one of the parts of the testing stack that already shows a clear end-to-end shape. Test implementations can add requirement information to reports, and the docs-as-code flow can consume those reports to create links back into requirements and verification artifacts. Tests therefore behave as first-class evidence objects, even when they are represented differently from textual requirements. Higher-level traceability in `reference_integration` is already moving in the same direction.
+
+The concrete mechanism for ITF-based tests is the attribute plugin's `@add_test_properties` decorator, which writes structured metadata into the JUnit XML report. The supported fields include `fully_verifies` (list of requirement identifiers the test covers), `test_type` (e.g. `requirements-based`), and `derivation_technique` (e.g. `requirements-analysis`). Sphinx-based documentation tooling can then consume these JUnit XML reports to create bidirectional traceability between test results and requirement objects. This creates a verification chain from requirement through implementation to test result, which is especially valuable when requirements change between releases and the documentation build needs to identify which links break.
+
+**Biggest gap**: Rust targets and some higher-level frameworks still cannot carry the same degree of traceability metadata as the more mature C++-centric and ITF-based flows.
+
+## 4.3 Test Execution & Dynamic Analysis 🟠
+
+*Infrastructure for executing automated tests and runtime-driven analysis via the build system.*
+
+**S-CORE**
+
+At execution time, the common model is straightforward: tests are Bazel targets and normally run through `bazel test`, which provides isolation and incremental reuse of previous results. When re-execution must be forced, `--nocache_test_results` is available, and coverage collection already follows the stricter rule of always re-running with instrumentation. This section also owns the runtime-oriented techniques that depend on executing software rather than inspecting it statically. That includes coverage, sanitizers, fuzzing, stress testing, profiling, and performance benchmarking, even when their outputs later feed other chapters. In practice, this mostly shows up as a deployment pattern: lower-level execution stays inside module repositories, while cross-repository and target-oriented execution increasingly relies on shared environments such as `reference_integration` and ITF.
+
+An important special case is cross-compiled test execution. S-CORE supports building for multiple target platforms through its toolchain infrastructure, but building a test binary and executing it are separate problems when the target platform differs from the build host. QNX is the clearest current example: [section 3.3.1](03-build-infrastructure.md#c-toolchains) describes how `bazel_cpp_toolchains` provides toolchain configuration for QNX builds, but running the resulting `cc_test` or `rust_test` binaries requires a QNX-capable execution environment.
+
+The [qnx_unit_tests](https://github.com/eclipse-score/qnx_unit_tests) module (`score_qnx_unit_tests`) solves this with a QEMU microvm approach. The `cc_test_qnx` and `rust_test_qnx` macros wrap standard Bazel test targets for execution inside QEMU running QNX 8. The execution pipeline packages the test binary and its runfiles into a tar archive, builds a QNX IFS boot image containing the kernel and startup scripts, boots QEMU with the IFS image, mounts the test archive via a custom virtio-9p resource manager for host-guest file sharing, executes the test, and extracts results (XML, coverage) from the shared directory. This supports both x86_64 and aarch64 target architectures and requires QEMU with KVM access for practical performance. QNX SDP 8.0 credentials are needed for the toolchain download.
+
+The same pattern applies to any platform where the build host cannot natively execute the test output, and it connects directly to the hardware runner infrastructure described in [section 7.1.2](07-automation-integration.md#hardware-test-runners). The QNX microvm approach is notable because it brings target execution into the normal `bazel test` flow without requiring a separate deployment or device provisioning step.
+
+**Biggest gap**: the QNX microvm execution model is functional for C++ and Rust unit tests, but broader cross-compiled test execution standards and runtime-analysis expectations are not yet defined consistently across repositories.
+
+### 4.3.1 Coverage & Runtime Instrumentation 🟠
+
+*Measuring exercised code and collecting instrumentation data during tests.*
+
+**S-CORE**
+
+Coverage is already part of the verification-evidence story in several places, which makes it one of the more concrete dynamic-analysis capabilities in S-CORE today. The missing piece is not the idea of coverage itself, but shared expectations around when it is required, how it is produced, and which result formats downstream tooling should rely on.
+
+For C++, Bazel can collect coverage using `bazel coverage` with the `--combined_report` flag, producing LCOV output that downstream tools can consume. The toolchain-level support comes from `bazel_cpp_toolchains` ([section 3.3.1](03-build-infrastructure.md#c-toolchains)), which configures the compiler instrumentation flags. The infrastructure gap is not the mechanism but the conventions: which targets should produce coverage, what minimum coverage expectations exist, and how results are aggregated across a module's test suite into a single report that CI can publish as an artifact.
+
+For Rust, `rules_rust` supports coverage through similar Bazel instrumentation, but the tooling maturity is lower than for C++. Source-based coverage via LLVM's `llvm-cov` is the preferred approach because it produces accurate line and region coverage without the branch-level noise of gcov-style instrumentation. The same LCOV output format should be used so that downstream reporting does not need language-specific parsers.
+
+For ITF-based tests, coverage collection crosses a process boundary because the test orchestrator (pytest) and the system under test (running in a Docker container, QEMU image, or on hardware) are separate processes. Collecting coverage in that scenario requires instrumentation on the target side and a mechanism to retrieve the coverage data after the test run completes. That integration is not yet in place for most ITF test configurations.
+
+**Biggest gap**: coverage expectations and result formats are not yet standardized across repositories. Language-specific coverage tooling exists but is not configured or reported consistently, and ITF-based coverage collection is not yet integrated.
+
+### 4.3.2 Sanitizers & Runtime Checks 🟠
+
+*Detecting runtime problems such as memory misuse, undefined behavior, or concurrency issues.*
+
+**S-CORE**
+
+Sanitizers and similar runtime checks can surface memory misuse, undefined behavior, or concurrency problems far earlier than system-level debugging. They are especially valuable for C and C++ heavy repositories, but they need common support and expectations if they are to become shared infrastructure rather than ad hoc local practice. The ownership boundary should stay explicit: [chapter 3](03-build-infrastructure.md#toolchain-management) owns how toolchains and Bazel features make sanitizers available, and [chapter 5](05-static-analysis-infrastructure.md#shared-rule-configuration) owns shared policy modules when they package reusable sanitizer feature sets or defaults. The moment those capabilities are executed against runnable targets and interpreted as verification evidence, however, they belong in the testing story here.
+
+### 4.3.3 Fuzzing, Stress & Profiling 🔴
+
+*Using generated inputs, stress techniques, and runtime diagnostics to expose robustness and performance issues.*
+
+**S-CORE**
+
+Fuzzing, stress execution, and profiling sit naturally next to the rest of the test execution story because they also depend on runnable targets, special harnesses, and result handling that differs from ordinary regression tests. They are relevant to robustness and performance, but they are still described more as possibilities than as reusable S-CORE capabilities. **Biggest gap**: advanced dynamic-analysis techniques beyond basic coverage are not yet defined as shared infrastructure.
+
+### 4.3.4 Performance & Benchmark Testing 🔴
+
+*Infrastructure for measuring and tracking runtime performance of S-CORE components on representative targets.*
+
+**S-CORE**
+
+Performance testing differs from functional testing in that the result is a measurement rather than a pass/fail verdict. A benchmark run produces timing data, throughput numbers, or resource consumption figures that only become meaningful when compared against a previous baseline or an agreed budget. That comparison model is what turns raw profiling output into actionable infrastructure.
+
+For S-CORE, the practical need comes from two directions. Module repositories want to detect performance regressions early, ideally as part of the normal Bazel test flow on cloud runners. Integration-level testing wants to measure representative workloads on real hardware targets such as embedded boards and automotive-grade SoCs, where host-based emulation cannot reproduce the actual timing and resource behavior.
+
+The infrastructure challenge is therefore layered. Cloud-based benchmark targets can reuse the existing runner and Bazel execution model, but they need stable machine baselines and a way to compare results across runs without being dominated by runner variance. Hardware-based benchmarks additionally need target provisioning, deployment, and result collection infrastructure that extends the hardware runner story described in [section 7.1.2](07-automation-integration.md#hardware-test-runners). The concrete hardware targets that matter today include Raspberry Pi boards for lightweight integration-level benchmarks and automotive-grade SoCs such as the Qualcomm SA8650P for representative platform performance measurement. Each target class has different provisioning and deployment requirements, but the result model — durable storage, baseline comparison, trend visualization — should be uniform. In both cases, results should be stored durably and presented as trend data rather than one-shot artifacts.
+
+**Biggest gap**: S-CORE has no shared performance testing framework, no benchmark result storage or comparison model, and no hardware target provisioning for performance measurement on boards such as Raspberry Pi or Qualcomm SA8650P.
+
+## 4.4 Test Reporting 🟠
+
+*Infrastructure for collecting, aggregating, and presenting test results as verification evidence across S-CORE.*
+
+**S-CORE**
+
+Test results are already visible in several places, but they do not yet form one consistent project-wide reporting layer. GitHub Actions exposes outcomes per pipeline run, release flows can aggregate and attach selected test and coverage artifacts, and some repositories already publish dashboard-style views for traceability or unit-test summaries. `reference_integration` also plays an important role in collecting higher-level evidence once modules are assembled and exercised together. The infrastructure direction is therefore visible: reporting should turn execution results into durable evidence that can be reviewed per run, per release, and eventually across repositories. **Biggest gap**: no centralized project-wide dashboard or durable cross-repository reporting model yet spans all of S-CORE.
+
+### 4.4.1 Result Aggregation 🟠
+
+*Infrastructure aggregating test results across CI pipeline runs.*
+
+**S-CORE**
+
+Aggregation already exists in pieces. CI runs produce artifacts, and release-oriented flows can combine selected outputs into something closer to a reusable evidence package. For higher integration levels, `reference_integration` is an especially important aggregation point because it collects results after cross-repository assembly and scenario execution. To stay meaningful, those aggregated results should be keyed to a concrete `known_good` manifest or record rather than to a vague notion of "current main". The fast integration subset can provide early feedback against a candidate manifest, but the deeper post-merge or scheduled suite is what should advance the stored known-good baseline. **Biggest gap**: aggregation works for some release flows, but continuous project-wide aggregation across repositories is still incomplete.
+
+### 4.4.2 Test Dashboards 🔴
+
+*Infrastructure providing dashboards for monitoring test results and trends.*
+
+**S-CORE**
+
+Some repositories already expose dashboard-like views for narrow concerns such as coverage or traceability, which shows the value of making test health visible beyond raw CI logs. What is missing is the shared layer that would let maintainers understand testing coverage and trends across repositories and execution styles without opening each repository separately. **Biggest gap**: test health visibility across S-CORE repositories is still fragmented.
\ No newline at end of file
diff --git a/docs/explanation/05-static-analysis-infrastructure.md b/docs/explanation/05-static-analysis-infrastructure.md
new file mode 100644
index 0000000..0d817c7
--- /dev/null
+++ b/docs/explanation/05-static-analysis-infrastructure.md
@@ -0,0 +1,206 @@
+# 5 Code Analysis Infrastructure ⚪
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure for inspecting S-CORE source code and repository configuration without executing the software, to enforce quality, consistency, and security expectations across repositories.*
+
+:::{warning} Draft
+This chapter has not been fully reviewed. Content may be incomplete or inaccurate.
+:::
+
+**S-CORE**
+
+- Static analysis complements testing by finding issues through code and configuration inspection instead of runtime verification.
+- This chapter defines the shared code-analysis capability: analyzer scope, baseline expectations, rule governance, and ownership boundaries across repositories.
+- Local execution and CI gating consume this capability in their own chapters rather than defining separate analyzer baselines.
+- In other words, [chapter 2](02-developer-environment.md) explains how contributors run checks locally, while this chapter explains which analyzers and rules those commands should carry.
+- Runtime-driven techniques such as coverage, sanitizers, fuzzing, and profiling belong in [chapter 4](04-testing-infrastructure.md), not here.
+- Dependency alerts, supply-chain analysis of dependency sets, and continuous SBOM monitoring belong in [chapter 6](06-compliance-infrastructure.md), not here.
+- **Biggest gap**: code analysis is not yet defined and governed as one cross-repository capability with shared tooling, rule baselines, and ownership expectations.
+
+## 5.1 Tooling Baseline ⚪
+
+*Defining which static analysis tools are approved, recommended, or required for different S-CORE repository types and languages.*
+
+**S-CORE**
+
+- Code analysis in S-CORE includes linters, type/interface analyzers, style and import checks, and security-oriented analyzers where appropriate.
+- Tool choice is currently influenced by language ecosystems, repository classes, and existing engineering practice.
+- **Biggest gap**: no explicit cross-repository baseline defines which analyzers are expected by default for C++, Rust, Python, and workflow or documentation assets.
+
+### 5.1.1 Tool Selection Criteria
+
+*Choosing analyzers that fit S-CORE repository needs and can be maintained at scale.*
+
+**S-CORE**
+
+- Tooling decisions should favor analyzers that can be shared across repositories, versioned centrally, and consumed consistently by local and automated execution environments.
+- Shared tools should produce machine-readable results where possible so reporting and policy gates can consume them consistently.
+- **Biggest gap**: selection criteria are implicit and repository-specific instead of centrally documented and reviewable.
+
+### 5.1.2 Repository and Language Baselines
+
+*Establishing default analyzer sets for major repository classes and implementation languages.*
+
+**S-CORE**
+
+- Different repository types need different analyzer sets, but the expected baseline should still be centrally defined.
+- Repository-specific additions are valid when justified by language, framework, or safety needs.
+- **Biggest gap**: baseline analyzer bundles and ownership of deviations are not yet described in one shared place.
+
+### 5.1.3 Non-Code Asset Analysis
+
+*Applying analyzers to workflows, documentation, configuration, and other repository assets beyond source code.*
+
+**S-CORE**
+
+- Repository quality and security depend on more than product code; workflow files, configuration, and documentation assets also need automated inspection.
+- **Biggest gap**: the analyzer baseline for non-code repository assets is even less defined than the baseline for implementation languages.
+
+---
+
+## 5.2 Shared Rule Configuration ⚪
+
+*Managing analyzer rules, severities, suppressions, and versioning as shared infrastructure instead of ad-hoc repository detail.*
+
+**S-CORE**
+
+- Shared rule configurations are an important part of repository standards and should be versioned like other infrastructure policy artifacts.
+- Repository overrides should be explicit, limited, and explainable rather than silent drift from the shared baseline.
+
+In the current S-CORE repository landscape, these shared rules are increasingly packaged as separate policy modules rather than being folded into toolchain repositories. That is why repositories such as `score_rust_policies` and `score_cpp_policies` belong to this chapter's perspective, while `toolchains_rust` and `bazel_cpp_toolchains` belong to [chapter 3](03-build-infrastructure.md#toolchain-management). The important architectural rule is that consumers should be able to adopt shared lint, warning, and formatting baselines without having to change compiler versions or Bazel toolchain registration at the same time. When such a policy also exposes selectable runtime-oriented features such as sanitizers, [chapter 4](04-testing-infrastructure.md#sanitizers-runtime-checks) still owns why and when those checks are executed; this chapter owns only the reusable rule baseline.
+
+### 5.2.1 Baseline Rulesets
+
+*Defining centrally maintained defaults for analyzer configuration.*
+
+**S-CORE**
+
+- Central baselines should define default enabled checks, severity handling, and common exclusions.
+- Baselines should be reusable in templates, synchronized configuration, or shared workflow inputs.
+- **Biggest gap**: there is no visible authoritative baseline for static-analysis rules across S-CORE repositories.
+
+### 5.2.2 Overrides and Suppressions
+
+*Allowing repository-specific exceptions without losing visibility or governance.*
+
+**S-CORE**
+
+- Overrides and suppressions are sometimes necessary for migration, generated code, third-party constraints, or language-specific false positives.
+- Exceptions should be narrow, reviewable, and traceable so that debt can be reduced over time.
+- **Biggest gap**: suppressions and local overrides are not yet governed by a shared policy for justification, expiry, or review.
+
+---
+
+## 5.3 Execution Model ⚪
+
+*Defining where and how the shared static-analysis capability should be executed across the engineering flow.*
+
+**S-CORE**
+
+- Static analysis should be executable in multiple contexts, especially local development and CI, without redefining analyzer baselines per context.
+- Different execution contexts can use different subsets or frequencies, but they should all derive from the same shared rules and ownership model.
+- **Biggest gap**: there is no documented execution model that cleanly separates shared analyzer policy from local and CI-specific delivery.
+
+### 5.3.1 Local Execution Expectations
+
+*Defining what static analysis should provide before code reaches CI.*
+
+**S-CORE**
+
+- Contributors should be able to run the shared analyzer baseline early enough to catch common issues before opening or updating a pull request.
+- Local execution should favor fast feedback and alignment with the centrally defined ruleset, while the delivery details for shared environments, editor usage, and pre-commit belong in [chapter 2](02-developer-environment.md).
+- **Biggest gap**: local execution expectations are not yet defined independently of specific tools such as devcontainers, IDEs, or pre-commit hooks.
+
+### 5.3.2 CI Execution Expectations
+
+*Defining what CI should enforce from the shared static-analysis capability.*
+
+**S-CORE**
+
+- CI should execute the agreed shared analyzer baseline in a consistent, review-visible way and use its outcomes for merge decisions where appropriate.
+- The workflow, reporting, and branch-protection mechanics belong in [chapter 7](07-automation-integration.md), not in the code-analysis capability definition itself.
+- **Biggest gap**: CI enforcement expectations are not yet clearly separated from workflow implementation details.
+
+### 5.3.3 Incremental Adoption
+
+*Rolling out stronger analyzer baselines without blocking repository progress all at once.*
+
+**S-CORE**
+
+- A shared analysis strategy should support migration from weak or inconsistent baselines toward stronger common enforcement.
+- **Biggest gap**: there is no documented rollout model for moving repositories from optional analysis toward required shared baselines.
+
+---
+
+## 5.4 Security Scanning 🟠
+
+*Clarifying how code analysis relates to security-oriented scanning of source and repository configuration.*
+
+**S-CORE**
+
+- Code analysis includes both general code-quality checks and security-relevant inspection of source and repository configuration.
+- This chapter is the canonical home for shared tooling, rule configuration, and execution boundaries that are common across analyzer types.
+- **Biggest gap**: the boundary between quality-oriented analyzers and security scanning is not yet described clearly enough to avoid duplication and ownership gaps.
+
+### 5.4.1 SAST 🟠
+
+*Static application security testing for S-CORE code and configuration.*
+
+**S-CORE**
+
+SAST tools analyze source code for security vulnerabilities without executing it. For S-CORE, CodeQL is the primary SAST tool because it integrates natively with GitHub through code scanning alerts, supports C/C++ and Python analysis relevant to the S-CORE language landscape, and can run as a standard GitHub Actions workflow. The infrastructure question is not whether CodeQL works — it does — but how it is configured consistently: which query suites are enabled, what severity thresholds gate a merge, and how results are surfaced to maintainers.
+
+A useful SAST configuration has three layers. The query suite defines which vulnerability patterns to look for — the default security suite covers the most impactful findings, while extended suites add code-quality checks at the cost of more noise. The CI gate defines which findings block merges — typically only high and critical severity — while lower findings appear as alerts for maintainers to triage. The cross-repository alignment defines whether all S-CORE repositories use the same query suite and gate policy or whether repositories can override the baseline.
+
+**Biggest gap**: SAST-specific configuration and required security-gate policies are not yet standardized across repositories. CodeQL query suite selection and severity thresholds vary between repositories.
+
+### 5.4.2 Secret Scanning 🟠
+
+*Detecting secrets inadvertently committed to S-CORE repositories.*
+
+**S-CORE**
+
+- GitHub secret scanning detects common credential patterns in repository history and ongoing changes.
+- **Biggest gap**: custom secret patterns and push-protection configuration are not uniformly enabled.
+
+### 5.4.3 Repository Configuration Security
+
+*Inspecting workflows and repository configuration for risky patterns before they become incidents.*
+
+**S-CORE**
+
+- Infrastructure repositories depend heavily on workflow configuration, permissions, and automation wiring, so configuration-level analysis is a meaningful part of code-analysis security scanning.
+- **Biggest gap**: configuration-oriented security analysis is not yet described as part of a shared S-CORE baseline.
+
+---
+
+## 5.5 Results and Governance ⚪
+
+*Managing findings, conformance visibility, and analyzer evolution across repositories.*
+
+**S-CORE**
+
+- Code-analysis infrastructure should provide visibility into adoption, drift, and findings without forcing every repository to invent its own process.
+- Governance includes rule changes, false-positive handling, technical-debt baselines, and measurement of conformance to shared expectations.
+- **Biggest gap**: no cross-repository reporting and governance loop currently shows which repositories run which analyzers, with what deviations and outcomes.
+
+### 5.5.1 False Positives and Baselines
+
+*Handling existing findings and noisy rules in a controlled way.*
+
+**S-CORE**
+
+- Migration to stronger analyzers often needs temporary baselines or approved suppressions so repositories can improve incrementally.
+- **Biggest gap**: there is no shared approach for introducing analyzers into repositories with existing finding backlogs.
+
+### 5.5.2 Cross-Repository Visibility
+
+*Measuring adoption and conformance of static-analysis standards across S-CORE.*
+
+**S-CORE**
+
+- Cross-repository reporting should show baseline adoption, exceptions, and required-check coverage, not just individual CI job output.
+- **Biggest gap**: no common dashboard or conformance report currently summarizes static-analysis coverage across S-CORE.
\ No newline at end of file
diff --git a/docs/explanation/06-compliance-infrastructure.md b/docs/explanation/06-compliance-infrastructure.md
new file mode 100644
index 0000000..fec77e5
--- /dev/null
+++ b/docs/explanation/06-compliance-infrastructure.md
@@ -0,0 +1,355 @@
+# 6 Compliance & Dependency Analysis ⚪
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+:::{note} Not yet assessed
+All sections in this chapter are marked ⚪ (not yet assessed). The content describes the target architecture and known gaps, not the current state of implementation.
+:::
+
+*Infrastructure for turning repository files, dependency declarations, and build outputs into licensing evidence, SBOMs, and ongoing compliance and vulnerability monitoring across S-CORE.*
+
+The compliance flow has five stages. File-level licensing (§6.1) classifies every file as first-party or third-party. Dependency analysis (§6.2) discovers what each repository consumes and produces enriched SBOMs. SBOM scoping (§6.3) decides which evidence belongs in which SBOM and who receives it. License checks (§6.4) verify that the license profile is acceptable and produce a license-enriched SBOM. Monitoring and governance (§6.5) uses that artifact for ongoing vulnerability detection and compliance oversight.
+
+[Chapter 3](03-build-infrastructure.md) owns generating raw build evidence. [Chapter 7](07-automation-integration.md) owns CI orchestration. [Chapter 8](08-artifact-distribution.md) owns artifact publication. This chapter owns interpreting, enriching, scoping, and checking compliance evidence.
+
+The tooling landscape for this area is still early-stage. [eclipse-score/sbom-tool](https://github.com/eclipse-score/sbom-tool) is a proof-of-concept Bazel rule set that integrates SBOM generation into the build, using dash-license-scan and cdxgen as data sources for license enrichment. It belongs entirely to this chapter: it consumes build outputs as inputs but owns discovery, enrichment, and SBOM generation — all compliance concerns. The remaining gaps are around scope decisions, non-Bazel repositories, monitoring, and governance — which is what this chapter describes.
+
+```{mermaid}
+flowchart TD
+ subgraph s61 ["§ 6.1 File-Level Licensing"]
+ repo_files["Repository files"]
+ file_class["File classification\n(first / third-party)"]
+ repo_files --> file_class
+ end
+
+ subgraph s62 ["§ 6.2 Dependency Analysis"]
+ dep_sources["`Dependency manifests
++ build graphs`"]
+ enriched_sboms["Enriched SBOMs"]
+ dep_sources --> enriched_sboms
+ end
+
+ subgraph s63 ["§ 6.3 SBOM Scoping and Compliance Evidence"]
+ scope{"`Scope decision
+(dev / product)`"}
+ scoped_sboms["Scoped SBOMs"]
+ scope --> scoped_sboms
+ end
+
+ subgraph s64 ["§ 6.4 License Checks and Compliance"]
+ license_check["License checking\n(Dash / IP review)"]
+ license_sbom["License-enriched SBOM"]
+ license_check --> license_sbom
+ end
+
+ subgraph s65 ["§ 6.5 Monitoring and Governance"]
+ monitoring["Vulnerability monitoring"]
+ governance["Findings & coverage"]
+ end
+
+ file_class --> scope
+ enriched_sboms --> scope
+ scoped_sboms --> license_check
+ license_sbom --> monitoring
+ license_sbom --> governance
+ monitoring --> governance
+
+ classDef artifact fill:#E3F2FD,stroke:#1E88E5,color:#0D47A1
+ classDef action fill:#E8F5E9,stroke:#43A047,color:#1B5E20
+ classDef decision fill:#FFF3E0,stroke:#FB8C00,color:#E65100
+ classDef outcome fill:#F3E5F5,stroke:#8E24AA,color:#4A148C
+
+ class repo_files,dep_sources,file_class,enriched_sboms,scoped_sboms,license_sbom artifact
+ class scope decision
+ class license_check,monitoring action
+ class governance outcome
+```
+
+## 6.1 File-Level Licensing ⚪
+
+*Classifying repository files as first-party or third-party and attaching machine-readable licensing metadata.*
+
+```{mermaid}
+flowchart LR
+ file["Repository files"]
+ header_ok{"`Supports
+inline header?`"}
+ header["`Copyright + SPDX
+header`"]
+ sidecar[".license sidecar"]
+ owner{"`Copyright holder
+= S-CORE?`"}
+ first["First-party"]
+ third["Third-party"]
+ out["`File classification
+→ §6.3`"]
+
+ file --> header_ok
+ header_ok -->|Yes| header
+ header_ok -->|No| sidecar
+ header --> owner
+ sidecar --> owner
+ owner -->|Yes| first
+ owner -->|No| third
+ first --> out
+ third --> out
+
+ classDef artifact fill:#E3F2FD,stroke:#1E88E5,color:#0D47A1
+ classDef action fill:#E8F5E9,stroke:#43A047,color:#1B5E20
+ classDef decision fill:#FFF3E0,stroke:#FB8C00,color:#E65100
+ classDef context fill:#F5F5F5,stroke:#BDBDBD,color:#757575
+
+ class file,first,third artifact
+ class header,sidecar action
+ class header_ok,owner decision
+ class out context
+```
+
+### 6.1.1 Metadata Model
+
+*How files carry their licensing information and how first-party content is distinguished from third-party content.*
+
+Every file needs machine-readable licensing metadata in one of two forms: a copyright notice and SPDX license identifier in the file header, or a sidecar `.license` file for formats that cannot carry inline headers. This metadata is what allows tooling to distinguish first-party S-CORE material from third-party imports. Third-party files need to stay visible as externally sourced so they reach later license-compliance steps.
+
+**Biggest gap**: file-level licensing metadata and first-party versus third-party classification are not yet enforced consistently across repositories.
+
+### 6.1.2 Enforcement
+
+*Automated enforcement of file-level licensing metadata through local hooks and CI checks.*
+
+Consistent metadata requires two enforcement layers: a pre-commit hook that auto-adds the correct header to new first-party files, and a CI check that verifies all files carry required metadata. Both should share the same configuration so local and remote enforcement agree. REUSE-style validation is the likely long-term consolidation point. Copyright tooling from [eclipse-score/tooling](https://github.com/eclipse-score/tooling) currently provides a pre-commit hook and PR check.
+
+**Biggest gap**: enforcement coverage is inconsistent across repositories, and the boundary between current header tooling and REUSE-based validation is not yet resolved.
+
+## 6.2 Dependency Analysis ⚪
+
+*Discovering what a repository consumes and producing enriched SBOM-format outputs.*
+
+This path requires three distinct capabilities: dependency discovery, license enrichment, and SBOM-format output. In Bazel-based repositories, [eclipse-score/sbom-tool](https://github.com/eclipse-score/sbom-tool) already integrates all three as a Bazel rule. It uses the Bazel module graph and aspects for discovery, dash-license-scan for Rust license data, cdxgen for C++ license data, and produces SPDX 2.3 / CycloneDX 1.6 output — so these tools are data sources within one orchestrated build step, not competing alternatives.
+
+```{mermaid}
+flowchart LR
+ subgraph inputs ["Build inputs"]
+ direction TB
+ lockfiles["Lock files"]
+ modulegraph["`Bazel module graph
++ aspects`"]
+ manual["`Manual
+declarations`"]
+ end
+
+ subgraph enrichment ["License data sources"]
+ direction TB
+ dash["`dash-license-scan
+(Rust)`"]
+ cdxgen["`cdxgen
+(C++)`"]
+ end
+
+ sbom_tool["`SBOM generator
+(sbom-tool)`"]
+ sbom_output["`SPDX 2.3
+CycloneDX 1.6`"]
+ out["`Enriched SBOMs
+→ §6.3`"]
+
+ inputs --> sbom_tool
+ enrichment --> sbom_tool
+ sbom_tool --> sbom_output --> out
+
+ classDef artifact fill:#E3F2FD,stroke:#1E88E5,color:#0D47A1
+ classDef action fill:#E8F5E9,stroke:#43A047,color:#1B5E20
+ classDef transparent fill:none,stroke:#ccc
+ classDef context fill:#F5F5F5,stroke:#BDBDBD,color:#757575
+
+ class lockfiles,modulegraph,manual,sbom_output artifact
+ class dash,cdxgen,sbom_tool action
+ class inputs,enrichment transparent
+ class out context
+```
+
+### 6.2.1 Discovery and Enrichment
+
+*Collecting dependency information from multiple sources and mapping it to license status.*
+
+For Bazel-based repositories, [sbom-tool](https://github.com/eclipse-score/sbom-tool) already combines these sources: the Bazel module graph provides structural dependency data, lock files provide version and checksum data, dash-license-scan enriches Rust crate licenses via the Eclipse Dash License Tool, and cdxgen scans C++ dependencies. Manual declarations cover vendored content and transitive relationships that automated sources miss. The result is a merged, enriched SBOM produced as a normal build output.
+
+For non-Bazel repositories, no equivalent integration exists yet. The same capabilities are needed — discovery, enrichment, output — but the tooling path is undefined.
+
+**Biggest gap**: sbom-tool covers Bazel-based repositories as a proof of concept, but the flow is not yet consistently available across all repository types. Coverage for non-Bazel repositories and for C++ license enrichment (where dash-license-scan does not yet work) remains open.
+
+## 6.3 SBOM Scoping and Compliance Evidence ⚪
+
+*Deciding what belongs in which SBOM and who consumes the resulting compliance evidence.*
+
+This is where the two input paths converge. One repository does not produce one SBOM — it produces inputs to a scope decision that determines which evidence goes where and to whom.
+
+```{mermaid}
+flowchart TD
+ in61["`File classification
+← §6.1`"]
+ in62["`Enriched SBOMs
+← §6.2`"]
+
+ scope{"`Scope
+decision`"}
+
+ dev_sbom["`Development SBOM
+(build scope)`"]
+ prod_sbom["`Product SBOM
+(runtime scope)`"]
+
+ license_checks["`License checks
+→ §6.4`"]
+ distributor_source["`Distributor: source
+release scan`"]
+ distributor_runtime["`Distributor: runtime
+image scan`"]
+
+ in61 --> scope
+ in62 --> scope
+ scope --> dev_sbom
+ scope --> prod_sbom
+
+ dev_sbom --> license_checks
+ prod_sbom --> license_checks
+ prod_sbom --> distributor_source
+ prod_sbom --> distributor_runtime
+
+ classDef artifact fill:#E3F2FD,stroke:#1E88E5,color:#0D47A1
+ classDef decision fill:#FFF3E0,stroke:#FB8C00,color:#E65100
+ classDef consumer fill:#F3E5F5,stroke:#8E24AA,color:#4A148C
+ classDef context fill:#F5F5F5,stroke:#BDBDBD,color:#757575
+
+ class dev_sbom,prod_sbom artifact
+ class scope decision
+ class distributor_source,distributor_runtime consumer
+ class in61,in62,license_checks context
+```
+
+### 6.3.1 Development vs Product Scope
+
+*Distinguishing between build-scope and runtime-scope compliance evidence.*
+
+Some dependencies belong only to building, testing, or the development environment. Others are part of the delivered runtime product. That distinction changes which SBOM is produced, how findings are interpreted, and which consumers care. The same scope model applies to S-CORE's tooling and environment artifacts such as devcontainers — [chapter 3](03-build-infrastructure.md#tooling-environment-sboms-license-evidence) describes how they produce build evidence; this chapter owns the scope decision.
+
+**Biggest gap**: no shared definition yet of which inputs belong in development-scope versus product-scope SBOMs.
+
+### 6.3.2 Compliance Consumers
+
+*Who uses the scoped evidence and for what purpose.*
+
+Scoped SBOMs serve two immediate audiences before feeding downstream. Internally, they are the input to §6.4 License Checks and Compliance. For downstream distributors, they support OSS scans whose scope varies by deliverable type: a source release, a runtime image, and a redistributed tool are different scan targets with different questions. Vulnerability monitoring (§6.5) sits downstream of §6.4 and receives the license-enriched SBOM, not the scoped SBOM directly.
+
+**Biggest gap**: no shared model defines which deliverable is the scan target in each compliance situation.
+
+## 6.4 License Checks and Compliance ⚪
+
+*Verifying that dependencies meet S-CORE's license policy and producing a license-enriched SBOM as output.*
+
+Scoped SBOMs from §6.3 carry dependency metadata but license status may still be unresolved or incomplete. This section runs the actual license checks — automated via Dash and manual via IP review — and resolves those gaps. The result is a **license-enriched SBOM** with verified license status for every component. That artifact is what §6.5 uses for vulnerability monitoring and governance; it is a richer input than the scoped SBOM from §6.3.
+
+```{mermaid}
+flowchart LR
+ in63["`Scoped SBOMs
+← §6.3`"]
+
+ pr_check["`PR-scoped
+check`"]
+ ip_review["`IP review &
+policy`"]
+
+ license_sbom["`License-enriched
+SBOM → §6.5`"]
+
+ in63 --> pr_check
+ in63 --> ip_review
+ pr_check --> license_sbom
+ ip_review --> license_sbom
+
+ classDef artifact fill:#E3F2FD,stroke:#1E88E5,color:#0D47A1
+ classDef action fill:#E8F5E9,stroke:#43A047,color:#1B5E20
+ classDef context fill:#F5F5F5,stroke:#BDBDBD,color:#757575
+
+ class license_sbom artifact
+ class pr_check,ip_review action
+ class in63 context
+```
+
+### 6.4.1 PR-Scoped License Checking
+
+*Checking dependency license status as part of the contribution workflow without creating noise.*
+
+Full-repository license scans on every PR produce too much noise. The effective model is scoped checking: run only when dependency changes are detected, surface results only when new license questions arise. This pattern matters regardless of which tool implements it — the check should be scoped to changes, produce structured output, and integrate into PR review.
+
+**Biggest gap**: PR-scoped dependency license checking is not consistently available across repositories.
+
+### 6.4.2 IP Review and Project Policy
+
+*Routing license findings that require human review and maintaining a shared policy for accepted and rejected licenses.*
+
+Automated checks resolve most license questions, but some dependencies require IP review. The project also needs a shared license policy — allowlists for accepted licenses and a clear escalation path for non-standard situations. That policy should be machine-readable enough to feed back into automated checks rather than living only in documents.
+
+**Biggest gap**: no shared license policy or allowlist is defined at the S-CORE level; individual repositories handle license decisions ad hoc.
+
+## 6.5 Monitoring and Governance ⚪
+
+*Continuous vulnerability monitoring, findings ownership, and cross-repository compliance visibility.*
+
+The compliance flow becomes useful infrastructure only when SBOMs stay fresh, findings can be owned, and coverage gaps stay visible.
+
+```{mermaid}
+flowchart TD
+ in64["`License-enriched SBOM
+← §6.4`"]
+
+ upload["`Upload to GitHub
+/ Dependency-Track`"]
+ vuln["Vulnerability findings"]
+
+ ownership["Findings ownership"]
+ baselines["Baselines & exceptions"]
+ visibility["Cross-repo coverage visibility"]
+
+ in64 --> upload --> vuln
+ vuln --> ownership
+ vuln --> baselines
+ ownership --> visibility
+ baselines --> visibility
+
+ classDef artifact fill:#E3F2FD,stroke:#1E88E5,color:#0D47A1
+ classDef action fill:#E8F5E9,stroke:#43A047,color:#1B5E20
+ classDef outcome fill:#F3E5F5,stroke:#8E24AA,color:#4A148C
+ classDef context fill:#F5F5F5,stroke:#BDBDBD,color:#757575
+
+ class vuln artifact
+ class upload action
+ class ownership,baselines,visibility outcome
+ class in64 context
+```
+
+### 6.5.1 Continuous Vulnerability Monitoring
+
+*Using license-enriched SBOMs as ongoing monitoring inputs to detect newly relevant issues over time.*
+
+Uploading SBOMs to systems such as GitHub and Dependency-Track allows the project to detect vulnerabilities after the initial build. sbom-tool already includes an SPDX-to-GitHub-snapshot converter for this purpose, though it is not yet integrated into a cross-repository upload flow. Monitoring is also the basis for impact analysis — mapping a newly disclosed vulnerability back to affected artifact versions and repository owners. This only works if uploads stay fresh; a stale SBOM gives a false sense of coverage.
+
+**Biggest gap**: no shared process keeps SBOM uploads fresh or supports impact analysis across S-CORE artifact types.
+
+### 6.5.2 Findings Ownership and Baselines
+
+*Clarifying who owns compliance findings and how existing debt is handled.*
+
+Findings come from different parts of the flow, so ownership cannot default to one team. A missing header belongs to a repository maintainer; a broken enrichment step belongs to tooling owners; a vulnerability in a distributed artifact belongs to whoever publishes it. Not every issue can be fixed immediately — temporary baselines are acceptable as long as exceptions remain visible, justified, and reviewable.
+
+**Biggest gap**: no documented ownership model connects findings to the responsible step in the compliance pipeline, and no shared policy defines how exceptions are justified, recorded, and revisited.
+
+### 6.5.3 Cross-Repository Visibility
+
+*Measuring how completely the compliance flow is implemented across repositories.*
+
+Visibility should show not just current findings but also coverage: which repositories classify files, which produce scoped SBOMs, which upload to monitoring, and where enrichment is still missing.
+
+**Biggest gap**: no conformance report shows how completely the compliance flow is implemented across S-CORE.
\ No newline at end of file
diff --git a/docs/explanation/07-automation-integration.md b/docs/explanation/07-automation-integration.md
new file mode 100644
index 0000000..31f8c75
--- /dev/null
+++ b/docs/explanation/07-automation-integration.md
@@ -0,0 +1,282 @@
+# 7 Automation Infrastructure & Continuous Integration (CI) ⚪
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure integrating code changes safely across S-CORE repositories through automated workflows and quality gates.*
+
+:::{warning} Draft
+This chapter has not been fully reviewed. Content may be incomplete or inaccurate.
+:::
+
+**S-CORE**
+
+GitHub Actions is the CI/CD platform for S-CORE. Workflows are triggered on pull requests, merges, schedules, and releases. Reusable workflows shared across repositories reduce duplication and enforce consistent pipeline structure. Pipeline execution relies on both GitHub-hosted cloud runners and hardware-oriented execution environments. This chapter owns workflow orchestration and gate delivery, including cases where CI reuses the shared contributor environment from [chapter 2](02-developer-environment.md), not the technical baselines defined in [chapter 3](03-build-infrastructure.md), [chapter 4](04-testing-infrastructure.md), [chapter 5](05-static-analysis-infrastructure.md), and [chapter 6](06-compliance-infrastructure.md).
+
+Because GitHub Actions is a managed platform, its constraints shape what workflows can and cannot do. The most consequential constraints include: workflow storage quotas that limit how much artifact data a repository can retain across runs, concurrency limits that determine how many jobs can run in parallel per organization, runner disk space that constrains large Bazel builds and Docker-in-Docker workloads, the split between `GITHUB_TOKEN` and fine-grained PAT permissions that affects cross-repository access, and the inability to share mutable state between jobs except through artifacts or caches. For self-hosted runners, additional constraints include node pool sizing, network access to internal resources, and the security implications of running untrusted pull-request code on persistent infrastructure. Established patterns that work well in S-CORE include using composite actions for Bazel setup and teardown, restricting `workflow_dispatch` and `pull_request_target` triggers to workflows that explicitly need elevated permissions, and using reusable workflows rather than copying common steps between repositories.
+
+**Biggest gap**: reusable workflow coverage and quality gate consistency across S-CORE repositories are incomplete. GitHub Actions platform constraints and S-CORE-specific best practices are not documented in one place.
+
+```{mermaid}
+graph TD
+ pr["Pull request / push"]
+ schedule["Schedule / release trigger"]
+
+ subgraph shared["Shared workflow libraries"]
+ cwf["`cicd-workflows
+on-pr.yml · daily.yml`"]
+ cac["`cicd-actions
+(composite actions)`"]
+ end
+
+ subgraph runners["Runners"]
+ cloud["`GitHub-hosted
+(cloud: x86, ARM, KVM)`"]
+ hw["`Self-hosted
+(hardware: RPi, automotive SoC)`"]
+ end
+
+ pr --> cwf
+ schedule --> cwf
+ cwf --> cac
+ cac --> cloud
+ cac --> hw
+ cloud --> results["`Status checks
+Artifacts / evidence`"]
+ hw --> results
+ results -->|"required checks via otterdog"| pr
+```
+
+## 7.1 Runners 🟠
+
+*Execution infrastructure used by S-CORE CI pipelines.*
+
+**S-CORE**
+
+- Pipeline execution relies on GitHub-hosted cloud runners and dedicated hardware test runners.
+- **Biggest gap**: hardware runner availability and reliability remain a bottleneck for integration pipelines.
+
+### 7.1.1 SW Test Runners 🟡
+
+*GitHub-hosted runners providing execution environments for CI pipelines.*
+
+**S-CORE**
+
+- Cloud runners cover ARM, x86, and QEMU (with KVM) architectures with autoscaling to match pipeline demand.
+- **Biggest gap**: runner capacity constraints under peak load are not yet fully mitigated.
+
+### 7.1.2 Hardware Test Runners 🔴
+
+*Execution environments for hardware-based testing in S-CORE CI pipelines.*
+
+**S-CORE**
+
+Hardware test runners differ from cloud runners in almost every dimension. A cloud runner is an ephemeral VM that executes a job and disappears; a hardware runner is a persistent physical device — an embedded board, an automotive-grade SoC, or a development kit — that must be provisioned, maintained, and shared across pipelines. The infrastructure challenge is not just making hardware available, but making it usable as a CI execution target with the same trigger-run-report model that cloud runners already provide.
+
+The practical need in S-CORE comes from two directions. Cross-compiled test execution ([section 4.3](04-testing-infrastructure.md#test-execution-dynamic-analysis)) needs a way to run `cc_test` and `rust_test` binaries built for non-host platforms such as QNX on an actual target or a representative emulator. Performance and benchmark testing ([section 4.3.4](04-testing-infrastructure.md#performance-benchmark-testing)) needs to measure timing, throughput, and resource consumption on real hardware where host-based emulation cannot reproduce the actual behavior. Both depend on the same underlying provisioning model.
+
+The target hardware landscape currently includes single-board computers such as Raspberry Pi for lightweight integration and smoke testing, and automotive-grade SoCs such as the Qualcomm SA8650P for representative performance measurement and platform-level validation. Each class brings different constraints: single-board computers are cheap and easy to provision but limited in compute; automotive SoCs are representative but expensive, scarce, and often require vendor-specific BSPs and boot infrastructure. A viable hardware runner model must account for both ends of that spectrum.
+
+The infrastructure layers that need to exist are: physical device management and health monitoring, a deployment mechanism that flashes or transfers test binaries and their dependencies to the target, a remote execution model that triggers test runs and collects results back into the CI pipeline, and an isolation strategy that prevents concurrent jobs from interfering with each other on shared devices. For GitHub Actions integration, this typically means self-hosted runners attached to specific device classes, with job routing based on labels that encode the target platform and availability.
+
+**Biggest gap**: S-CORE has no documented hardware runner provisioning model, no deployment and result collection pipeline for embedded targets, and no device management or scheduling infrastructure. Hardware test execution is currently ad hoc rather than a reproducible CI capability.
+
+### 7.1.3 Execution Isolation & Trust Boundaries
+
+*Separating jobs and credentials appropriately across runner classes and workflow contexts.*
+
+**S-CORE**
+
+- CI execution environments should make trust boundaries explicit, especially when different jobs handle external contributions, internal credentials, or hardware access.
+- **Biggest gap**: there is no clearly documented execution trust model across the different runner types used in S-CORE workflows.
+
+## 7.2 Reusable Workflows ⚪
+
+*Shared GitHub Actions workflows reused across S-CORE repositories.*
+
+**S-CORE**
+
+Reusable workflows are maintained in [eclipse-score/cicd-workflows](https://github.com/eclipse-score/cicd-workflows) and reusable composite actions in [eclipse-score/cicd-actions](https://github.com/eclipse-score/cicd-actions). Module repositories call these shared workflows to standardize build, test, analysis, documentation, and release steps. Two meta-workflows compose the individual checks into standard pipeline shapes: `on-pr.yml` for pull-request checks and `daily.yml` for scheduled maintenance. Required status checks are configured centrally via [otterdog](https://otterdog.readthedocs.io/en/latest/userguide/) in the [S-CORE configuration](https://github.com/eclipse-score/.eclipsefdn/blob/main/otterdog/eclipse-score.jsonnet).
+
+When workflow consistency benefits from reusing the shared local environment described in [chapter 2](02-developer-environment.md), the workflow layer is still responsible for how that environment is invoked and gated.
+
+**Biggest gap**: reusable workflow coverage is partial and quality gate definitions are not yet consistently enforced via shared workflows.
+
+### 7.2.1 Workflow Library Coverage
+
+*Completeness of centrally maintained reusable workflows for common CI patterns.*
+
+**S-CORE**
+
+The [cicd-workflows](https://github.com/eclipse-score/cicd-workflows) library already covers a broad set of pipeline patterns: build and test, formatting, copyright enforcement, lock file verification, documentation build and verification, static analysis, CodeQL security scanning, dependency license checking, C++ and Rust coverage, QNX cross-compilation, and template synchronization. The [cicd-actions](https://github.com/eclipse-score/cicd-actions) repository complements this with composite actions for cross-repository token provisioning and QNX SDP setup.
+
+**Biggest gap**: the workflow library is substantial, but adoption is not yet universal. Some repositories still use local workflow copies instead of the shared library, and the full set of quality gates is not uniformly applied across all repository classes.
+
+### 7.2.2 Build Validation
+
+*Ensuring builds succeed before code is merged, using standardized workflow building blocks.*
+
+**S-CORE**
+
+- Build success is a required check for merges in S-CORE repositories via branch protection configuration.
+- **Biggest gap**: build validation implementation details still vary by repository maturity.
+
+Where repositories use dependency lock files, the CI perspective should be enforcement rather than regeneration: workflows should verify that committed files such as `MODULE.bazel.lock` and `uv.lock` are already up to date instead of silently rewriting them during the run.
+
+### 7.2.3 Test Validation
+
+*Ensuring tests pass before code is merged, with reusable test workflow patterns.*
+
+**S-CORE**
+
+- Test results gate merges in repositories where test pipelines are set up.
+- **Biggest gap**: test gate coverage remains incomplete across S-CORE repositories.
+
+### 7.2.4 Analysis Enforcement
+
+*Executing shared code-analysis and dependency-analysis checks as reusable CI workflow steps and merge gates.*
+
+**S-CORE**
+
+- CI consumes the shared analysis capabilities described in [chapter 5](05-static-analysis-infrastructure.md) and [chapter 6](06-compliance-infrastructure.md) and turns them into workflow runs, status checks, and review-visible results.
+- Reusable workflows should encapsulate execution and reporting so repositories do not reimplement the same enforcement mechanics.
+- **Biggest gap**: reusable workflow coverage and required-check policy for analysis gates are not yet consistently applied across repositories.
+
+### 7.2.5 Documentation & Release Workflows
+
+*Supporting documentation publishing and release automation through shared pipeline building blocks.*
+
+**S-CORE**
+
+- Shared workflow infrastructure should cover more than compile-and-test paths.
+- **Biggest gap**: non-build workflow patterns are not yet captured in one clearly reusable automation baseline.
+
+---
+
+## 7.3 Cross-Repository Integration ⚪
+
+*Validating integration scenarios across S-CORE components in CI beyond single-repository scope.*
+
+**S-CORE**
+
+- Cross-repository integration validation is a target capability; most repositories currently validate in isolation.
+- The integration environment itself belongs primarily to [chapter 4](04-testing-infrastructure.md); this chapter covers how CI orchestrates and gates it.
+- **Biggest gap**: no shared integration validation pipeline spans multiple S-CORE middleware components.
+
+### 7.3.1 Integration Validation Scope
+
+*Defining which component combinations and dependency chains are validated together.*
+
+**S-CORE**
+
+- Integration coverage is currently limited and often project-specific instead of project-wide.
+- **Biggest gap**: no agreed minimum integration matrix is defined for S-CORE.
+
+### 7.3.2 Integration Pipeline Orchestration
+
+*Coordinating multi-repository builds and tests as one automated CI flow.*
+
+**S-CORE**
+
+- Multi-repository orchestration is a target capability and not yet standardized.
+- CI should be able to trigger shared environments such as `reference_integration`, pass the relevant module versions or revisions into them, and collect the resulting evidence.
+- **Biggest gap**: trigger, artifact handover, and result aggregation patterns are not yet unified.
+
+### 7.3.3 Artifact & Evidence Handover
+
+*Passing build outputs, metadata, and test evidence safely between stages or repositories in one CI flow.*
+
+**S-CORE**
+
+- Cross-repository automation needs more than triggers; it also needs a repeatable way to hand off artifacts, SBOMs, and verification evidence between jobs or repositories.
+- That handover may include the `known_good` manifest or identifier, module references resolved through `bazel_registry`, release assets, and the test outputs produced by `reference_integration`.
+- **Biggest gap**: no shared artifact handover model exists for multi-repository automation scenarios.
+
+### 7.3.4 Known-Good Promotion
+
+*Using `reference_integration` to validate and promote integrated module sets in CI.*
+
+**S-CORE**
+
+`known_good` gives CI a stable unit of promotion. Module repositories can continue to publish releases, registry entries, or candidate revisions independently, but cross-repository automation needs one place where those inputs are assembled into a candidate stack, executed together, and either promoted or rejected with clear feedback. The important nuance is that CI does not treat `known_good` as a byproduct of Bazel resolution. It treats it as the higher-level control file that selects the candidate stack and can also carry automation metadata such as which branch should be followed for automatic updates.
+
+Assuming the still-undecided Option 2 direction currently under discussion, `reference_integration` would own that promotion gate. For a pull request in one repository, CI would build a candidate manifest from the changed repository ref together with the last known-good refs for the other participating repositories, generate the Bazel-facing inputs needed for the integrated workspace from that manifest, and run the fast integration subset for early feedback. After merges, or on a schedule, `reference_integration` would build a fuller manifest from the latest eligible branches, run the deeper suite, and only on success update the stored `known_good` record. If the final scope of `reference_integration` is narrowed later, the same promotion pattern still makes sense, but the meaning of `known_good` must be reduced to the checks that are actually re-executed centrally.
+
+That also gives the handover model a natural key: artifacts, SBOMs, reports, and logs should be traceable to the `known_good` identifier or manifest hash they were produced for rather than only to an individual repository run. **Biggest gap**: S-CORE has no standardized candidate-manifest construction, `known_good` promotion workflow, ownership model, or result schema for cross-repository CI.
+
+The workflow shape described here follows the distributed-monolith integration model in [DR-002-Infra](https://eclipse-score.github.io/score/main/design_decisions/DR-002-infra.html), while the stronger central ownership assumed in some sentences still depends on the unresolved Option 2 versus lighter-scope discussion in [DR-008-Int](https://github.com/qorix-group/score/blob/da4ea900f1eece5c8e795697d71e277446dca84e/docs/design_decisions/DR-008-int.rst?plain=1).
+
+## 7.4 Secrets Management ⚪
+
+*Protecting credentials and establishing least-privilege access for CI workflows and runners.*
+
+**S-CORE**
+
+- CI workflows rely on repository, organization, and environment secrets for accessing external systems.
+- OIDC-based short-lived credentials are the preferred pattern where supported, reducing long-lived static secrets.
+- **Biggest gap**: centralized secret inventory, rotation policy enforcement, and usage audits are not yet consistently implemented.
+
+### 7.4.1 Secret Scope and Rotation
+
+*Managing where secrets are stored and how frequently they are rotated.*
+
+**S-CORE**
+
+- Secret scoping follows GitHub constructs (repository, organization, environment), but conventions differ between repositories.
+- **Biggest gap**: no uniform rotation cadence and ownership model is enforced across all CI secrets.
+
+### 7.4.2 Federated Identity (OIDC)
+
+*Replacing static credentials with short-lived identity federation for CI jobs.*
+
+**S-CORE**
+
+- OIDC adoption is progressing for cloud access use cases where providers support federated trust.
+- **Biggest gap**: OIDC usage is not yet standardized across all repositories and target environments.
+
+### 7.4.3 Workflow Permissions
+
+*Defining the minimum permissions automation jobs need in order to operate safely.*
+
+**S-CORE**
+
+- GitHub workflow permissions, token scopes, and environment protections are part of automation infrastructure, not just repository-level policy trivia.
+- **Biggest gap**: no shared least-privilege baseline governs permissions across S-CORE workflows.
+
+## 7.5 CI Observability ⚪
+
+*Monitoring CI health, performance, and reliability to improve developer feedback loops.*
+
+**S-CORE**
+
+- CI observability relies on GitHub Actions logs, job outcomes, and repository status checks.
+- Key indicators include queue times, job durations, failure rate, and flaky test behavior.
+- **Biggest gap**: no shared observability baseline or dashboard is used consistently across S-CORE repositories.
+
+### 7.5.1 Pipeline Health Metrics
+
+*Tracking execution and quality signals to detect bottlenecks and reliability issues early.*
+
+**S-CORE**
+
+- Pipeline metrics exist in native tooling but are not yet normalized into common S-CORE KPIs.
+- **Biggest gap**: threshold definitions and trend tracking are not centrally aligned.
+
+### 7.5.2 Alerting and Incident Response
+
+*Reacting quickly to CI outages, widespread failures, or degraded feedback latency.*
+
+**S-CORE**
+
+- Notification and incident handling practices exist but differ between repositories and teams.
+- **Biggest gap**: no standard CI incident playbook with shared escalation paths is applied project-wide.
+
+### 7.5.3 Flakiness & Feedback Quality
+
+*Improving trust in CI by detecting unstable jobs and reducing noisy feedback.*
+
+**S-CORE**
+
+- Developers lose trust in automation when failures are noisy, nondeterministic, or slow to diagnose.
+- **Biggest gap**: no shared mechanism identifies unstable CI checks and turns them into actionable infrastructure work.
\ No newline at end of file
diff --git a/docs/explanation/08-artifact-distribution.md b/docs/explanation/08-artifact-distribution.md
new file mode 100644
index 0000000..7351d2e
--- /dev/null
+++ b/docs/explanation/08-artifact-distribution.md
@@ -0,0 +1,261 @@
+# 8 Release & Distribution ⚪
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure managing released deliverables, versioning, publication, and consumer access across S-CORE.*
+
+:::{warning} Draft
+This chapter has not been fully reviewed. Content may be incomplete or inaccurate.
+:::
+
+**S-CORE**
+
+- GitHub Releases is the primary mechanism for publishing archive-style S-CORE deliverables, while Bazel modules are published through the shared registry at [eclipse-score/bazel_registry](https://github.com/eclipse-score/bazel_registry/).
+- S-CORE delivery can include source releases, prebuilt artifacts, container images, and associated release metadata.
+- The registry UI at [eclipse-score.github.io/bazel_registry_ui](https://eclipse-score.github.io/bazel_registry_ui/) is the intended discovery surface for published Bazel modules.
+- Artifact versioning follows semantic versioning aligned with Git tagging.
+- SBOM and provenance data should be generated during builds and accompany released deliverables.
+- This chapter covers publishing that evidence with releases, while [chapter 6](06-compliance-infrastructure.md) is the canonical home for how SBOMs are scoped, interpreted, and monitored once they exist.
+
+```{mermaid}
+graph LR
+ code["Module repository\n(source + tests)"]
+ tag["Git tag\n(v1.2.3)"]
+ release["GitHub Release\n(source archive + assets)"]
+ registry["`eclipse-score/bazel_registry\n(registry entry)`"]
+ ui["`Registry UI\nbazel_registry_ui`"]
+ consumer["Consumer MODULE.bazel\nbazel_dep(name, version)"]
+
+ code -->|"git tag + push"| tag
+ tag -->|"GitHub Release workflow"| release
+ release -->|"PR to add registry entry"| registry
+ registry --> ui
+ registry -->|"resolved via .bazelrc"| consumer
+```
+
+## 8.1 Deliverable Types ⚪
+
+*Infrastructure defining which kinds of release deliverables S-CORE can publish and support.*
+
+**S-CORE**
+
+- S-CORE repositories may need to publish different deliverable types depending on consumer needs, including source archives, prebuilt packages, and container images.
+- The infrastructure should support describing, versioning, and publishing these deliverables consistently across repositories.
+- **Biggest gap**: no shared capability model defines which deliverable types exist in S-CORE, how they differ, or what infrastructure each type requires.
+
+### 8.1.1 Source Deliverables
+
+*Delivery of source-based release artifacts intended for downstream build or inspection.*
+
+**S-CORE**
+
+- Source delivery can include tagged source archives and related release metadata published from version control.
+- GitHub Releases can act as a distribution point for source-based deliverables.
+- **Biggest gap**: no shared definition exists for which source deliverables are expected, how complete they must be, or which metadata must always accompany them.
+
+### 8.1.2 Prebuilt Deliverables
+
+*Delivery of compiled or otherwise pre-generated artifacts for direct downstream consumption.*
+
+**S-CORE**
+
+- Prebuilt deliverables can include binaries, archives, packages, generated SDK assets, or other installable outputs attached to a release.
+- GitHub Releases currently provides the most obvious publication mechanism for such assets.
+- **Biggest gap**: no common publication pattern defines which prebuilt deliverables should be release-grade, how they are structured, or how consumers discover them.
+
+### 8.1.3 Image Deliverables
+
+*Delivery of container or VM-style images intended for execution or integration environments.*
+
+**S-CORE**
+
+- Some S-CORE use cases may require deliverables in image form, such as container images for tooling, CI, or runtime integration.
+- Image-based delivery differs from archive-style release assets and usually requires registry-oriented publication and lifecycle handling.
+- **Biggest gap**: no image delivery channel, registry strategy, or publication standard is currently defined for S-CORE.
+
+## 8.2 Distribution Channels ⚪
+
+*Infrastructure publishing release deliverables to downstream consumers through appropriate channels.*
+
+**S-CORE**
+
+- GitHub Releases is currently the primary public distribution channel for archive-style S-CORE deliverables.
+- The shared Bazel registry is the public distribution channel for S-CORE Bazel modules.
+- Different deliverable types may require different channels, such as release assets, registries, or mirrored repositories.
+- **Biggest gap**: no shared distribution model maps deliverable types to supported publication channels and consumer access patterns.
+
+### 8.2.1 Release Publishing
+
+*Publishing release deliverables through release-oriented channels such as GitHub Releases.*
+
+**S-CORE**
+
+- Release pipelines can publish deliverables as GitHub Releases and attach binaries, source bundles, checksums, SBOMs, and related files.
+- This channel is suitable for archive-style release deliverables and public release notes.
+- **Biggest gap**: release publication is not yet standardized across repositories, and release composition is not consistently defined.
+
+### 8.2.2 Registry-Based Distribution
+
+*Publishing deliverables through registries such as package repositories or OCI registries.*
+
+**S-CORE**
+
+This subsection is the main description of how S-CORE publishes and consumes Bazel modules. Other chapters reference it from their own perspective, but the end-to-end registry flow belongs here.
+
+For S-CORE Bazel modules, the custom registry is the release channel that matters. GitHub Releases are still useful for archives, binaries, checksums, and release notes, but Bazel itself consumes module metadata from the shared registry at [eclipse-score/bazel_registry](https://github.com/eclipse-score/bazel_registry/). In other words, if a module version should be usable as a dependency by another S-CORE repository, it needs to be present in the registry.
+
+In S-CORE, the registry and GitHub Releases are deliberately coupled. The useful mental model is that the registry is Bazel's view of a released module version. A maintainer creates a GitHub release in the module repository, the registry imports that release as described in the [registry README](https://github.com/eclipse-score/bazel_registry/blob/main/README.md), and downstream repositories then resolve that version through Bazel. That coupling is why the split between "release" and "dependency resolution" can feel artificial: conceptually it is one publication pipeline, even though different infrastructure chapters look at it from different angles.
+
+This also means module maintainers publish their modules by making a proper repository release and then adding the corresponding version to the registry, rather than inventing a repository-specific distribution pattern. The exact mechanics belong in the [registry README](https://github.com/eclipse-score/bazel_registry/blob/main/README.md), which should remain the maintained source of truth. This infrastructure guide explains the role of the registry and the end-to-end flow, but it deliberately avoids copying the details so that the workflow stays defined in one place.
+
+For module users, the easiest entry point is the registry UI at [eclipse-score.github.io/bazel_registry_ui](https://eclipse-score.github.io/bazel_registry_ui/). It provides a browseable view of the modules and versions published in the registry and is backed by the data in [eclipse-score/bazel_registry_ui](https://github.com/eclipse-score/bazel_registry_ui). If there is ever any doubt, the registry repository itself remains authoritative because it is the actual input to Bazel.
+
+The end-to-end flow is therefore simple. A module maintainer cuts a GitHub release in the module repository. The registry records that released version and the metadata Bazel needs to fetch it. Module users discover the version through the registry UI or the registry repository itself. Consumer repositories then resolve that version through `MODULE.bazel` and the registry configuration described in [chapter 3](03-build-infrastructure.md). Infrastructure maintainers, finally, operate the registry, its validation, and the UI as described in [chapter 10](10-infrastructure-operations.md).
+
+This chapter is the best place to understand that overall publication flow. [Chapter 3](03-build-infrastructure.md) covers how consumers point Bazel at the registry, while [chapter 10](10-infrastructure-operations.md) covers how the registry and UI are run as shared services.
+
+Helpful links:
+
+- [S-CORE Bazel registry](https://github.com/eclipse-score/bazel_registry/)
+- [Registry README](https://github.com/eclipse-score/bazel_registry/blob/main/README.md)
+- [Registry UI](https://eclipse-score.github.io/bazel_registry_ui/)
+- [Registry UI repository](https://github.com/eclipse-score/bazel_registry_ui)
+
+---
+### 8.2.3 Mirrors & Replication
+
+*Replicating important deliverables into secondary channels for resilience, reach, or governance reasons.*
+
+
+## 8.3 Release Metadata ⚪
+
+*Infrastructure attaching the metadata required to identify, verify, and consume released deliverables.*
+
+**S-CORE**
+
+- Released deliverables should be accompanied by metadata such as version identifiers, checksums, SBOMs, provenance, and release notes.
+- Metadata is part of the delivery capability because downstream consumers need it to verify, integrate, and audit releases.
+- **Biggest gap**: no common release metadata baseline defines what every S-CORE release must publish.
+
+### 8.3.1 Versioning & Tagging
+
+*Identifying deliverables consistently across repositories and releases.*
+
+**S-CORE**
+
+- Semantic versioning aligned with Git tags is the expected standard across S-CORE repositories.
+- Versioning and tagging identify release deliverables and connect them back to source history.
+- **Biggest gap**: versioning conventions are not uniformly enforced or validated across repositories.
+
+### 8.3.2 Compliance & Traceability Metadata
+
+*Publishing supporting metadata needed for compliance, verification, and supply-chain traceability.*
+
+**S-CORE**
+
+SBOMs, provenance data, signatures, checksums, and release notes should accompany released deliverables where applicable. From the release perspective, the key question is simple: which evidence travels with the published artifact so downstream users can verify and understand it? The harder compliance questions, such as how a repository arrived at that SBOM, how license data was enriched, or whether a dependency belongs in development scope or product scope, belong in [chapter 6](06-compliance-infrastructure.md) and should not be duplicated here.
+
+This metadata still matters here because publication is what makes the evidence durable and consumer-visible. A release artifact without its supporting evidence is harder to audit, trust, and respond to later when issues are disclosed. **Biggest gap**: no standardized process ensures that compliance and traceability metadata is generated and published with each release.
+
+---
+
+## 8.4 Consumer Access ⚪
+
+*Infrastructure making released deliverables discoverable, retrievable, and usable by downstream consumers.*
+
+**S-CORE**
+
+- Consumers need a clear path to discover available deliverables, understand their intended use, and retrieve the correct format.
+- For Bazel modules, consumer access is centered on the shared registry metadata and the registry UI.
+- Consumer access includes naming, discoverability, documentation, and availability of public download or pull mechanisms.
+- **Biggest gap**: no shared consumer-facing model explains where deliverables live, which consumers each format serves, or how access should work across S-CORE.
+
+### 8.4.1 Discoverability
+
+*Making available deliverables and their purpose visible to downstream users.*
+
+**S-CORE**
+
+GitHub Releases provide basic discoverability for release assets and release notes, but they are not the right starting point for Bazel modules. For modules, users should begin with the [registry UI](https://eclipse-score.github.io/bazel_registry_ui/), which presents the published contents of the shared registry in a way that is easier to browse than the raw repository. The underlying source of truth is still the registry data in [eclipse-score/bazel_registry](https://github.com/eclipse-score/bazel_registry/).
+
+Good discoverability also requires light explanation. Users need to know that the registry answers the question "which module versions exist?" while the owning repository answers "how do I use this module once I depend on it?" Those two layers complement each other and should stay linked.
+
+**Biggest gap**: no consistent discoverability pattern yet spans both GitHub release assets and registry-published modules in one coherent consumer story.
+
+### 8.4.2 Retention, Availability & Rollback
+
+*Keeping released deliverables accessible over time and enabling reliable rollback to previous baselines.*
+
+**S-CORE**
+
+Retention and rollback are two sides of the same coin. Retention asks which artifacts stay available and for how long; rollback asks how a consumer or the project itself reverts to a previously baselined release when a newer version turns out to be broken.
+
+For S-CORE, the retention picture depends on the publication channel. GitHub Releases retain release assets indefinitely by default, which means source archives, binaries, and attached metadata remain accessible as long as the repository exists. The Bazel registry retains module entries permanently because they are committed files in a Git repository. GitHub Actions artifacts, by contrast, are ephemeral and disappear after a configurable retention window, which makes them unsuitable as the only home for anything that needs to survive beyond a single CI run.
+
+Rollback requires more than artifact availability. A consumer who needs to revert to a previous module version can do so through the registry by pinning `bazel_dep` to the older version, which is straightforward as long as the older version is still present in the registry and the release assets it references are still available. For integrated baselines that span multiple modules, rollback means returning to a previous `known_good` manifest rather than individually downgrading components, because the combination of module versions matters as much as any single version. The `known_good` model described in [section 7.3.4](07-automation-integration.md#known-good-promotion) provides the identifier, but the ability to rebuild and redeploy from that identifier depends on all referenced artifacts, toolchain versions, and environment images still being retrievable.
+
+A practical rollback strategy therefore needs three properties: durable artifact storage so that nothing disappears before it is no longer needed, manifest-level version identity so that "go back to the previous known-good" is an unambiguous operation, and a tested procedure so that rollback is a routine operation rather than an emergency improvisation.
+
+**Biggest gap**: no explicit retention policy, rollback procedure, or availability guarantee is defined for S-CORE deliverables. The ability to roll back to a previous integrated baseline is assumed but not documented or tested.
+
+### 8.4.3 Consumer Guidance
+
+*Helping downstream users choose the right deliverable and understand how it should be consumed.*
+
+**S-CORE**
+
+For Bazel modules, the normal consumer workflow is straightforward. First, browse the [registry UI](https://eclipse-score.github.io/bazel_registry_ui/) to find the module and version you need. Next, configure your repository to use the S-CORE registry as described in [section 3.2.2](03-build-infrastructure.md#internal-module-dependencies). Finally, declare the dependency in `MODULE.bazel` and use the module according to the documentation in its owning repository.
+
+Because registry entries are coupled to GitHub Releases, users can usually think of a registry version as the Bazel-consumable form of a repository release. The registry tells you which versions exist and how Bazel should fetch them. The owning repository tells you what the release contains and how to use the module once you depend on it.
+
+To make this concrete, consumer repositories need the registry configuration in `.bazelrc`:
+
+```text
+common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/
+common --registry=https://bcr.bazel.build
+```
+
+With that in place, `MODULE.bazel` can declare dependencies with Bazel's normal module mechanism such as `bazel_dep(...)`. The S-CORE registry is then used for first-party modules, while the Bazel Central Registry remains available for public dependencies. The official [Bazel modules documentation](https://bazel.build/external/module) is the best reference for the `MODULE.bazel` syntax itself.
+
+That split is important for keeping the documentation maintainable. This infrastructure guide explains where modules are published, how consumers discover them, and how Bazel is pointed at the registry. The mechanics for adding or updating module versions stay in the [registry README](https://github.com/eclipse-score/bazel_registry/blob/main/README.md), while module-specific API and usage details stay with the module's own source repository.
+
+**Biggest gap**: there is no short, shared pattern for explaining how to consume registry-published S-CORE modules across repositories.
+
+## 8.5 Post-Release Communication & Response ⚪
+
+*Infrastructure for communicating and managing consumer-facing response once issues in distributed artifacts have been identified.*
+
+**S-CORE**
+
+- Dependency analysis, license interpretation, and continuous SBOM monitoring belong in [chapter 6](06-compliance-infrastructure.md).
+- This chapter focuses on what happens on the consumer-facing release side once those issues are known.
+- **Biggest gap**: no shared advisory and remediation communication model is defined for S-CORE deliverables.
+
+### 8.5.1 Consumer Advisories
+
+*Communicating post-release issues to downstream consumers in a clear and durable way.*
+
+**S-CORE**
+
+- Consumers need a clear advisory path once a relevant issue has been confirmed.
+- **Biggest gap**: there is no shared advisory model for communicating issues affecting S-CORE releases.
+
+### 8.5.2 Affected & Remediated Versions
+
+*Explaining which released versions are affected and which versions contain remediation.*
+
+**S-CORE**
+
+- Consumer communication should eventually link affected versions, remediated versions, and the relevant release metadata.
+- **Biggest gap**: version-level remediation guidance is not yet standardized across S-CORE releases.
+
+### 8.5.3 Supporting Evidence
+
+*Linking advisories back to the evidence that supports them.*
+
+**S-CORE**
+
+- Advisories are stronger when they can reference release notes, SBOMs, provenance, and other supporting material already produced elsewhere in the infrastructure flow, including the scoped compliance evidence described in [chapter 6](06-compliance-infrastructure.md).
+- **Biggest gap**: there is no shared pattern for linking consumer advisories back to the supporting release evidence.
\ No newline at end of file
diff --git a/docs/explanation/09-documentation-infrastructure.md b/docs/explanation/09-documentation-infrastructure.md
new file mode 100644
index 0000000..170d35f
--- /dev/null
+++ b/docs/explanation/09-documentation-infrastructure.md
@@ -0,0 +1,149 @@
+# 9 Documentation & Traceability 🟠
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure supporting engineering documentation across S-CORE repositories.*
+
+**S-CORE**
+
+- Documentation infrastructure in S-CORE currently spans repository documentation sites and engineering-focused docs-as-code capabilities.
+- Documentation is published through CI-driven static site generation and hosting.
+- Engineering traceability (requirements, architecture, design, implementation, tests) is a target capability for functional safety compliance.
+- **Biggest gap**: shared documentation conventions, cross-repository navigation, and traceability integration are not yet defined as one coherent project-wide capability.
+
+## 9.1 Authoring & Tooling 🟡
+
+*Capabilities for writing, structuring, and maintaining documentation in repositories.*
+
+**S-CORE**
+
+- Documentation is authored in version-controlled repositories alongside source code.
+- Markdown and rST are the primary input formats.
+- **Biggest gap**: authoring conventions and required documentation structure are not yet standardized across S-CORE repositories.
+
+### 9.1.1 Docs-As-Code Tooling 🟡
+
+*Shared documentation build infrastructure across S-CORE repositories.*
+
+**S-CORE**
+
+[eclipse-score/docs-as-code](https://github.com/eclipse-score/docs-as-code) provides the shared documentation build tooling consumed across S-CORE. It packages Sphinx with MyST parser, the pydata-sphinx-theme with S-CORE branding, traceability support via sphinx-needs, and related documentation infrastructure into a versioned Bazel module. Repositories declare a dependency on `docs-as-code` to get a consistent documentation build experience without assembling their own toolchain.
+
+Adoption is uneven: recent module repositories use `docs-as-code` v4.x, while older repositories still reference v1.x–v3.x or do not use the shared tooling at all. This version spread mirrors the broader synchronization challenge described in [chapter 1](01-source-code-infrastructure.md#synchronization-mechanisms). Good documentation infrastructure should also let contributors preview and validate changes without waiting for a remote publishing pipeline.
+
+**Biggest gap**: `docs-as-code` version adoption is fragmented, and fast local preview and validation workflows are not yet consistently documented across documentation-producing repositories.
+
+---
+
+## 9.2 Build, Validation & Publishing 🟡
+
+*Infrastructure for builds, quality checks, and publication of documentation sites.*
+
+**S-CORE**
+
+Documentation build infrastructure should be versioned, reproducible, and reviewable like any other engineering toolchain. [eclipse-score/docs-as-code](https://github.com/eclipse-score/docs-as-code) is the shared build tooling that most module repositories are expected to consume. It is distributed through the Bazel registry and provides Sphinx-based documentation builds including traceability extensions. The CI side is handled by the reusable `docs.yml` and `docs-verify.yml` workflows in [eclipse-score/cicd-workflows](https://github.com/eclipse-score/cicd-workflows).
+
+This infrastructure documentation site uses `docs-as-code` with the standard Bazel-based Sphinx build, consistent with the rest of the S-CORE ecosystem. While it does not currently define traceability need objects, the infrastructure is in place to add them when needed.
+
+**Biggest gap**: not all documentation-producing repositories follow one shared toolchain and publication pattern. The `docs-as-code` version spread (v1.x through v4.x across repositories) means repositories do not reliably share the same documentation capabilities.
+
+### 9.2.1 Deterministic Build and Configuration 🟡
+
+*Ensuring reproducible documentation output across local and CI environments.*
+
+**S-CORE**
+
+- Tooling and site configuration should live in version control so contributors can reproduce the published result locally and in CI.
+- **Biggest gap**: documentation toolchain choices and configuration practices are not yet aligned across S-CORE documentation surfaces.
+
+### 9.2.2 Validation, Previews, and Publishing 🟡
+
+*Providing contributor feedback before merge through fast preview and validation workflows.*
+
+**S-CORE**
+
+Documentation quality depends on catching structural problems before they reach the published site. Strict builds are the first line of defense: running the site generator in strict mode surfaces broken internal links, invalid markup, and missing navigation entries during CI rather than after publication. Beyond strict builds, dedicated structural checks can validate concerns that the site generator itself does not enforce, such as external link reachability, heading hierarchy consistency, required metadata fields, and naming conventions for files or anchors.
+
+These checks should run as part of the normal pull-request workflow so that contributors get feedback before merge. The important design choice is where the check definitions live. Checks that apply to all S-CORE documentation repositories belong in shared reusable workflows described in [section 7.2](07-automation-integration.md#reusable-workflows), while repository-specific validation rules can stay local. Both should produce clear, actionable output rather than noisy warnings that contributors learn to ignore.
+
+Publishing should be an explicit, reproducible stage of the docs pipeline rather than an undocumented side effect. A contributor should be able to run the same validation locally before pushing, so the tooling must not depend on CI-only infrastructure.
+
+**Biggest gap**: validation depth, preview availability, and publishing ownership are not yet consistent across repositories. Structural checks beyond strict builds are not yet defined as a shared capability.
+
+---
+
+## 9.3 Cross-Repository Documentation Integration 🔴
+
+*Connecting documentation across repositories with stable linking and navigation patterns.*
+
+**S-CORE**
+
+- Contributors and stakeholders should be able to move across repository boundaries without losing context.
+- **Biggest gap**: there is no shared information architecture for how repository-local documentation fits into a broader S-CORE documentation landscape.
+
+### 9.3.1 Cross-Repository Linking 🔴
+
+*Establishing reliable links across repository boundaries and release versions.*
+
+**S-CORE**
+
+- Stable links are required if documentation, code, requirements, and release artifacts live in different repositories.
+- For integrated views produced from `reference_integration`, those links should resolve within one explicit `known_good` snapshot rather than silently mixing repository heads.
+- **Biggest gap**: no agreed cross-repository linking strategy exists for versioned and unversioned documentation content.
+
+### 9.3.2 Shared Navigation and Discovery 🔴
+
+*Making documentation content easier to discover across repository-specific sites.*
+
+**S-CORE**
+
+When documentation is spread across repository-specific sites, the first problem is knowing where to look. A contributor searching for "how do I add a Bazel module" should not need to guess whether the answer lives in the platform documentation, the build infrastructure site, or a module repository's own pages. The same applies to consumers who want to understand what S-CORE offers before they start integrating.
+
+Shared entry points address this by giving readers a starting location that links outward. The simplest version is an overview page or hub site that indexes the major documentation surfaces and describes what each one covers. A more structured version adds cross-site navigation elements — shared headers, breadcrumbs, or sidebar links — so that readers who land on one repository's site can see where related content lives without returning to the hub. The design choice is how tightly to couple this: a lightweight hub with stable links is easy to maintain, while deeper navigation integration requires coordination whenever a repository restructures its pages.
+
+For S-CORE, the practical starting point is the main [eclipse-score.github.io](https://eclipse-score.github.io/score) site, which already serves as a project-level entry. But the path from that entry to repository-specific documentation is not yet systematic: some repositories are linked, others are not, and the reader has no way to know what exists without browsing GitHub directly. A shared navigation pattern would define which documentation surfaces are expected to appear, how they are categorized, and where the canonical index lives so that new repositories automatically become discoverable when they follow the pattern.
+
+**Biggest gap**: repository-specific sites still feel isolated because no common navigation and discovery pattern ties them together. There is no defined standard for how new documentation surfaces register themselves in a project-wide index.
+
+---
+
+## 9.4 Engineering Documentation & Traceability 🟠
+
+*Infrastructure supporting requirements, architecture, design, and links to implementation and tests.*
+
+**S-CORE**
+
+- Engineering documentation (requirements, architecture, detailed design) is required for process compliance (e.g. ISO 26262, ASPICE).
+- Architecture visualization and code integration are target capabilities to connect documentation with implementation artifacts.
+- Test evidence itself is produced in [chapter 4](04-testing-infrastructure.md); this chapter focuses on the documentation and traceability structures that should consume that evidence.
+- **Biggest gap**: traceability and engineering evidence exist in parts, but the supporting model and tooling are not yet standardized across repositories and verification flows.
+
+### 9.4.1 Traceability, Code Integration, and Impact Analysis 🟠
+
+*Linking requirements, design, code, and verification artifacts to support impact analysis.*
+
+**S-CORE**
+
+Traceability needs explicit object models and stable identifiers, not just linked prose. In a docs-as-code setting, that means requirements, design decisions, and verification references should be machine-readable documentation objects with typed relationships rather than free-form text that happens to mention a requirement ID.
+
+The Sphinx ecosystem provides this through extensions that let authors declare typed objects directly in documentation source and express relationships between them. Those objects can then be queried, filtered, and rendered as traceability matrices, coverage tables, or impact analysis views without maintaining a separate database. The important property is that the traceability data lives in version control alongside the prose, follows the same review process, and can be validated during the documentation build.
+
+For S-CORE, the practical value is that test evidence produced in [chapter 4](04-testing-infrastructure.md#test-traceability) can be linked back to requirement objects in documentation, creating a verification chain from requirement through implementation to test result. When requirements change between releases, the same object model makes it possible to identify which links break, which tests need re-evaluation, and which verification evidence is stale. That is the versioning dimension: requirement objects should carry version identity so that a documentation build for one `known_good` snapshot can show the requirement state at that point, while a diff between snapshots shows what changed.
+
+**Biggest gap**: the tooling direction for docs-as-code traceability exists but is not yet named, standardized, or integrated into the documentation build pipeline across S-CORE repositories. Requirement versioning across releases is not yet addressed.
+
+### 9.4.2 Known-Good Documentation Snapshots 🔴
+
+*Tying integrated docs and traceability evidence to one validated cross-repository snapshot.*
+
+**S-CORE**
+
+Cross-repository documentation becomes ambiguous unless readers can tell which combination of component revisions it describes. The `known_good` concept solves that by giving integrated documentation, verification summaries, and traceability views one shared snapshot identifier. A single documentation build in `reference_integration` should therefore describe one concrete `known_good` manifest or record, not an unspecified mix of module heads.
+
+Under the currently assumed but still-undecided Option 2 model, this identifier is also what allows the project to claim that integrated docs and integrated evidence were generated from the same centrally validated stack. If `reference_integration` later ends up with a lighter scope, the documentation benefit remains, but the traceability story has to distinguish more clearly between centrally generated pages and evidence linked in from module repositories.
+
+The important architectural point is that links, release notes, dashboards, and archived evidence should all resolve back to the same `known_good` identifier. **Biggest gap**: S-CORE does not yet have a documented rule for binding integrated documentation and traceability artifacts to one explicit cross-repository snapshot.
+
+This snapshot-oriented documentation view depends on the same integration model described in [DR-002-Infra](https://eclipse-score.github.io/score/main/design_decisions/DR-002-infra.html) and on the still-unsettled `reference_integration` scope discussion in [DR-008-Int](https://github.com/qorix-group/score/blob/da4ea900f1eece5c8e795697d71e277446dca84e/docs/design_decisions/DR-008-int.rst?plain=1).
\ No newline at end of file
diff --git a/docs/explanation/10-infrastructure-operations.md b/docs/explanation/10-infrastructure-operations.md
new file mode 100644
index 0000000..67a388f
--- /dev/null
+++ b/docs/explanation/10-infrastructure-operations.md
@@ -0,0 +1,182 @@
+# 10 Infrastructure Operations ⚪
+
+:::{tip} Looking for practical guides?
+This chapter is part of the infrastructure landscape assessment. For step-by-step how-tos and quick references, see the [How-to Guides](../how-to/index.md).
+:::
+
+*Infrastructure for operating and maintaining the S-CORE engineering infrastructure.*
+
+:::{warning} Draft
+This chapter has not been fully reviewed. Content may be incomplete or inaccurate.
+:::
+
+**S-CORE**
+
+- Infrastructure operations covers runner operations, monitoring, dependency maintenance, governance, and upkeep of shared services such as the Bazel registry and its UI.
+- Some of the shared services used by S-CORE are operated by external providers or teams, especially in the runner space.
+- Dependabot automates dependency updates for infrastructure tooling across repositories.
+- **Biggest gap**: systematic monitoring, incident handling, and proactive maintenance processes are not yet consistently defined across S-CORE infrastructure.
+
+## 10.1 CI Runner Operations ⚪
+
+*Operating CI execution environments for S-CORE pipelines.*
+
+**S-CORE**
+
+- Self-hosted runner infrastructure may be operated outside the public S-CORE project, while public S-CORE CI also relies on GitHub-hosted runners.
+- **Biggest gap**: dependency on external runner operations creates a gap in public contributor autonomy and visibility.
+
+### 10.1.1 GitHub Public Runners
+
+*GitHub-hosted runners used by S-CORE CI pipelines.*
+
+**S-CORE**
+
+- GitHub-hosted runners are the default execution environment for public S-CORE CI.
+- **Biggest gap**: GitHub-hosted runner capacity and feature availability are outside S-CORE control.
+
+### 10.1.2 Runner Configuration
+
+*Managing runner environment configuration.*
+
+**S-CORE**
+
+- Runner configuration is managed through workflow YAML files and, for self-hosted runners, by external operating teams.
+- **Biggest gap**: runner environment consistency and configuration documentation are not maintained in a central, public location.
+
+### 10.1.3 Ownership & Boundaries
+
+*Clarifying which parts of runner operations are owned inside S-CORE and which are external dependencies.*
+
+**S-CORE**
+
+- Contributors need a clearer model for which infrastructure concerns they can change directly and which depend on GitHub or external operators.
+- **Biggest gap**: the operational boundary between project-owned configuration and externally operated execution services is not yet documented clearly enough.
+
+---
+
+## 10.2 Infrastructure Monitoring ⚪
+
+*Monitoring CI usage, failures, and infrastructure health across S-CORE.*
+
+**S-CORE**
+
+- CI pipeline failures are visible via GitHub Actions; no proactive monitoring or alerting spans S-CORE repositories.
+- Shared service monitoring should eventually include the Bazel registry publication path and the registry UI, not only CI pipelines.
+- **Biggest gap**: no cross-repository infrastructure health dashboard or alert channel exists for S-CORE.
+
+### 10.2.1 CI Usage Monitoring
+
+*Monitoring CI usage patterns and capacity across S-CORE pipelines.*
+
+**S-CORE**
+
+- GitHub Actions provides per-repository usage metrics; no aggregated cross-repository view exists.
+- **Biggest gap**: S-CORE-wide CI usage visibility and capacity planning are not operationalized.
+
+### 10.2.2 Failure Monitoring
+
+*Monitoring failures across S-CORE infrastructure systems.*
+
+**S-CORE**
+
+- Pipeline failures are surfaced per repository via GitHub; no S-CORE-wide failure tracking dashboard exists.
+- Failures affecting the shared Bazel registry, its validation workflows, or the registry UI would block module publication or discovery across repositories.
+- **Biggest gap**: recurring failure patterns across S-CORE pipelines and shared distribution services are not systematically detected.
+
+### 10.2.3 Incident Coordination
+
+*Coordinating response when infrastructure failures affect multiple repositories or teams.*
+
+**S-CORE**
+
+- Cross-repository incidents need lightweight coordination so contributors do not diagnose the same infrastructure problem independently.
+- **Biggest gap**: there is no shared incident coordination and communication pattern for project-wide infrastructure problems.
+
+---
+
+## 10.3 Infrastructure Maintenance ⚪
+
+*Keeping S-CORE infrastructure tooling and dependencies up to date.*
+
+**S-CORE**
+
+- Dependabot automates version and SHA updates for infrastructure dependencies across S-CORE repositories.
+- **Biggest gap**: proactive maintenance beyond Dependabot (e.g. major tool upgrades, deprecation handling) is not yet structured.
+
+### 10.3.1 Tool Updates
+
+*Updating shared infrastructure tools across S-CORE repositories.*
+
+**S-CORE**
+
+- Tool upgrades (e.g. Bazel, docs-as-code, runner images) are performed reactively on a per-repository basis.
+- **Biggest gap**: no coordinated tool update process or shared upgrade playbook exists across S-CORE.
+
+### 10.3.2 Dependency Updates
+
+*Updating infrastructure dependencies across S-CORE repositories.*
+
+**S-CORE**
+
+- [Dependabot](https://github.com/dependabot) automatically opens pull requests to bump dependency versions and SHA hashes.
+- **Biggest gap**: Dependabot coverage is limited to supported dependency file types; non-standard lockfiles are not auto-updated.
+
+### 10.3.3 Deprecation & Lifecycle Management
+
+*Retiring outdated infrastructure components before they become operational risk.*
+
+**S-CORE**
+
+- Operational maintenance includes responding to upstream deprecations before they create outages.
+- **Biggest gap**: there is no shared deprecation tracking and migration planning process for infrastructure components.
+
+### 10.3.4 Shared Registry Services
+
+*Maintaining the shared Bazel module registry and its consumer UI as part of S-CORE infrastructure.*
+
+**S-CORE**
+
+The shared Bazel registry at [eclipse-score/bazel_registry](https://github.com/eclipse-score/bazel_registry/) and the registry UI at [eclipse-score.github.io/bazel_registry_ui](https://eclipse-score.github.io/bazel_registry_ui/) are part of the live infrastructure surface for cross-repository dependency management. The full publication and consumption flow is described in [chapter 8](08-artifact-distribution.md#registry-based-distribution); this section is only about operating that service reliably.
+
+Infrastructure maintainers therefore need to keep the registry repository, the automation that validates and publishes registry updates, the raw GitHub-hosted content that Bazel reads, and the GitHub Pages deployment of the companion [eclipse-score/bazel_registry_ui](https://github.com/eclipse-score/bazel_registry_ui) project working together. If the registry data is wrong, if validation breaks, or if the UI deployment is stale, module publication and discovery degrade across the project.
+
+The [registry README](https://github.com/eclipse-score/bazel_registry/blob/main/README.md) should remain the canonical contributor guide for adding or updating module versions. Operations documentation should complement it with service ownership, monitoring, incident handling, and recovery guidance rather than copying the contributor workflow.
+
+---
+
+## 10.4 Infrastructure Governance ⚪
+
+*Guiding and recording the evolution of S-CORE infrastructure.*
+
+**S-CORE**
+
+- Infrastructure decisions and policies are expected to be documented and version-controlled.
+- **Biggest gap**: a structured decision record process and central policy repository are not yet operational across S-CORE.
+
+### 10.4.1 Infrastructure Policies
+
+*Defining policies governing S-CORE infrastructure usage.*
+
+**S-CORE**
+
+- Infrastructure usage policies (runner selection, dependency constraints, tooling standards) are not yet formally documented.
+- **Biggest gap**: no central, versioned policy document set governs S-CORE infrastructure choices.
+
+### 10.4.2 Infrastructure Decision Records
+
+*Documenting major S-CORE infrastructure decisions.*
+
+**S-CORE**
+
+- Architecture Decision Records (ADRs) are a target practice for documenting significant infrastructure decisions.
+- **Biggest gap**: no ADR process or repository is established for S-CORE infrastructure decisions.
+
+### 10.4.3 Change Rollout & Communication
+
+*Explaining how infrastructure changes are communicated across repositories.*
+
+**S-CORE**
+
+- Some cross-repository changes need more than a merged pull request; they also need timing and migration communication.
+- **Biggest gap**: there is no documented rollout-and-communication model for changes that affect multiple S-CORE repositories.
\ No newline at end of file
diff --git a/docs/explanation/decisions.md b/docs/explanation/decisions.md
new file mode 100644
index 0000000..37e0629
--- /dev/null
+++ b/docs/explanation/decisions.md
@@ -0,0 +1,71 @@
+# Infrastructure Design Decisions
+
+Key architectural decisions that shape the S-CORE infrastructure. Each entry summarizes the problem, the decision made, and the main tradeoff. Full decision records live in the [S-CORE Handbook](https://eclipse-score.github.io/score/main/handbook).
+
+---
+
+## DR-003 — Devcontainer: Monolithic Image vs. Multi-Container
+
+**Problem**: S-CORE repositories need a shared local environment for tools that are not delivered by the primary build flow (editors, formatters, linters, documentation tooling). The question was whether to use a single shared container image or a Docker Compose setup with one container per concern.
+
+**Decision**: Monolithic image — one `ghcr.io/eclipse-score/devcontainer` image that carries all shared tools.
+
+**Rationale**: Keeps the contributor entry point simple (one container, one `devcontainer.json`). Avoids orchestration complexity of managing multiple containers for a development-time convenience layer.
+
+**Tradeoff**: The image is larger than any individual contributor needs. Pre-built images and layer caching mitigate startup cost in practice.
+
+**Effect on docs**: Section [2.1 Central Devcontainer](02-developer-environment.md#central-devcontainer) describes how repositories consume this image.
+
+---
+
+## DR-001-Strat — Consistent Stack Direction
+
+**Problem**: S-CORE consists of many independently-developed component repositories. Without a defined integration model, there is no canonical answer for "which combination of component versions is the validated S-CORE stack at any given moment."
+
+**Decision**: Establish a `known_good` integration manifest that identifies which component revisions belong together in one validated stack. This is the authoritative record of integration state, distinct from individual component releases.
+
+**Effect on docs**: The `known_good` concept is described in [Glossary: known_good](../reference/glossary.md#k). The integration model is implemented through [reference_integration](../reference/glossary.md#r).
+
+**Full DR**: [DR-001-Strat](https://eclipse-score.github.io/score/main/design_decisions/DR-001-strat.html)
+
+---
+
+## DR-002-Infra — Distributed-Monolith Integration Model
+
+**Problem**: With `known_good` established as the integration unit, the question is what the integration environment (`reference_integration`) should do: assemble the stack, validate it, and produce evidence — but with what ownership and scope?
+
+**Decision**: Adopt a distributed-monolith integration model. Component repositories own their individual verification. `reference_integration` assembles the `known_good` manifest, runs cross-repository validation on it, and promotes it on success.
+
+**Effect on docs**: The cross-repository CI orchestration flow is described in [7.3 Cross-Repository Integration](07-automation-integration.md#cross-repository-integration). The CI promotion model is described in [7.3.4 Known-Good Promotion](07-automation-integration.md#known-good-promotion).
+
+**Full DR**: [DR-002-Infra](https://eclipse-score.github.io/score/main/design_decisions/DR-002-infra.html)
+
+---
+
+## DR-008-Int — `reference_integration` Scope (Open)
+
+**Status**: Not yet decided.
+
+**Problem**: Two options are under discussion for the scope of `reference_integration`:
+
+- **Option 2** (stronger central ownership): `reference_integration` rebuilds and re-tests the full integrated stack for every `known_good` promotion. All cross-repository verification evidence is produced centrally.
+- **Lighter scope**: `reference_integration` assembles and promotes `known_good` but delegates more verification to individual component repositories. Some evidence stays per-module.
+
+**Effect on docs**: Several sections in [Chapter 3](03-build-infrastructure.md) and [Chapter 7](07-automation-integration.md) note where their architecture description assumes Option 2 and where it would change under a lighter scope.
+
+**Full DR**: [DR-008-Int](https://github.com/qorix-group/score/blob/da4ea900f1eece5c8e795697d71e277446dca84e/docs/design_decisions/DR-008-int.rst?plain=1)
+
+---
+
+## `known_good` Architecture Note
+
+This section was formerly part of [Chapter 3 § 3.2.7](03-build-infrastructure.md#dependency-management) and moved here because it describes an architectural decision context, not a current build capability.
+
+`reference_integration` introduced the idea of a `known_good` set: an explicit manifest of which component revisions belong together in one integrated S-CORE stack. The core content is a tuple of `(component, commit)` pairs plus metadata. This should not be described as just another Bazel lock file — it sits one level above that:
+
+- A **lock file** (`MODULE.bazel.lock`, `uv.lock`) captures the resolved dependency graph that a concrete Bazel workspace consumes.
+- A **`known_good` manifest** is the curated integration selection from which Bazel-facing inputs can be generated. It can also carry automation metadata such as timestamps, suite identity, and which branch should be followed for automated CI refreshes.
+
+Regardless of whether the project eventually adopts Option 2 or a lighter `reference_integration` scope, `known_good` should be version-controlled, diffable, reproducible, and clearly distinct from generated Bazel lock data. The concrete file format matters less than that behavior.
+
+**Decision background**: [DR-001-Strat](https://eclipse-score.github.io/score/main/design_decisions/DR-001-strat.html) · [DR-002-Infra](https://eclipse-score.github.io/score/main/design_decisions/DR-002-infra.html) · [DR-008-Int](https://github.com/qorix-group/score/blob/da4ea900f1eece5c8e795697d71e277446dca84e/docs/design_decisions/DR-008-int.rst?plain=1)
diff --git a/docs/explanation/index.md b/docs/explanation/index.md
new file mode 100644
index 0000000..0733274
--- /dev/null
+++ b/docs/explanation/index.md
@@ -0,0 +1,674 @@
+# Infrastructure Landscape
+
+Architecture, design rationale, and maturity assessment of each S-CORE infrastructure area. These chapters describe what exists, how it works, and what is still missing.
+
+- [1. Source Code Infrastructure](01-source-code-infrastructure.md)
+- [2. Developer Environment](02-developer-environment.md)
+- [3. Build & Dependencies](03-build-infrastructure.md)
+- [4. Testing](04-testing-infrastructure.md)
+- [5. Code Analysis Infrastructure](05-static-analysis-infrastructure.md)
+- [6. Compliance & Dependency Analysis](06-compliance-infrastructure.md)
+- [7. Automation & CI](07-automation-integration.md)
+- [8. Release & Distribution](08-artifact-distribution.md)
+- [9. Documentation & Traceability](09-documentation-infrastructure.md)
+- [10. Infrastructure Operations](10-infrastructure-operations.md)
+- [Infrastructure Design Decisions](decisions.md)
+
+## Status Legend
+
+- 🟢 Implemented and effective
+- 🟡 Partially implemented / needs improvement
+- 🟠 Implemented but problematic or insufficient
+- 🔴 Not started
+- ⚪ Unknown / not yet assessed
+
+## Chapter Map
+
+
+
This chapter map is generated from the `#` and `##` headings in the numbered chapter files. Click any chapter or section box to open it.
+ +```{mermaid} +mindmap + root((S-CORE Infrastructure)) + node_001["`1 Source Code +Infrastructure 🟠`"] + node_002["`1.1 Hosting & Organization +⚪`"] + node_003["`1.2 Repository +Provisioning & Lifecycle 🟡`"] + node_004["`1.3 Repository Policy +Management 🔴`"] + node_005["1.4 Repository Standards 🟠"] + node_006["`2 Developer Environment +🟡`"] + node_007["2.1 Central Devcontainer 🟠"] + node_008["`2.2 Local Auxiliary +Tooling 🟡`"] + node_009["3 Build & Dependencies ⚪"] + node_010["3.1 Build System ⚪"] + node_011["`3.2 Dependency Management +⚪`"] + node_012["3.3 Toolchain Management ⚪"] + node_013["`3.4 Build Reproducibility +& Evidence ⚪`"] + node_014["`3.5 Build Execution +Infrastructure ⚪`"] + node_015["4 Testing 🟠"] + node_016["`4.1 Test Framework +Integration 🟠`"] + node_017["4.2 Test Traceability 🟠"] + node_018["`4.3 Test Execution & +Dynamic Analysis 🟠`"] + node_019["4.4 Test Reporting 🟠"] + node_020["`5 Code Analysis +Infrastructure ⚪`"] + node_021["5.1 Tooling Baseline ⚪"] + node_022["`5.2 Shared Rule +Configuration ⚪`"] + node_023["5.3 Execution Model ⚪"] + node_024["5.4 Security Scanning 🟠"] + node_025["`5.5 Results and Governance +⚪`"] + node_026["`6 Compliance & +Dependency Analysis ⚪`"] + node_027["6.1 File-Level Licensing ⚪"] + node_028["6.2 Dependency Analysis ⚪"] + node_029["`6.3 SBOM Scoping and +Compliance Evidence ⚪`"] + node_030["`6.4 License Checks and +Compliance ⚪`"] + node_031["`6.5 Monitoring and +Governance ⚪`"] + node_032["`7 Automation +Infrastructure & +Continuous Integration +(CI) ⚪`"] + node_033["7.1 Runners 🟠"] + node_034["7.2 Reusable Workflows ⚪"] + node_035["`7.3 Cross-Repository +Integration ⚪`"] + node_036["7.4 Secrets Management ⚪"] + node_037["7.5 CI Observability ⚪"] + node_038["`8 Release & Distribution +⚪`"] + node_039["8.1 Deliverable Types ⚪"] + node_040["`8.2 Distribution Channels +⚪`"] + node_041["8.3 Release Metadata ⚪"] + node_042["8.4 Consumer Access ⚪"] + node_043["`8.5 Post-Release +Communication & Response ⚪`"] + node_044["`9 Documentation & +Traceability 🟠`"] + node_045["9.1 Authoring & Tooling 🟡"] + node_046["`9.2 Build, Validation & +Publishing 🟡`"] + node_047["`9.3 Cross-Repository +Documentation Integration +🔴`"] + node_048["`9.4 Engineering +Documentation & +Traceability 🟠`"] + node_049["`10 Infrastructure +Operations ⚪`"] + node_050["`10.1 CI Runner Operations +⚪`"] + node_051["`10.2 Infrastructure +Monitoring ⚪`"] + node_052["`10.3 Infrastructure +Maintenance ⚪`"] + node_053["`10.4 Infrastructure +Governance ⚪`"] +``` + + + +:::{toctree} +:maxdepth: 1 +:hidden: + +01-source-code-infrastructure +02-developer-environment +03-build-infrastructure +04-testing-infrastructure +05-static-analysis-infrastructure +06-compliance-infrastructure +07-automation-integration +08-artifact-distribution +09-documentation-infrastructure +10-infrastructure-operations +decisions +::: diff --git a/docs/how-to/building.md b/docs/how-to/building.md new file mode 100644 index 0000000..cc13f62 --- /dev/null +++ b/docs/how-to/building.md @@ -0,0 +1,51 @@ +# How to Build with Bazel + +## Configure registries + +Every S-CORE module repository configures two Bazel registries in `.bazelrc`: + +```text +common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/ +common --registry=https://bcr.bazel.build +``` + +The first line resolves S-CORE internal modules. The second line falls back to the public [Bazel Central Registry](https://registry.bazel.build/) for everything else. + +## Add a dependency + +Declare dependencies in `MODULE.bazel`: + +```python +bazel_dep(name = "my_dependency", version = "1.2.3") +``` + +Use the [Registry UI](https://eclipse-score.github.io/bazel_registry_ui/) to discover available modules and their versions. + +## Find available modules + +The [Registry UI](https://eclipse-score.github.io/bazel_registry_ui/) lists all modules published to the S-CORE registry. Each registry entry corresponds to a GitHub Release in the module's repository. + +## Configure toolchains + +Build-side toolchains and policy modules are separate concerns: + +| Repository | Role | +|---|---| +| [bazel_cpp_toolchains](https://github.com/eclipse-score/bazel_cpp_toolchains) | **How to compile** C++ (Linux, QNX) | +| [toolchains_rust](https://github.com/eclipse-score/toolchains_rust) | **How to compile** Rust (incl. Ferrocene) | +| [score_cpp_policies](https://github.com/eclipse-score/score_cpp_policies) | **Which rules to enforce** for C++ | +| [score_rust_policies](https://github.com/eclipse-score/score_rust_policies) | **Which rules to enforce** for Rust | + +Toolchains define compilers and linkers. Policies define warning baselines, lint rules, and sanitizer selections. They evolve independently. + +## Refresh lock files + +`MODULE.bazel.lock` and `uv.lock` should be committed. When dependency declarations change, refresh lock files: + +```bash +pre-commit run --all-files +``` + +## Start a new module + +Use [module_template](https://github.com/eclipse-score/module_template) as a starting point. It provides the standard directory layout, `.bazelrc`, devcontainer configuration, and CI workflows. See [Tutorial: Creating a New Module](../tutorials/creating-a-module.md) for a step-by-step walkthrough. diff --git a/docs/how-to/code-quality.md b/docs/how-to/code-quality.md new file mode 100644 index 0000000..45f4968 --- /dev/null +++ b/docs/how-to/code-quality.md @@ -0,0 +1,53 @@ +# How to Enforce Code Quality + +## Set up pre-commit hooks + +```bash +pre-commit install +``` + +Run all checks manually: + +```bash +pre-commit run --all-files +``` + +Hook definitions are maintained in [eclipse-score/tooling](https://github.com/eclipse-score/tooling/blob/main/.pre-commit-hooks.yaml). Checks include formatting, YAML validation, copyright headers, and lock file freshness. + +## Add copyright and license headers + +Every source file needs: + +- A **copyright notice** in the file header +- An **SPDX license identifier** + +For file formats that do not support inline comments, use a `.license` sidecar file alongside the source file. + +Pre-commit hooks and CI PR checks from [eclipse-score/tooling](https://github.com/eclipse-score/tooling) enforce header presence automatically. + +## Apply C++ policies + +[score_cpp_policies](https://github.com/eclipse-score/score_cpp_policies) centralizes: + +- Warning baselines +- Sanitizer feature selections (ASan, UBSan, LSan, TSan) +- Constraint targets + +Consume these policies as a Bazel dependency to apply consistent C++ quality rules across repositories. + +## Apply Rust policies + +[score_rust_policies](https://github.com/eclipse-score/score_rust_policies) packages: + +- Shared Clippy lint rules +- rustfmt defaults + +## Understand where checks run + +| Stage | What runs | Speed | +|---|---|---| +| **Local (pre-commit)** | Formatting, YAML, copyright headers, lock files | Seconds | +| **Bazel build** | Compiler warnings, lint policies, sanitizers | Minutes | +| **CI** | Full test suite, coverage, compliance checks | Minutes | + +Pre-commit catches formatting and hygiene fast. Bazel enforces deeper checks. CI is the final gate. diff --git a/docs/how-to/index.md b/docs/how-to/index.md new file mode 100644 index 0000000..d7fd5d2 --- /dev/null +++ b/docs/how-to/index.md @@ -0,0 +1,31 @@ +# How-to Guides + +Practical recipes for specific tasks. Assumes you already have a working environment. + +## Module development + +- [Building with Bazel](building.md) — Registry, dependencies, toolchains, lock files +- [Testing](testing.md) — Test frameworks, coverage, sanitizers, QNX +- [Code Quality](code-quality.md) — Pre-commit, lint policies, copyright headers +- [Publishing Modules](publishing.md) — Release, registry import, consumer access +- [Writing Documentation](writing-docs.md) — Bazel + Sphinx/MyST setup, local preview, validation + +## Infrastructure development + +- [Update the Devcontainer](update-devcontainer.md) — Build, publish, and roll out a new shared image +- [Manage CI Secrets](manage-ci-secrets.md) — Create, rotate, and replace secrets with OIDC +- [Update a Shared Toolchain](update-toolchain.md) — Bump compiler or policy versions across repositories + +:::{toctree} +:maxdepth: 1 +:hidden: + +building +testing +code-quality +publishing +writing-docs +update-devcontainer +manage-ci-secrets +update-toolchain +::: diff --git a/docs/how-to/manage-ci-secrets.md b/docs/how-to/manage-ci-secrets.md new file mode 100644 index 0000000..a81bdc3 --- /dev/null +++ b/docs/how-to/manage-ci-secrets.md @@ -0,0 +1,106 @@ +# How to Manage CI Secrets + +This guide covers creating, scoping, rotating, and replacing static secrets with federated identity (OIDC) in S-CORE CI workflows. + +## Secret scopes in GitHub Actions + +GitHub provides three secret scopes: + +| Scope | Where set | Who can use it | +|---|---|---| +| Repository | Repository → Settings → Secrets | Workflows in that repository | +| Organization | Org → Settings → Secrets | Workflows in repositories where the secret is granted | +| Environment | Repository → Settings → Environments | Workflows that target that environment | + +**Default to the narrowest scope that works.** Use environment secrets for deploy-time credentials that should be gated by environment protection rules (e.g. requiring a reviewer before a secret is accessible). + +## Create a new secret + +1. Decide on the scope (repository, organization, or environment). +2. Go to the appropriate Settings → Secrets page on GitHub. +3. Click **New secret** (or **New repository secret** / **New organization secret**). +4. Give the secret a clear, uppercase, underscore-separated name (e.g. `REGISTRY_TOKEN`). +5. Paste the secret value and save. + +To reference it in a workflow: + +```yaml +env: + MY_TOKEN: ${{ secrets.MY_TOKEN }} +``` + +Or pass it directly to a step: + +```yaml +- name: Authenticate + run: some-tool login + env: + TOKEN: ${{ secrets.MY_TOKEN }} +``` + +## Rotate a secret + +1. Generate the new credential in the upstream service (GitHub PAT, API key, etc.). +2. Update the secret value in GitHub Settings. +3. Verify that workflows using the secret still succeed after rotation. +4. Revoke the old credential. + +Rotation should happen on a regular cadence (e.g. annually for long-lived PATs) or immediately when a credential is suspected to be compromised. + +## Replace a static secret with OIDC + +OIDC lets CI jobs request short-lived credentials from a cloud provider instead of storing long-lived static secrets. This is the preferred pattern for cloud access where the provider supports it. + +### How it works + +``` +GitHub Actions job → requests OIDC token from GitHub + → exchanges token at cloud provider + → receives short-lived credential + → calls cloud provider API +``` + +The cloud provider is configured to trust GitHub's OIDC issuer and to grant access to tokens with specific claims (e.g. the repository name, branch, or environment). + +### Example: AWS + +1. In AWS IAM, create an OIDC identity provider for `token.actions.githubusercontent.com`. +2. Create an IAM role with a trust policy that allows GitHub tokens from your repository and branch. +3. In the workflow, use the `aws-actions/configure-aws-credentials` action — no static secret needed: + +```yaml +permissions: + id-token: write + contents: read + +steps: + - uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::123456789012:role/my-role + aws-region: eu-central-1 +``` + +For other providers, the pattern is the same: create the OIDC trust on the provider side, then use the appropriate GitHub Action to request credentials. + +## Cross-repository token provisioning + +S-CORE workflows sometimes need to act across repositories (e.g. opening a PR in another repo). The `cicd-actions` repository provides a composite action for this: + +```yaml +- uses: eclipse-score/cicd-actions/get-app-token@Overview, roadmap, contribution guide, and reference
++ This site explains what S-CORE infrastructure is, which shared capabilities and repositories already exist, + how mature they are, what is still missing, and how a concrete issue or pull request fits into the bigger picture. + Whether you're asking how we do something, where to look for a topic, or how an issue fits the big picture — start here. +
+Contributing to this documentation
+ +Contributing Guide
+Documentation style, structure, and review checklist for contributors to this site.
+ + +How to Write Docs
+Bazel + Sphinx/MyST setup, local preview, validation workflow.
+ +Infrastructure Team
+ +Meeting Minutes
+Infrastructure team meeting notes on GitHub Discussions.
+ + +Slack: #score-infrastructure
+Main channel for infrastructure team discussion.
+ + +Slack: #score-infrastructure-review-requests
+Drop PR links here for review — no comments, just links.
+ + +Repository Overview
+Cross-repo metrics and status across all eclipse-score repositories.
+ +S-CORE Project
+ + + +This chapter map is generated from the `#` and `##` headings in the numbered chapter files. Click any chapter or section box to open it.
', + "", + "```{mermaid}", + diagram, + "```", + '", + INDEX_MAP_END, + ] + ) + + +def update_index_page(index_path: Path, chapters: list[Section]) -> bool: + """Replace the generated chapter-map block in the overview page.""" + original = index_path.read_text(encoding="utf-8") + pattern = re.compile( + rf"{re.escape(INDEX_MAP_START)}.*?{re.escape(INDEX_MAP_END)}", + re.DOTALL, + ) + replacement = render_embed(chapters) + updated, n_replacements = pattern.subn(replacement, original, count=1) + if n_replacements != 1: + raise ValueError(f"Could not find generated chapter-map markers in {index_path}") + if updated == original: + return False + index_path.write_text(updated, encoding="utf-8") + return True + + +def main() -> int: + """Generate the overview chapter map and return a shell-friendly exit code.""" + docs_dir = repo_root() / "docs" / "explanation" + index_path = docs_dir / "index.md" + + chapters = [parse_chapter(path) for path in chapter_documents(docs_dir)] + if not chapters: + print(f"⚠️ No chapter files found in {docs_dir}") + return 1 + changed = update_index_page(index_path, chapters) + if changed: + print(f" ✅ Updated {index_path}") + else: + print(f" ℹ️ No changes needed for {index_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/run_tool.sh b/scripts/run_tool.sh new file mode 100644 index 0000000..e4fa335 --- /dev/null +++ b/scripts/run_tool.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Unified entry point for running a CLI tool by name. +# Inside a container the tool is expected on PATH; outside, it is resolved via Bazel. +# See https://github.com/eclipse-score/devcontainer/tree/main/tools for further information. + +set -euo pipefail + +if [[ "$#" -lt 1 ]]; then + echo "Usage: $0