Skip to content

Fix SPDX 3.0.1 opaque metadata in Annotations (#299) - #304

Merged
pellecchialuigi merged 3 commits into
mainfrom
issue-299
Aug 7, 2026
Merged

Fix SPDX 3.0.1 opaque metadata in Annotations (#299)#304
pellecchialuigi merged 3 commits into
mainfrom
issue-299

Conversation

@pellecchialuigi

Copy link
Copy Markdown
Collaborator

Address the 3.0.1-addressable portion of the opaque-metadata gap identified in elisa-tech/Safety_Architecture_WG#18 (Gap 4).

All BASIL-specific metadata was previously serialised as raw JSON strings inside Annotation.statement fields, making entity identifiers and titles invisible to standard SPDX-aware tooling.

Changes in api/spdx_manager.py:

  • Add BASIL_ANNOTATION_VERSION = "2.0" constant so consumers can distinguish the new annotation schema from the old one.

  • Add SPDXExternalIdentifier class that serialises as a SPDX 3.0.1 ExternalIdentifier inline object (externalIdentifierType "other"). The identifier follows the convention basil:<db_tablename>:<db_id>, using the model's tablename directly to stay in sync with the database schema without a separate mapping layer.

  • Extend SPDXFile with an optional external_identifiers list; to_dict() emits "externalIdentifier": [...] when the list is non-empty.

  • Populate ExternalIdentifier on every persisted BASIL entity: apis, sw_requirements, test_specifications, test_cases, documents, justifications, test_runs.

  • Inject "basil:annotationVersion": "2.0" into every Annotation.statement automatically inside SPDXAnnotation.init, with no changes required at call sites.

  • Add clean_entity_annotation_dict() helper that strips "id" and "title" from entity annotation payloads — both fields are now carried by the ExternalIdentifier on the element itself.

  • Add clean_snippet_annotation_dict() helper that strips "offset", "section", and "coverage" from snippet annotation payloads — these are already represented in software_byteRange and Relationship.completeness respectively.

Changes in api/test/test_spdx_api_validation.py:

  • Add helper functions _export_and_parse(), _external_identifiers_for(), and _assert_external_identifier() shared by the new tests.

  • Add one dedicated test per entity type (api, sw_requirements, test_specifications, test_cases, justifications, documents, test_runs) that asserts the ExternalIdentifier carries the correct basil:: identifier and a comment containing the entity id.

  • Add test_spdx_annotation_version_injected: every Annotation.statement
    must contain "basil:annotationVersion": "2.0".

  • Add test_spdx_entity_annotations_have_no_id_or_title: entity annotation statements must not contain "id" or "title".

  • Add test_spdx_snippet_annotations_stripped: snippet annotation statements must not contain "offset", "section", or "coverage".

Address the 3.0.1-addressable portion of the opaque-metadata gap identified
in elisa-tech/Safety_Architecture_WG#18 (Gap 4).

All BASIL-specific metadata was previously serialised as raw JSON strings
inside Annotation.statement fields, making entity identifiers and titles
invisible to standard SPDX-aware tooling.

Changes in api/spdx_manager.py:

- Add BASIL_ANNOTATION_VERSION = "2.0" constant so consumers can
  distinguish the new annotation schema from the old one.

- Add SPDXExternalIdentifier class that serialises as a SPDX 3.0.1
  ExternalIdentifier inline object (externalIdentifierType "other").
  The identifier follows the convention basil:<db_tablename>:<db_id>,
  using the model's __tablename__ directly to stay in sync with the
  database schema without a separate mapping layer.

- Extend SPDXFile with an optional external_identifiers list; to_dict()
  emits "externalIdentifier": [...] when the list is non-empty.

- Populate ExternalIdentifier on every persisted BASIL entity:
  apis, sw_requirements, test_specifications, test_cases, documents,
  justifications, test_runs.

- Inject "basil:annotationVersion": "2.0" into every Annotation.statement
  automatically inside SPDXAnnotation.__init__, with no changes required
  at call sites.

- Add clean_entity_annotation_dict() helper that strips "id" and "title"
  from entity annotation payloads — both fields are now carried by the
  ExternalIdentifier on the element itself.

- Add clean_snippet_annotation_dict() helper that strips "offset",
  "section", and "coverage" from snippet annotation payloads — these are
  already represented in software_byteRange and Relationship.completeness
  respectively.

Changes in api/test/test_spdx_api_validation.py:

- Add helper functions _export_and_parse(), _external_identifiers_for(),
  and _assert_external_identifier() shared by the new tests.

- Add one dedicated test per entity type (api, sw_requirements,
  test_specifications, test_cases, justifications, documents, test_runs)
  that asserts the ExternalIdentifier carries the correct
  basil:<tablename>:<id> identifier and a comment containing the entity id.

- Add test_spdx_annotation_version_injected: every Annotation.statement
  must contain "basil:annotationVersion": "2.0".

- Add test_spdx_entity_annotations_have_no_id_or_title: entity annotation
  statements must not contain "id" or "title".

- Add test_spdx_snippet_annotations_stripped: snippet annotation statements
  must not contain "offset", "section", or "coverage".

Signed-off-by: Luigi Pellecchia <pellecchia.luigi@gmail.com>
Commit #303 ("Fix SPDX 3.0.1 relationship type gaps") changed the
relationship type emitted for SW requirement -> test case links from
"hasTest" to the more specific SPDX 3.0.1 type "hasTestCase", but the
assertion added by commit #302 in
test_spdx_sw_requirement_children_exported was never updated to match,
causing a spurious CI failure.

Update the assertion and its error message to check for "hasTestCase"
so the test reflects the relationship type actually emitted by
addSwRequirementTestCases.

Signed-off-by: Luigi Pellecchia <pellecchia.luigi@gmail.com>
Signed-off-by: Luigi Pellecchia <pellecchia.luigi@gmail.com>
@pellecchialuigi
pellecchialuigi merged commit e64a45e into main Aug 7, 2026
3 of 4 checks passed
@pellecchialuigi
pellecchialuigi deleted the issue-299 branch August 7, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant