Skip to content
1 change: 1 addition & 0 deletions .cspell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ words:
- mstest
- myterm
- nameof
- netstandard
- ncipollo
- Neko
- NOASSERTION
Expand Down
75 changes: 74 additions & 1 deletion .reviewmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
# Patterns identifying all files that require review.
# Processed in order; prefix a pattern with '!' to exclude.
needs-review:
- "requirements.yaml" # Root requirements file
- "docs/reqstream/**/*.yaml" # Requirements files
- "docs/design/**/*.md" # Design documentation
- "**/*.cs" # All C# source and test files
- "!**/obj/**" # Exclude build output
- "!**/bin/**" # Exclude build output
Expand All @@ -21,4 +24,74 @@ evidence-source:
# Review sets grouping files by logical unit of review.
# Each review-set groups requirements, source, and tests for a coherent software unit
# so that an AI-assisted review can verify consistency across the full evidence chain.
reviews: []
reviews:
- id: SpdxModel-System
title: SpdxModel System Review
paths:
- "docs/reqstream/system.yaml"
- "docs/design/introduction.md"
- "docs/design/system.md"
- "docs/reqstream/spdx-annotation.yaml"
Comment thread
Malcolmnixon marked this conversation as resolved.
Outdated
- "docs/reqstream/spdx-checksum.yaml"
- "docs/reqstream/spdx-creation-information.yaml"
- "docs/reqstream/spdx-external-document-reference.yaml"
- "docs/reqstream/spdx-external-reference.yaml"
- "docs/reqstream/spdx-extracted-licensing-info.yaml"
- "docs/reqstream/spdx-file.yaml"
- "docs/reqstream/spdx-package.yaml"
- "docs/reqstream/spdx-package-verification-code.yaml"
- "docs/reqstream/spdx-relationship.yaml"
- "docs/reqstream/spdx-snippet.yaml"
- "docs/design/spdx-annotation.md"
- "docs/design/spdx-checksum.md"
- "docs/design/spdx-creation-information.md"
- "docs/design/spdx-document.md"
- "docs/design/spdx-element.md"
- "docs/design/spdx-external-document-reference.md"
- "docs/design/spdx-external-reference.md"
- "docs/design/spdx-extracted-licensing-info.md"
- "docs/design/spdx-file.md"
- "docs/design/spdx-helpers.md"
- "docs/design/spdx-license-element.md"
- "docs/design/spdx-package.md"
- "docs/design/spdx-package-verification-code.md"
- "docs/design/spdx-relationship.md"
- "docs/design/spdx-snippet.md"

- id: SpdxModel-Design
title: SpdxModel Design Review
paths:
- "docs/reqstream/system.yaml"
- "docs/reqstream/platform-requirements.yaml"
- "docs/design/**/*.md"

- id: SpdxModel-AllRequirements
title: SpdxModel All Requirements Review
paths:
- "requirements.yaml"
- "docs/reqstream/**/*.yaml"

- id: SpdxModel-IO
title: SpdxModel IO Subsystem Review
paths:
- "docs/reqstream/io/io.yaml"
- "docs/reqstream/io/spdx-2-json-deserializer.yaml"
- "docs/reqstream/io/spdx-2-json-serializer.yaml"
- "docs/design/io/io.md"
- "docs/design/io/spdx-2-json-deserializer.md"
- "docs/design/io/spdx-2-json-serializer.md"
- "docs/design/io/spdx-constants.md"
- "src/DemaConsulting.SpdxModel/IO/Spdx2JsonDeserializer.cs"
- "src/DemaConsulting.SpdxModel/IO/Spdx2JsonSerializer.cs"
- "src/DemaConsulting.SpdxModel/IO/SpdxConstants.cs"
- "test/DemaConsulting.SpdxModel.Tests/IO/**/*.cs"

- id: SpdxModel-Transform
title: SpdxModel Transform Subsystem Review
paths:
- "docs/reqstream/transform/transform.yaml"
- "docs/reqstream/transform/spdx-relationships.yaml"
- "docs/design/transform/transform.md"
- "docs/design/transform/spdx-relationships.md"
- "src/DemaConsulting.SpdxModel/Transform/SpdxRelationships.cs"
- "test/DemaConsulting.SpdxModel.Tests/Transforms/SpdxRelationshipsTests.cs"
Comment thread
Malcolmnixon marked this conversation as resolved.
109 changes: 109 additions & 0 deletions docs/design/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# DemaConsulting.SpdxModel Design Documentation

## Purpose

This document provides the design overview for the DemaConsulting.SpdxModel library, a .NET library
for reading, writing, and manipulating SPDX (Software Package Data Exchange) documents. It serves as
the entry point for the design documentation, providing architectural context for formal code review,
compliance auditing, and maintenance support.

## Scope

This design documentation covers the DemaConsulting.SpdxModel library, including:

- The SPDX data model (documents, packages, files, snippets, relationships, annotations, checksums, etc.)
- JSON serialization and deserialization (SPDX 2.2 and SPDX 2.3)
- Relationship manipulation utilities

Excluded from scope:

- Consumer application code using this library
- CI/CD pipeline configuration
- NuGet package distribution infrastructure

## Software Structure

```text
DemaConsulting.SpdxModel (System)
├── IO (Subsystem)
│ ├── Spdx2JsonDeserializer (Unit)
│ ├── Spdx2JsonSerializer (Unit)
│ └── SpdxConstants (Unit)
├── Transform (Subsystem)
│ └── SpdxRelationships (Unit)
├── SpdxAnnotation (Unit)
├── SpdxChecksum (Unit)
├── SpdxCreationInformation (Unit)
├── SpdxDocument (Unit)
├── SpdxElement (Unit)
├── SpdxExternalDocumentReference (Unit)
├── SpdxExternalReference (Unit)
├── SpdxExtractedLicensingInfo (Unit)
├── SpdxFile (Unit)
├── SpdxHelpers (Unit)
├── SpdxLicenseElement (Unit)
├── SpdxPackage (Unit)
├── SpdxPackageVerificationCode (Unit)
├── SpdxRelationship (Unit)
└── SpdxSnippet (Unit)
```

OTS Software Items:

- MSTest — unit test framework
- ReqStream — requirements traceability enforcement
- BuildMark — build notes documentation generation
- VersionMark — tool version documentation
- SarifMark — CodeQL SARIF report generation
- SonarMark — SonarCloud quality report generation

## Folder Layout

```text
src/DemaConsulting.SpdxModel/
├── IO/
│ ├── Spdx2JsonDeserializer.cs — SPDX 2.x JSON deserialization
│ ├── Spdx2JsonSerializer.cs — SPDX 2.x JSON serialization
│ └── SpdxConstants.cs — SPDX constants
├── Transform/
│ └── SpdxRelationships.cs — Relationship manipulation utilities
├── SpdxAnnotation.cs — Annotation data model
├── SpdxAnnotationType.cs — Annotation type enum
├── SpdxChecksum.cs — Checksum data model
├── SpdxChecksumAlgorithm.cs — Checksum algorithm enum
├── SpdxCreationInformation.cs — Creation information data model
├── SpdxDocument.cs — Document data model
├── SpdxElement.cs — Base element class
├── SpdxExternalDocumentReference.cs — External document reference model
├── SpdxExternalReference.cs — External reference data model
├── SpdxExtractedLicensingInfo.cs — Extracted licensing info model
├── SpdxFile.cs — File data model
├── SpdxFileType.cs — File type enum
├── SpdxHelpers.cs — Helper utilities
├── SpdxLicenseElement.cs — License element base class
├── SpdxPackage.cs — Package data model
├── SpdxPackageVerificationCode.cs — Package verification code model
├── SpdxReferenceCategory.cs — Reference category enum
├── SpdxRelationship.cs — Relationship data model
├── SpdxRelationshipType.cs — Relationship type enum
└── SpdxSnippet.cs — Snippet data model

test/DemaConsulting.SpdxModel.Tests/
├── IO/
│ ├── Examples/ — Test example JSON files
│ └── (Spdx2JsonDeserialize*.cs and Spdx2JsonSerialize*.cs test files)
├── Transforms/
│ └── SpdxRelationshipsTests.cs — Relationship utility tests
├── SpdxAnnotationTests.cs
├── SpdxChecksumTests.cs
├── SpdxCreationInformationTests.cs
├── SpdxDocumentTests.cs
├── SpdxExternalDocumentReferenceTests.cs
├── SpdxExternalReferenceTests.cs
├── SpdxExtractedLicensingInfoTests.cs
├── SpdxFileTests.cs
├── SpdxPackageTests.cs
├── SpdxPackageVerificationCodeTests.cs
├── SpdxRelationshipTests.cs
└── SpdxSnippetTests.cs
```
53 changes: 53 additions & 0 deletions docs/design/io/io.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# IO Subsystem Design

