Skip to content

pulseengine/playground-eclipse-score

Repository files navigation

playground-eclipse-score

validate license: Apache-2.0

A pulseengine.eu playground exploring how rivet — a typed-traceability tool — handles the Eclipse S-CORE sphinx-needs corpus.

Not affiliated with the Eclipse Foundation. Eclipse S-CORE is a substantial body of safety engineering work; this workspace converts a snapshot of that work into a second representation so we can study how the two toolchains relate. Upstream eclipse-score repositories are pinned by exact SHA in rivet.yaml + rivet.lock and materialised on demand by make sync — no upstream code is vendored here.

What this is for

Pulseengine builds rivet as part of a wider verification-and-attestation toolchain. We needed a real, non-toy corpus to test rivet's typed schemas, its cross-repo machinery, its variant subsystem, and the ergonomics of rivet validate at scale. Eclipse S-CORE is exactly that kind of corpus — open, well-documented, ISO 26262 / ASPICE-shaped, actively maintained by a working group with strong automotive expertise. Working through it gives us:

  • A concrete answer to "does rivet's schema cover real ASIL-rated artifact shapes?" — measured against 2985 actual sphinx-needs artifacts, not bespoke examples.
  • Direct feedback on rivet's developer experience when ingesting an upstream we don't control.
  • A test surface for proposed rivet features (variant models, per-field embeds, cross-repo externals) under realistic load.

It's a learning exercise for pulseengine. Anything that looks polished about it owes that to upstream eclipse-score — the metamodel, the process documentation, and the artifact discipline are theirs.

Workspace layout

