Skip to content

feat: scope verification reports to a report_version via valid_from - #843

Merged
AlexanderLanin merged 7 commits into
mainfrom
feat/report-version-scoping
Sep 22, 2026
Merged

AlexanderLanin merged 7 commits into
mainfrom
feat/report-version-scoping

Conversation

@antonkri

@antonkri antonkri commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Stacked on #839 (targets that branch, not main, so the diff here only shows the two commits below; it will show against main once #839 merges and this PR's base is retargeted).

Why

module_verification_report and platform_verification_report (see #839) always show every Requirement/Feature/Component in the current build. There is no way to scope either report to "everything relevant for release X", even though the metamodel already has a valid_from/valid_until attribute on feat_req/stkh_req for exactly this purpose (see tool_req__docs_req_attr_validity_correctness).

What changed

  • src/extensions/score_metamodel/metamodel.yaml: new optional report_version attribute on the document need type, using the same vMAJOR.MINOR[.PATCH] format already enforced for valid_from/valid_until.
  • src/extensions/score_sphinx_needs_templates/__init__.py: two new render-context helpers.
    • req_in_scope(need, report_version) decides whether a single requirement Need is in scope. feat_req/stkh_req carry valid_from directly; comp_req has no valid_from of its own, so it inherits scope from the feat_req it is derived_from. A requirement with no resolvable valid_from is excluded whenever a report_version is set.
    • any_req_in_scope(reqs, report_version) decides whether a Feature/Component has any requirement in scope.
  • src/needs_templates/module_verification_report.need and src/needs_templates/platform_verification_report.need use these helpers to:
    • restrict the Requirements Statistics needpies and the requirements needtable to id in [...] the in-scope requirement IDs, and
    • drop a Feature/Component from the report entirely (Overview table and its whole detail section) when none of its requirements are in scope, instead of rendering an empty section.
  • An unset/empty report_version keeps a report fully unscoped (all Features/Components/requirements shown), which is what doc__platform_verification_report_latest and similar "latest" reports rely on — this is opt-in and backward compatible.

@github-actions

Copy link
Copy Markdown
Contributor

Documentation preview for this pull request is available at:
pr-843: https://eclipse-score.github.io/docs-as-code/pr-843/

@antonkri
antonkri force-pushed the feat/report-version-scoping branch from 2e26aec to c565de1 Compare September 21, 2026 07:30
@antonkri

Copy link
Copy Markdown
Contributor Author

@AlexanderLanin as requested, please review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Release scoping ignores the exclusive valid_until boundary and lacks focused behavioral tests.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Adds opt-in release-version scoping to module and platform verification reports.

Changes:

  • Adds report_version metadata and requirement-scope helpers.
  • Filters report sections, statistics, and tables by requirement validity.
  • Updates generated Needs JSON fixtures.
File Description
src/​extensions/​score_metamodel/​metamodel.yaml Defines report_version.
src/​extensions/​score_sphinx_needs_templates/​__init__.py Implements scope helpers.
src/​needs_templates/​module_verification_report.need Scopes component reporting.
src/​needs_templates/​platform_verification_report.need Scopes feature reporting.
src/​tests/​docs_bzl/​scenarios/​basic_docs/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​data_files_runfiles/​_expected/​data_bundle_needs/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​data_files_runfiles/​_expected/​isolated_source_bundle_needs/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​data_files_runfiles/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​nested_bundles/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​reference_integration/​_expected/​needs_local.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​reference_integration/​legacy_module/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​reference_integration/​legacy_module/​docs/​components/​component/​_expected/​needs_local.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​reference_integration/​modern_module/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​reference_integration/​modern_module/​docs/​components/​unlinked_component/​_expected/​needs_local.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​reference_integration/​score_platform/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​subdirectory_bundle/​consumer/​_expected/​needs_json/​needs.json Updates expected schema.
src/​tests/​docs_bzl/​scenarios/​subdirectory_bundle/​producer/​_expected/​needs_json/​needs.json Updates expected schema.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +214 to +219
valid_from = need.get("valid_from")
if valid_from:
try:
return _parse_version(valid_from) <= _parse_version(report_version)
except ValueError:
return False

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and you're right that it's inconsistent with the documented valid_from/valid_until semantics (tool_req__docs_req_attr_validity_correctness: "from" inclusive, "until" exclusive).

This is intentional scope for this PR, though: report_version here answers "everything relevant as of release X" (a snapshot of what should exist by then), not "everything still valid in release X" (which would additionally need the valid_until exclusion you describe). We deliberately kept it to the simpler valid_from-only check for the initial version of this feature - happy to open a follow-up to add report_version < valid_until support (with comp_req inheriting the full interval via derived_from, as you suggest) once there's a concrete need for it, rather than speculatively building it now.

Added focused unit tests for the current behavior (including the comp_req/derived_from inheritance path and malformed-value handling) in b71c770.

before.
"""

def __call__(self, need: NeedItem, report_version: str | None) -> bool:
)
app.config.needs_render_context.setdefault("linked_needs", _linked_needs_callable)
app.config.needs_render_context.setdefault("needs_of_type", _needs_of_type_callable)
app.config.needs_render_context.setdefault("req_in_scope", _req_in_scope_callable)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

req_in_scope does not really imply "version". Maybe "req_in_report_version"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, renamed to req_in_report_version in 0cd3801.

app.config.needs_render_context.setdefault("needs_of_type", _needs_of_type_callable)
app.config.needs_render_context.setdefault("req_in_scope", _req_in_scope_callable)
app.config.needs_render_context.setdefault(
"any_req_in_scope", _any_req_in_scope_callable

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here. Like any_req_in_report_version. Or something prettier.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to any_req_in_report_version in 0cd3801, thanks.

module_verification_report previously rendered both the module's own
components AND every Feature reachable from those components, mixing
module-scoped and platform-scoped statistics into a single report.

- module_verification_report.need: drop the feature-loop section
  (Requirements/Architecture/Inspection Statistics per Feature). The
  report now covers Components only, as its name implies.
- platform_verification_report.need (new): the feature-scoped
  counterpart, listing every Feature in the current build (via the
  existing needs_of_type("feat") helper) with the same statistics that
  were removed from the module report.
@antonkri
antonkri force-pushed the feat/split-platform-verification-report branch from 11e4c89 to 3046110 Compare September 21, 2026 09:35
Adds an optional report_version attribute on document Needs. When set,
module_verification_report and platform_verification_report only show
requirements (and the Features/Components that own them) with
valid_from <= report_version. comp_req has no valid_from of its own,
so its scope is inherited from the feat_req it is derived_from.
Features/Components with no in-scope requirement are dropped from the
report entirely instead of rendering an empty section. Unset/empty
report_version keeps reports unscoped, matching prior behavior.
- ruff-format src/extensions/score_sphinx_needs_templates/__init__.py
  (2 lines that now fit on one line each).
- Regenerate the 13 checked-in _expected/needs_json + needs_local.json
  fixtures under src/tests/docs_bzl/scenarios to include the new
  report_version extra-option schema entry, matching what
  test_docs_bzl_scenario_expected_output already wrote locally when it
  detected the diff (CI fails this test on purpose after auto-updating,
  so the updated files can be reviewed and committed).
Adds focused unit tests for the report_version scoping helpers added
in a previous commit, addressing a PR review finding that only the
generated-schema fixtures exercised report_version, with no direct
coverage of the filtering logic itself:
- unscoped (no report_version) always includes everything
- valid_from boundary is inclusive
- malformed valid_from is excluded rather than raising
- comp_req with no valid_from and nothing to inherit is excluded
- comp_req inherits its scope from the feat_req it is derived_from
- any_req_in_scope for empty/matching/non-matching requirement lists
Per review feedback: 'scope' didn't make clear these helpers are about
report_version specifically. Renames the Jinja render-context globals
and their backing classes/instances:
- req_in_scope -> req_in_report_version (_RequirementInScope ->
  _RequirementInReportVersion)
- any_req_in_scope -> any_req_in_report_version
  (_AnyRequirementInScope -> _AnyRequirementInReportVersion)

Updates the two .need template call sites and the unit tests
accordingly. No behavior change.
@antonkri
antonkri force-pushed the feat/report-version-scoping branch from 0cd3801 to 9c26357 Compare September 21, 2026 09:36
@AlexanderLanin
AlexanderLanin changed the base branch from feat/split-platform-verification-report to main September 21, 2026 22:02
@AlexanderLanin

Copy link
Copy Markdown
Member

LGTM, but I would like to merge #841 first

@antonkri

Copy link
Copy Markdown
Contributor Author

#841

Hey @AlexanderLanin , why should #841 first? From my point of view there are no correlations.

@AlexanderLanin

Copy link
Copy Markdown
Member

@copilot resolve the merge conflicts in this pull request. This PR adds report_version support to the templates.

@MaximilianSoerenPollak MaximilianSoerenPollak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments.

I think this is a good idea, just had some questions.

Comment on lines +218 to +219
except ValueError:
return False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion this can never happen, or am I thinking wrong?

I do like defensive programming, but this seems a bit weird.
If anything this defence may should be in the parser.

return any(self(feat_req, report_version) for feat_req in linked_feat_reqs)


_req_in_report_version_callable = _RequirementInReportVersion()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single variable indirections are useless imo.
Makes it harder to read.

You are only using htem on 2 places, so this makes no sense to put into a variable that is also the same lenght...

Comment thread src/extensions/score_sphinx_needs_templates/__init__.py
…coping

# Conflicts:
#	src/needs_templates/module_verification_report.need
#	src/needs_templates/platform_verification_report.need

Co-authored-by: AlexanderLanin <5074553+AlexanderLanin@users.noreply.github.com>

Copilot AI commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request. This PR adds report_version support to the templates.

Resolved by merging main into this branch and fixing the template conflicts in merge commit afe61f5.

@AlexanderLanin
AlexanderLanin merged commit c65a0e8 into main Sep 22, 2026
25 checks passed
@AlexanderLanin
AlexanderLanin deleted the feat/report-version-scoping branch September 22, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

5 participants