## Purpose

The IO subsystem provides JSON serialization and deserialization for SPDX 2.x documents,
converting between the in-memory `SpdxDocument` object model and SPDX JSON files conforming
to the SPDX 2.2 and 2.3 specifications.

## Units

| Unit | File | Responsibility |
| ---- | ---- | -------------- |
| `Spdx2JsonDeserializer` | `IO/Spdx2JsonDeserializer.cs` | Reads SPDX 2.x JSON into the object model |
| `Spdx2JsonSerializer` | `IO/Spdx2JsonSerializer.cs` | Writes the object model to SPDX 2.x JSON |
| `SpdxConstants` | `IO/SpdxConstants.cs` | String constants for SPDX JSON field names |

## Design

### Spdx2JsonDeserializer

`Spdx2JsonDeserializer` reads a JSON stream or string and populates a `SpdxDocument`. It uses
`System.Text.Json` `JsonDocument` for DOM-based parsing, navigating named properties to
reconstruct each element. Both SPDX 2.2 and 2.3 JSON schemas are supported; version differences
are handled transparently during parsing.

Key design decisions:

- DOM-based parsing (rather than streaming) to allow forward references between document elements
- Graceful handling of optional SPDX fields (missing fields result in default values)

### Spdx2JsonSerializer

`Spdx2JsonSerializer` takes an `SpdxDocument` and writes it to a `Utf8JsonWriter`. It iterates
over each element collection in document order, writing the appropriate JSON structure for each
SPDX element type.
Comment thread
Malcolmnixon marked this conversation as resolved.
Outdated

Key design decisions:

- Output follows SPDX 2.3 JSON schema by default
- Optional fields are omitted when empty or null to keep output clean

### SpdxConstants

`SpdxConstants` is a static class holding string constants for every JSON property name used in
the SPDX 2.x JSON format. Using named constants prevents typos and centralizes the mapping
between the object model and the serialized form.

## Dependencies

The IO subsystem depends on:

- `System.Text.Json` (BCL / NuGet)
- All data model units in the root namespace (`SpdxDocument`, `SpdxPackage`, etc.)
35 changes: 35 additions & 0 deletions docs/design/io/spdx-2-json-deserializer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Spdx2JsonDeserializer Unit Design

## Purpose

`Spdx2JsonDeserializer` reads SPDX 2.x JSON documents and populates the in-memory `SpdxDocument`
object model. It supports both the SPDX 2.2 and SPDX 2.3 JSON schemas, handling version
differences transparently during parsing.

## Design

`Spdx2JsonDeserializer` is a public static class with no instance state. All public entry points
accept either a JSON string or a `JsonNode` and return strongly typed model objects.

Key design decisions:

- DOM-based parsing via `System.Text.Json.Nodes` (`JsonNode`/`JsonArray`) to allow forward
references between document elements before the full document is assembled.
- Graceful handling of optional SPDX fields: missing properties result in default values rather
than exceptions.
- Per-element `Deserialize*` methods (`DeserializePackage`, `DeserializeFile`, etc.) are public
to support targeted unit testing and partial deserialization.

Key methods:

| Method | Description |
| ------ | ----------- |
| `Deserialize(string)` | Entry point — parses a raw JSON string into an `SpdxDocument` |
| `DeserializeDocument(JsonNode)` | Converts a parsed `JsonNode` tree into an `SpdxDocument` |
| `Deserialize*(JsonNode?)` | Per-element helpers for each SPDX element type |

## Dependencies

- `System.Text.Json` (BCL) — JSON DOM parsing via `JsonNode`
- `SpdxDocument` and all data model units in the root namespace
- `SpdxConstants` — string constants for JSON property names
35 changes: 35 additions & 0 deletions docs/design/io/spdx-2-json-serializer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Spdx2JsonSerializer Unit Design

## Purpose

`Spdx2JsonSerializer` converts an in-memory `SpdxDocument` object model to an SPDX 2.3 JSON
string. It is the counterpart to `Spdx2JsonDeserializer` and completes the round-trip
serialization support for the IO subsystem.

## Design

`Spdx2JsonSerializer` is a public static class with no instance state. All public methods
accept strongly typed model objects and return `JsonObject`/`JsonArray` nodes or a final JSON
string.

Key design decisions:

- Output conforms to SPDX 2.3 JSON schema.
- Optional fields are omitted entirely (not written as `null`) when empty or null to keep
output concise and compatible with strict schema validators.
- Per-element `Serialize*` methods (`SerializePackage`, `SerializeFile`, etc.) are public to
support targeted unit testing and partial serialization.

Key methods:

| Method | Description |
| ------ | ----------- |
| `Serialize(SpdxDocument)` | Entry point — returns a complete SPDX JSON string |
| `SerializeDocument(SpdxDocument)` | Converts an `SpdxDocument` to a `JsonObject` |
| `Serialize*(…)` | Per-element helpers for each SPDX element type |

## Dependencies

- `System.Text.Json` (BCL) — JSON node construction via `JsonObject`/`JsonArray`
- `SpdxDocument` and all data model units in the root namespace
- `SpdxConstants` — string constants for JSON property names
24 changes: 24 additions & 0 deletions docs/design/io/spdx-constants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SpdxConstants Unit Design

## Purpose

`SpdxConstants` is a static class that centralizes all JSON property-name strings used when
serializing and deserializing SPDX 2.x JSON documents. It eliminates hard-coded string literals
scattered throughout the IO subsystem and provides a single place to update field names if the
specification changes.

## Design

`SpdxConstants` is a non-instantiable static class containing only `public const string` fields.
Each constant corresponds to one JSON property name in the SPDX 2.x JSON schema (e.g.,
`FieldSpdxId`, `FieldName`, `FieldVersionInfo`).

Key design decisions:

- All constants are `const string` to allow use as switch-case labels and compile-time
embedding.
- No logic or state — purely a name registry.

## Dependencies

- None (no external dependencies; consumed by `Spdx2JsonDeserializer` and `Spdx2JsonSerializer`)
32 changes: 32 additions & 0 deletions docs/design/spdx-annotation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SpdxAnnotation Unit Design

## Purpose

`SpdxAnnotation` represents an SPDX annotation — a comment or review note attached to any SPDX
element by a person, organization, or tool. Annotations support compliance workflows where
reviewers document findings about software components.

## Design

`SpdxAnnotation` is a sealed class that extends `SpdxElement` (inheriting the `Id` field).

Data members:

| Property | Type | Description |
| -------- | ---- | ----------- |
| `Annotator` | `string` | Person, organization, or tool that made the annotation |
| `Date` | `string` | ISO 8601 UTC timestamp of the annotation |
| `Type` | `SpdxAnnotationType` | Enumerated annotation type (Review, Other) |
| `Comment` | `string` | Free-text annotation content |

Key methods:

- `DeepCopy()` — returns a new `SpdxAnnotation` with all fields copied
- `Enhance(SpdxAnnotation)` — fills in missing fields from another instance
- `Validate(List<string>)` — appends validation issues to the supplied list
- `Same` — static `IEqualityComparer<SpdxAnnotation>` comparing annotator, date, type, and comment

## Dependencies

- `SpdxElement` (base class)
- `SpdxAnnotationType` (enum)
Loading
Loading