playground-eclipse-score/
├── upstream/                     # symlinks → .rivet/repos/<short>/
│   ├── eclipse-score-score/
│   ├── eclipse-score-process-description/
│   └── ... (58 total, all pinned)
├── rivet/                        # generated rivet projects
│   ├── eclipse-score-score/
│   │   ├── rivet.yaml
│   │   ├── artifacts/imported.yaml   # generated by `make convert`
│   │   ├── docs/<path>/*.md          # generated markdown alongside
│   │   └── coverage.md               # per-repo conversion report
│   └── ... (one per upstream)
├── tools/
│   ├── score_import.py           # RST → rivet YAML converter
│   └── falsification-journey.md  # log of every gap surfaced + closed
├── vendor/
│   └── rivet-schemas/            # pinned snapshot of rivet schemas
├── variants/
│   ├── feature-model.yaml        # starter variant model
│   └── bindings.yaml             # 4 named worked variants
├── rivet.yaml                    # combined corpus + externals declaration
├── rivet.lock                    # SHA pins (cargo-like)
├── Makefile                      # sync / convert / validate / variant-check
└── README.md                     # you are here

Each upstream/<dir> and rivet/<dir> is named eclipse-score-<upstream-repo-name> so a single eclipse-score-* glob filters the entire surface in git, ripgrep, IDE pickers, etc. The doubled-name case (eclipse-score-score, where the upstream repo is literally called score) preserves the verbatim repo name so the rebase target is unambiguous.

Reproducibility

The fork uses rivet's externals: machinery (see rivet docs cross-repo) to pin all 58 upstream eclipse-score repos by exact commit SHA. The authoritative pin source is the externals: block in rivet.yaml plus the generated rivet.lock. Anyone with a checkout and internet access can materialise the exact corpus state this workspace was validated against:

git clone https://github.com/pulseengine/playground-eclipse-score
cd playground-eclipse-score
make sync         # rivet sync upstreams + create upstream/ symlinks
make convert      # run the RST → YAML converter
make validate     # rivet validate + variant check-all

Upstream clones land in .rivet/repos/<short-name>/ (gitignored, rivet-managed). The Makefile creates upstream/eclipse-score-<X>/ symlinks so the converter's paths stay readable.

The CI workflow at .github/workflows/validate.yml runs the same three targets on every push, pull request, and nightly cron — so the numbers in the table below stay live, not snapshot.

Current state

$ make validate
Result: PASS (2507 warnings)
4/4 variants passed (0 failed)
Stat Value
Upstream eclipse-score repos pinned 58
RST files scanned 919
Sphinx-needs artifacts converted 2985
Repos with at least one need 14
Repos with zero needs (Doxygen-only / toolchain / website) 44
Unknown eclipse need types encountered 0
Unknown option keys encountered 7
needextend rules resolved 114 → 2504 tag mutations
Markdown documents emitted 634
Variant axes in variants/feature-model.yaml 6
Named worked variants 4
rivet variant check-all result 4/4 pass
rivet validate errors 0
rivet validate warnings 2507 (all lifecycle gaps in eclipse data, not schema issues)

Per-repo (top 14 by need count, remaining 44 report 0 needs by design):

Repo RST files Needs converted
eclipse-score-score 404 1373
eclipse-score-process-description 299 1257
eclipse-score-baselibs_rust 21 76
eclipse-score-module_template 39 65
eclipse-score-persistency 30 61
eclipse-score-docs-as-code 24 61
eclipse-score-inc_security_crypto 10 38
eclipse-score-lifecycle 19 28
eclipse-score-inc_someip_gateway 14 12
eclipse-score-baselibs 5 9
eclipse-score-reference_integration 3 2
eclipse-score-score-crates 1 1
eclipse-score-logging 2 1
eclipse-score-inc_os_autosd 1 1

Coverage reports per repo at rivet/<repo>/coverage.md list files scanned, needs converted, anything skipped, and unknown option keys encountered. They're the surface where converter limitations show up.

The conversion path (and every fix the corpus surfaced) is logged in tools/falsification-journey.md — useful if you want to understand the trade-offs the converter makes.

Rebase / reconvert workflow

When upstream eclipse-score moves and the pinned SHAs lag:

# 1. Pull each upstream to its remote HEAD.
make rebase

# 2. Write the new HEADs back into the pin file.
make update-pins                  # rivet lock --update

# 3. Re-run the converter against the new RST.
make convert

# 4. Re-run the oracle. If it does NOT pass, the corpus has surfaced
#    a real gap — either:
#      • eclipse added a new need type / link / option we don't cover
#      • eclipse changed an existing predicate's semantic / target type
#      • eclipse fixed something we were working around
#    Each of those is useful data — fix the converter or schema,
#    re-run, commit the new snapshot.
make validate

The nightly CI cron does the same flow against upstream HEADs with continue-on-error: true — the rebased oracle is informational, not gating, so it tells us when eclipse moved without breaking the main green badge.

How upstream sphinx-needs features map to rivet

For each sphinx-needs feature eclipse uses heavily, the converter either captures it natively, transforms it, or routes to a rivet equivalent. The interesting cases:

Need directives → typed rivet artifacts

Every eclipse need type (~30 of them: stkh_req, feat_req, comp_req, feat, feat_arc_sta/dyn, comp_arc_sta/dyn, logic_arc_int, mod, dd_sta/dyn, sw_unit, tsf, tenet, assertion, workflow, role, workproduct, gd_*, std_*, feat_saf_fmea, comp_saf_fmea, *_saf_dfa, dec_rec, doc_*, testcase, tool_req, aou_req) maps to a corresponding rivet artifact type via TYPE_MAP in tools/score_import.py. Options (:safety:, :security:, :reqtype:, :rationale:, etc.) become typed fields:. Links (:satisfies:, :implements:, :fulfils:, :violates:, :mitigated_by:, etc.) become typed links:.

needextend → baked-in mutations

Sphinx-needs .. needextend:: directives let authors mutate already-declared needs by filter expression (e.g. "every need under process_areas/safety_analysis/ gets +tags: safety_analysis"). The converter pre-scans the RST tree for needextend blocks, evaluates the filter expression at conversion time, and bakes the resulting attribute mutations into the static YAML artifacts. 114 rules across the corpus produce 2504 mutations.

Supported filter shapes (covers all 114 occurrences):

  • docname is not None and "<path>" in docname
  • "<sub>" in id
  • c.this_doc()
  • combinations with and type == "<X>" / and not status

Mutation keys: +tags, +belongs_to (the only two eclipse uses).

Markdown documents from RST surroundings

For every RST file containing at least one need directive, the converter emits a parallel markdown file at rivet/<repo>/docs/<same-path>.md. Section structure is mapped to markdown headings, need declarations become ### {title} followed by an {{artifact:ID:status,safety-level,security}} embed, and inline sphinx-needs :need:X`` roles are rewritten to rivet's [[X]] syntax. Currently 634 documents.

Compliance rendering — handled by rivet's existing surface

Eclipse uses .. needtable:: / .. needpie:: / .. needarch:: directives to embed filtered tables and charts directly in their RST docs. Rivet ships equivalents that consume the same artifact graph:

  • {{coverage}} / {{coverage:rule-name}} — coverage bars per rule
  • {{matrix}} / {{matrix:source:target}} — traceability matrices
  • {{table:TYPE:FIELDS}} — filtered artifact tables
  • {{stats}} / {{stats:types}} / {{stats:status}} — metrics
  • /api/v1/{stats,coverage,artifacts,diagnostics} — JSON API with permissive CORS, intended for Grafana embedding
  • rivet export --format html — static compliance bundle

Authors who want eclipse-style "tables and pies in the doc" use these embeds inside the emitted markdown. The converter doesn't translate the in-doc widgets directly — that's an open item, see the falsification journey doc for the current shape.

Variant model — a starter example

Eclipse-score's stakeholder requirements include a placeholder for variant management (stkh_req__overall_goals__variant_management, status: valid, rationale: tbd). The upstream metamodel does not yet have a variant need type or a binding format.

This playground includes a worked starter feature model under variants/ that captures the variant axes already implicit in eclipse's data:

  • feature-model.yaml — 6 axes (safety-classification, security, requirement-category, process-area, standards-compliance, components), with an attribute-schema for typed attributes and constraints encoding rules like "ASIL-B implies ISO 26262 compliance"
  • bindings.yaml — 4 named worked variants (persistency-qm, persistency-asil-b-secure, platform-only, aspice-assessment)

The model is offered as a starting point an integrator could adopt and extend, not as a proposal for upstream eclipse-score to adopt. Run make variant-check to validate the model + named variants, or make variant-matrix to emit a GitHub Actions CI matrix from the named variants. Both use rivet variant — see rivet docs schemas-overview.

Schema sourcing

vendor/rivet-schemas/ is a pinned copy of rivet/schemas/. It's vendored so this workspace is self-contained — make validate works without a local pulseengine/rivet checkout. The pinning also protects the corpus oracle from being silently invalidated by upstream rivet schema changes.

To refresh from a newer rivet:

cp /path/to/rivet/schemas/*.yaml vendor/rivet-schemas/
make validate

What this is not

To set expectations:

  • Not an alternative to eclipse-score. The upstream project is the source of truth for everything in upstream/. This workspace produces a derived representation; it does not modify, replace, or compete with anything eclipse-score ships.
  • Not a fork in the GitHub sense. No PRs flow from here to eclipse-score; we don't claim to maintain a divergent copy. The word "fork" in the directory name reflects that we hold pinned references to upstream, nothing more.
  • Not endorsed by the Eclipse Foundation or any eclipse-score maintainer. Pulseengine is an independent project at pulseengine.eu. Any issues you find in this workspace's converter or schemas should be filed here, not upstream.
  • Not a guarantee of certification readiness. rivet itself is pre-1.0; this workspace exercises rivet against real data but neither rivet nor this playground has been independently assessed for use as ISO 26262 / DO-178C / IEC 61508 evidence. See rivet's SAFETY.md for its current self-assessed scope.

Archived eclipse-score repos

16 eclipse-score repositories marked archived: true on GitHub are excluded from this workspace per the original fork-setup decision:

examples, inc_abi_compatible_datatypes, inc_ai_platform, inc_config_management, inc_feo, inc_gen_ai, inc_json, inc_mw_com, inc_mw_log, inc_process_test_management, inc_process_variant_management, inc_score_codegen, operating_system, test_integration, test_module_a, test_module_b

Three more repos are external forks (nlohmann_json, bazel_registry_ui, rules_rust) and are skipped because they mirror upstream projects with their own metamodel conventions.

Contributing

PRs welcome for: converter improvements (tools/score_import.py), variant model extensions (variants/), documentation, additional named variants, fixes to the falsification-journey log.

For schema changes that touch vendor/rivet-schemas/, please also file an issue on pulseengine/rivet so the change propagates upstream — the vendored copy is a snapshot, not a fork of the schema itself.

For anything that needs to change in eclipse-score's RST or metamodel, please contribute upstream at the relevant github.com/eclipse-score repository.

License

Apache-2.0 — matches both eclipse-score and rivet. See LICENSE.

The eclipse-score upstream content materialised under .rivet/repos/<X>/ retains its original licensing. The converter output under rivet/<X>/ is a derivative work and inherits the upstream's Apache-2.0 license, plus this workspace's Apache-2.0 for the overlay (converter, schema vendoring, variant model, this README).

About

Eclipse S-CORE typed-traceability playground — 2985 sphinx-needs artifacts converted to rivet typed YAML, with falsification oracle and starter variant model. Not affiliated with the Eclipse Foundation.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors