From b976f96776398f8fd35eae571ffaef5b77fa4b31 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Sat, 11 Jul 2026 15:44:44 -0400 Subject: [PATCH] Add SysML2 architecture model support and update documentation - Scaffold docs/sysml2/ model and design-views with sysml2tools wired into lint.ps1, build.yaml, .config/dotnet-tools.json, .versionmark.yaml - Refactor docs/design/introduction.md to reference the generated SoftwareStructureView diagram instead of a hand-maintained tree - Embed per-subsystem/unit diagrams across docs/design/test-results-library/** - Rework .reviewmark.yaml to match the updated reviewmark-usage standard (Purpose/Decomposition review-sets, context blocks, NamespaceDoc.cs relocated to their owning system/subsystem review-sets) - Fix docs/design/test-results-library/io/serializer-helpers.md heading (Key Properties -> Key Methods) found during formal review - Add sysml, sysml2tools to cspell words Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .config/dotnet-tools.json | 6 + .cspell.yaml | 2 + .github/agents/formal-review.agent.md | 12 +- .github/agents/template-sync.agent.md | 2 + .github/skills/sysml2tools-query/SKILL.md | 145 +++++++++++ .github/standards/design-documentation.md | 12 +- .github/standards/reviewmark-usage.md | 136 +++++----- .github/standards/software-items.md | 5 + .github/standards/sysml2-modeling.md | 232 ++++++++++++++++++ .github/workflows/build.yaml | 16 +- .reviewmark.yaml | 77 +++++- .versionmark.yaml | 5 + AGENTS.md | 15 +- docs/design/introduction.md | 25 +- docs/design/test-results-library.md | 2 + docs/design/test-results-library/io.md | 2 + .../io/junit-serializer.md | 2 + .../io/serializer-helpers.md | 4 +- .../test-results-library/io/serializer.md | 2 + .../test-results-library/io/trx-serializer.md | 2 + .../test-results-library/test-outcome.md | 2 + .../test-results-library/test-result.md | 2 + .../test-results-library/test-results.md | 2 + docs/sysml2/model/test-results-library.sysml | 21 ++ .../model/test-results-library/io.sysml | 15 ++ .../io/junit-serializer.sysml | 11 + .../io/serializer-helpers.sysml | 11 + .../test-results-library/io/serializer.sysml | 11 + .../io/trx-serializer.sysml | 11 + .../test-results-library/test-outcome.sysml | 11 + .../test-results-library/test-result.sysml | 11 + .../test-results-library/test-results.sysml | 11 + docs/sysml2/views/design-views.sysml | 18 ++ lint.ps1 | 6 + 34 files changed, 751 insertions(+), 96 deletions(-) create mode 100644 .github/skills/sysml2tools-query/SKILL.md create mode 100644 .github/standards/sysml2-modeling.md create mode 100644 docs/sysml2/model/test-results-library.sysml create mode 100644 docs/sysml2/model/test-results-library/io.sysml create mode 100644 docs/sysml2/model/test-results-library/io/junit-serializer.sysml create mode 100644 docs/sysml2/model/test-results-library/io/serializer-helpers.sysml create mode 100644 docs/sysml2/model/test-results-library/io/serializer.sysml create mode 100644 docs/sysml2/model/test-results-library/io/trx-serializer.sysml create mode 100644 docs/sysml2/model/test-results-library/test-outcome.sysml create mode 100644 docs/sysml2/model/test-results-library/test-result.sysml create mode 100644 docs/sysml2/model/test-results-library/test-results.sysml create mode 100644 docs/sysml2/views/design-views.sysml diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 43e6eb6..8d3d850 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -61,6 +61,12 @@ "commands": [ "dotnet-sonarscanner" ] + }, + "demaconsulting.sysml2tools.tool": { + "version": "0.1.0-beta.5", + "commands": [ + "sysml2tools" + ] } } } \ No newline at end of file diff --git a/.cspell.yaml b/.cspell.yaml index e94ac6d..a988ace 100644 --- a/.cspell.yaml +++ b/.cspell.yaml @@ -32,6 +32,8 @@ words: - slnx - sonar - sonarmark + - sysml + - sysml2tools - versionmark - Weasy - Weasyprint diff --git a/.github/agents/formal-review.agent.md b/.github/agents/formal-review.agent.md index 14e487a..cb78ddf 100644 --- a/.github/agents/formal-review.agent.md +++ b/.github/agents/formal-review.agent.md @@ -31,12 +31,14 @@ standards from the selection matrix in AGENTS.md. 1. Download the review checklist from . If the download fails, report the failure rather than proceeding without the template. -2. Use `dotnet reviewmark --elaborate {review-set}` to get the files to review -3. Review all files holistically, checking for cross-file consistency and - compliance with the review checklist -4. Save the populated review checklist to `.agent-logs/reviews/review-report-{review-set}.md`. +2. Run `dotnet reviewmark --elaborate {review-set}`. Read all files listed under + `## Context` first — these are reference material, not under review — then review + all files listed under `## Files` holistically, using the context to understand + the intended role and scope within the broader system, and checking for cross-file + consistency and compliance with the review checklist. +3. Save the populated review checklist to `.agent-logs/reviews/review-report-{review-set}.md`. This directory holds formal review artifacts, not agent logs. -5. Generate a completion report per the AGENTS.md reporting requirements. +4. Generate a completion report per the AGENTS.md reporting requirements. # Report Template diff --git a/.github/agents/template-sync.agent.md b/.github/agents/template-sync.agent.md index df4d488..baf5fa8 100644 --- a/.github/agents/template-sync.agent.md +++ b/.github/agents/template-sync.agent.md @@ -21,6 +21,8 @@ Delegate each group to a sub-agent. # Work Groups - **Root config files** - all non-collection files at the repository root +- **`docs/sysml2/`** - SysML2 model files and rendered views (root-level flat folder, + not a Pandoc collection) - **One group per flat `docs/` folder** - e.g. `docs/build_notes/`, `docs/user_guide/` - **One group for root files in each of `docs/design/`, `docs/verification/`, `docs/reqstream/`** - e.g. `docs/design/introduction.md` — separate from the diff --git a/.github/skills/sysml2tools-query/SKILL.md b/.github/skills/sysml2tools-query/SKILL.md new file mode 100644 index 0000000..f754338 --- /dev/null +++ b/.github/skills/sysml2tools-query/SKILL.md @@ -0,0 +1,145 @@ +--- +name: sysml2tools-query +description: Query this repository's SysML2 architecture model (docs/sysml2/) to understand software structure, purpose, and relationships before deep-diving into source code. Use this when asked to understand the codebase, find which unit implements something, assess the impact of a change, or trace requirements to code. +--- + +# SysML2Tools Query Skill + +This repository models its software structure in SysML2 under `docs/sysml2/`. Prefer +querying this model over grepping/reading source files when you need to understand +*what* a piece of the system is, *why* it exists, or *what it depends on*. + +## Prerequisites + +The `sysml2tools` CLI is a local .NET tool pinned in `.config/dotnet-tools.json`. +Restore it once per session if not already available: + +```pwsh +dotnet tool restore +``` + +## Model files + +- `docs/sysml2/model/{system-name}.sysml` — system-level `part def` only (no subsystems/units + inline). A repository may contain more than one system. +- `docs/sysml2/model/{system-name}/{subsystem-name}.sysml` and + `docs/sysml2/model/{system-name}/{subsystem-name}/{unit-name}.sysml` — one file per + Subsystem/Unit, nested to mirror the same folder depth as that item's companion + `docs/design/`, `docs/reqstream/`, and `docs/verification/` files. +- `docs/sysml2/model/ots.sysml` — off-the-shelf (OTS) dependency parts (present when OTS items + exist). +- `docs/sysml2/model/shared.sysml` — Shared Package parts (present when Shared Package items + exist). +- `docs/sysml2/views/design-views.sysml` — named views rendered for the design document; a + sibling of `model/`, not nested inside it. Not usually needed for query workflows, but + useful to see how diagrams are scoped. + +Always pass all `.sysml` files (or a glob covering them) to every `sysml2tools` +invocation — the model spans multiple files and cross-references between them; files that +reopen the same `package Name { ... }` from different files merge into one namespace +automatically, no `import` required. As of `sysml2tools` 0.1.0-beta.5, every subcommand +(`lint`, `render`, `query`) expands `*`/`**` glob patterns internally and recurses +correctly — pass a single **quoted** glob string and let the tool resolve it, rather than +relying on the shell (quoting works identically in both PowerShell and bash): + +```pwsh +dotnet sysml2tools query list 'docs/sysml2/model/**/*.sysml' +``` + +## Artifact-location metadata + +Every System/Subsystem/Unit `part def` carries named `comment` elements pointing at its +companion artifacts (source, test, design, verification, and — for repositories that still +use ReqStream — requirements file). `query describe` returns every comment attached to +an element, so one query gets you every artifact location for that item without grepping the +source tree: + +```pwsh +dotnet sysml2tools query describe -e {SystemName}::{UnitName} 'docs/sysml2/model/**/*.sysml' +``` + +```text +- Documentation: One-line purpose statement for the unit. +- Comment: Source: src/{Project}/{Subsystem}/{UnitName}.cs +- Comment: Test: test/{Project}.Tests/{Subsystem}/{UnitName}Tests.cs +- Comment: Design: docs/design/{system-name}/{subsystem-name}/{unit-name}.md +- Comment: Verification: docs/verification/{system-name}/{subsystem-name}/{unit-name}.md +- Comment: Requirements: docs/reqstream/{system-name}/{subsystem-name}/{unit-name}.yaml +``` + +Not every item has all five comments — Systems/Subsystems have no `Source` comment, and +units without a dedicated companion doc point at their parent's doc instead (see the +Artifact-Location Comments section of `sysml2-modeling.md` for the full rules). Prefer these +paths over guessing a file location from the unit name; fall back to `grep`/`glob` only when +a comment is missing or the model is stale. + +## Recommended workflow + +1. **Discover the system(s) present** — do not assume a fixed name: + + ```pwsh + dotnet sysml2tools query list --kind "part def" 'docs/sysml2/model/**/*.sysml' + ``` + + Look for the top-level part def with no containing part (or the one with the most + children) to identify each system's qualified name. + +2. **Get the full hierarchy** (subsystems and units) for a system found above: + + ```pwsh + dotnet sysml2tools query describe -e 'docs/sysml2/model/**/*.sysml' + ``` + + `describe` lists direct children and every artifact-location comment; repeat on each + child to walk deeper, or use `query list` to see the full flat inventory. + +3. **Understand a specific unit's purpose and find its files** before opening its source + file — `describe` returns both the purpose `doc` and every `Comment:` artifact-location + line in one call (see Artifact-location metadata above): + + ```pwsh + dotnet sysml2tools query describe -e 'docs/sysml2/model/**/*.sysml' + ``` + +4. **Assess impact before editing a unit** — see what depends on it: + + ```pwsh + dotnet sysml2tools query used-by -e 'docs/sysml2/model/**/*.sysml' + dotnet sysml2tools query impact -e 'docs/sysml2/model/**/*.sysml' + ``` + + Note: this only surfaces structural (typing/containment) references modeled in + `.sysml` — not full call-graph/behavioral dependencies. Confirm actual usage in source + before making impact-sensitive changes. + +5. **Trace requirements** linked to a unit, if modeled: + + ```pwsh + dotnet sysml2tools query requirements -e 'docs/sysml2/model/**/*.sysml' + ``` + +6. **Search by name or kind** when the qualified name is unknown: + + ```pwsh + dotnet sysml2tools query find --name 'docs/sysml2/model/**/*.sysml' + dotnet sysml2tools query list --kind "part def" 'docs/sysml2/model/**/*.sysml' + ``` + +Use `--format json` on any query verb for machine-parsed output. + +## Fallback + +If the model is stale, doesn't yet cover a unit, or a query returns nothing useful, fall +back to `grep`/`glob`/reading source directly. When you finish work that adds or changes a +Unit/Subsystem, update the corresponding `.sysml` model file (including its artifact-location +comments) in the same change (mirrors the existing requirement to keep `docs/design/*.md` and +`docs/reqstream/*.yaml` companion artifacts in sync). See the `sysml2-modeling.md` +standard for full modeling and view-authoring conventions. + +## Validating changes to the model + +Before committing changes to any `.sysml` file, lint it: + +```pwsh +dotnet sysml2tools lint 'docs/sysml2/**/*.sysml' +``` diff --git a/.github/standards/design-documentation.md b/.github/standards/design-documentation.md index e5b7bf9..c6f107f 100644 --- a/.github/standards/design-documentation.md +++ b/.github/standards/design-documentation.md @@ -8,6 +8,8 @@ globs: ["docs/design/**/*.md"] - **`technical-documentation.md`** - General technical documentation standards - **`software-items.md`** - Software categorization (System/Subsystem/Unit/OTS/Shared Package) +- **`sysml2-modeling.md`** - SysML2 model and view conventions feeding the Software Structure + section # Folder Structure @@ -30,7 +32,6 @@ docs/design/ All sections in every file are mandatory; write "N/A - {justification}" rather than removing any. Determine subsystem vs. unit classification from `docs/design/introduction.md` — folder depth does not determine classification. -Do not record version numbers anywhere in design documentation — version information is managed in SBOMs. # introduction.md (MANDATORY) @@ -38,7 +39,8 @@ Must include: - **Purpose**: audience and compliance drivers - **Scope**: items covered and explicitly excluded (no test projects) -- **Software Structure**: text tree showing all Systems/Subsystems/Units/OTS/Shared items +- **Software Structure**: diagram(s) rendered from the SysML2 model under `docs/sysml2/`, + per `sysml2-modeling.md` — not a hand-maintained text tree - **Folder Layout**: text tree showing source folder structure - **Companion Artifact Structure**: parallel paths for requirements, design, verification, source, tests - **References** _(if applicable)_: external standards or specifications - only in `introduction.md` @@ -98,6 +100,12 @@ For each Shared Package, create `docs/design/shared/{package-name}.md` (`##` hea - Use Mermaid diagrams to supplement (not replace) text - Use verbal cross-references ("see _Parser Design_") - not markdown hyperlinks (break in PDF) - Provide sufficient detail for formal code review +- Do not record version numbers in design documentation — they go stale with dependency updates and + are managed in SBOMs. Version numbers are pinned release versions (e.g., `1.2.3`, `v2.0.1`). + The following are **not** version numbers and are permitted: + - Language/platform standards: `netstandard2.0`, `net10.0`, `C++20`, `C# 12` (stable standard identifiers) + - Protocol standards: `TLS 1.3`, `HTTP/2` (stable specifications) + - Placeholders: `0.0.0` (signals "not yet assigned") # Quality Checks diff --git a/.github/standards/reviewmark-usage.md b/.github/standards/reviewmark-usage.md index b521433..bc73da6 100644 --- a/.github/standards/reviewmark-usage.md +++ b/.github/standards/reviewmark-usage.md @@ -21,71 +21,86 @@ review, organizes them into review-sets, and generates review plans and reports. - **Lint Configuration**: `dotnet reviewmark --lint` - **Elaborate Review-Set**: `dotnet reviewmark --elaborate {review-set}` - **Generate Plan**: `dotnet reviewmark --plan docs/code_review_plan/generated/plan.md --enforce` - -> **Note**: `--enforce` causes the plan to fail with a non-zero exit code if any repository -> files are not covered by a review-set. Uncovered files indicate a gap in review-set -> configuration that should be addressed. + (exits non-zero if any files are uncovered) ## Repository Structure -Required repository items for ReviewMark operation: - - `.reviewmark.yaml` - Configuration for review-sets, file-patterns, and review evidence-source. -- `docs/code_review_plan/generated/` - Generated review plan (build output, do not edit) -- `docs/code_review_report/generated/` - Generated review report (build output, do not edit) # Review Definition Structure Configure reviews in `.reviewmark.yaml` at repository root: ```yaml -# Patterns identifying all files that require review needs-review: - # Include source code (adjust file extensions for your repo) - - "**/*.cs" # C# source files - - "**/*.cpp" # C++ source files - - "**/*.hpp" # C++ header files - - "!**/bin/**" # Generated source in build outputs - - "!**/obj/**" # Generated source in build intermediates - - # Include requirement files - - "requirements.yaml" # Root requirements file - - "docs/reqstream/**/*.yaml" # Requirements files - - # Include critical documentation files - - "README.md" # Root level README - - "docs/user_guide/**/*.md" # User guide - - "docs/design/**/*.md" # Design documentation - - "docs/verification/**/*.md" # Verification design documentation - -# Source of review evidence + - "**/*.cs" + - "**/*.cpp" + - "**/*.hpp" + - "!**/bin/**" + - "!**/obj/**" + - "requirements.yaml" + - "docs/reqstream/**/*.yaml" + - "docs/sysml2/**/*.sysml" + - "README.md" + - "docs/user_guide/**/*.md" + - "docs/design/**/*.md" + - "docs/verification/**/*.md" + evidence-source: type: none -# Review-sets (each focuses on a single compliance question) +context: + - docs/design/introduction.md + reviews: - id: Purpose - title: Review of user-facing capabilities and system promises + title: Review that README and User Guide are Coherent and Complete paths: - "README.md" - "docs/user_guide/**/*.md" - - "docs/reqstream/{system-name}.yaml" + - id: Decomposition + title: Review that {SystemName} Decomposition Addresses the Stated Purpose + context: + - "README.md" + - "docs/user_guide/**/*.md" + paths: + - "requirements.yaml" - "docs/design/introduction.md" - - "docs/design/{system-name}.md" ``` -# Review-Set Design Principles +For a complete annotated example with template directives, see `.reviewmark.yaml` in the +reference template (`{template-url}/.reviewmark.yaml` per `AGENTS.md`). -When constructing review-sets, follow these principles to maintain manageable scope and effective compliance evidence: +# Review-Set Design Principles - **Hierarchical Scope**: Higher-level reviews exclude lower-level implementation details, relying instead on design documents to describe what components they use. System reviews exclude subsystem/unit details, subsystem reviews exclude unit source code, only unit reviews include actual implementation. - **Single Focus**: Each review-set proves one specific compliance question (user promises, system architecture, design consistency, etc.) +- **Parent Context**: Unit and subsystem reviews include parent design and requirements as + context so reviewers understand the intended role and scope; see the Context Files section. - **Context Management**: Keep file counts manageable to prevent context overflow while maintaining complete coverage through the hierarchy +# Context Files + +Context files are shown to reviewers for orientation but not fingerprinted. Add a top-level +`context:` key for global context (every reviewer) and a per-review-set `context:` between +`title:` and `paths:` for review-specific context. Always include `docs/design/introduction.md` +as global context. + +| Review Type | Context to add | +| :---------- | :------------- | +| `Decomposition` | `README.md`, `docs/user_guide/**/*.md` | +| `{SystemName}-Architecture` | `README.md`, `docs/user_guide/**/*.md` | +| `{SystemName}-Design` | `docs/reqstream/{system-name}.yaml` | +| `{SystemName}-Verification` | `docs/reqstream/{system-name}.yaml` | +| `{SystemName}-AllRequirements` | Parent system design doc + `docs/reqstream/{system-name}.yaml` | +| `{SystemName}-{UnitName}` (direct unit) | Parent system design doc + parent system requirements | +| `{SystemName}-{SubsystemName}` (subsystem) | Parent system design doc + parent system requirements | +| `{SystemName}-{SubsystemName}-{UnitName}` (unit under subsystem) | System + subsystem design docs + requirements | + # Review-Set Organization **Naming conventions**: Placeholders in documentation, requirements, design, and @@ -96,23 +111,30 @@ placeholders are always PascalCase (e.g., `{SystemName}`). ## `Purpose` Review (only one per repository) -Reviews user-facing capabilities and system promises: - -- **Purpose**: Proves that the systems provide the capabilities the user is being told about -- **Title**: "Review that Advertised Features Match System Design" -- **Scope**: Excludes subsystem and unit files, relying on system-level design documents - to describe what subsystems and units they use +- **Purpose**: Proves that the user-facing docs are coherent and complete — the north-star for the hierarchy +- **Title**: "Review that README and User Guide are Coherent and Complete" +- **ID**: `Purpose` (no system prefix — one per repository) +- **Scope**: README and user_guide only; no requirements or design files - **File Path Patterns**: - README: `README.md` - User guide: `docs/user_guide/**/*.md` - - System requirements: `docs/reqstream/{system-name}.yaml` + +## `Decomposition` Review (only one per repository) + +- **Purpose**: Proves that the software items tree breakdown logically addresses the user-facing + promise; the structural mirror of the decomposition decision +- **Title**: "Review that {SystemName} Decomposition Addresses the Stated Purpose" +- **ID**: `Decomposition` (no system prefix — one per repository) +- **Scope**: introduction.md (the decomposition narrative), the SysML2 model (the + authoritative structural tree), and requirements.yaml; no system-level detail +- **File Path Patterns**: + - Root requirements: `requirements.yaml` - Design introduction: `docs/design/introduction.md` - - System design: `docs/design/{system-name}.md` + - SysML2 model: `docs/sysml2/**/*.sysml` +- **Context Files**: `README.md`, `docs/user_guide/**/*.md` ## `{SystemName}-Architecture` Review (one per system) -Reviews system architecture and operational validation: - - **Purpose**: Proves that the system is designed and tested to satisfy its requirements - **Title**: "Review that {SystemName} Architecture Satisfies Requirements" - **Scope**: Excludes subsystem and unit files, relying on system-level design to describe @@ -124,16 +146,15 @@ Reviews system architecture and operational validation: - Verification introduction: `docs/verification/introduction.md` - System verification design: `docs/verification/{system-name}.md` - System integration tests: `test/{SystemName}.Tests/{SystemName}Tests.{ext}` +- **Context Files**: `README.md`, `docs/user_guide/**/*.md` ## `{SystemName}-Design` Review (one per system) -Reviews architectural and design consistency: - - **Purpose**: Proves the system design is consistent and complete - **Title**: "Review that {SystemName} Design is Consistent and Complete" - **Scope**: Only brings in top-level requirements and relies on brevity of design documentation +- **Context Files**: `docs/reqstream/{system-name}.yaml` - **File Path Patterns**: - - System requirements: `docs/reqstream/{system-name}.yaml` - Platform requirements: `docs/reqstream/{system-name}/platform-requirements.yaml` - Design introduction: `docs/design/introduction.md` - System design: `docs/design/{system-name}.md` @@ -143,13 +164,11 @@ Reviews architectural and design consistency: ## `{SystemName}-Verification` Review (one per system) -Reviews verification completeness and consistency: - - **Purpose**: Proves the system verification design is consistent and covers all requirements - **Title**: "Review that {SystemName} Verification is Consistent and Complete" - **Scope**: Only brings in top-level requirements and all verification docs for the system +- **Context Files**: `docs/reqstream/{system-name}.yaml` - **File Path Patterns**: - - System requirements: `docs/reqstream/{system-name}.yaml` - Verification introduction: `docs/verification/introduction.md` - System verification: `docs/verification/{system-name}.md` - System verification files: `docs/verification/{system-name}/**/*.md` @@ -158,20 +177,15 @@ Reviews verification completeness and consistency: ## `{SystemName}-AllRequirements` Review (one per system) -Reviews requirements quality and traceability: - - **Purpose**: Proves the requirements are consistent and complete - **Title**: "Review that All {SystemName} Requirements are Complete" - **Scope**: Only brings in requirements files to keep review manageable - **File Path Patterns**: - - Root requirements: `requirements.yaml` - - System requirements: `docs/reqstream/{system-name}.yaml` - Subsystem/unit requirements: `docs/reqstream/{system-name}/**/*.yaml` +- **Context Files**: `docs/design/{system-name}.md`, `docs/reqstream/{system-name}.yaml` ## `{SystemName}-{SubsystemName}[-{SubsystemName}...]` Review (one per subsystem at any depth) -Reviews subsystem architecture and interfaces: - - **Purpose**: Proves that the subsystem is designed and tested to satisfy its requirements - **Title**: "Review that {SystemName} {SubsystemName} Satisfies Subsystem Requirements" - **Scope**: Excludes units under the subsystem, relying on subsystem design to describe @@ -181,11 +195,10 @@ Reviews subsystem architecture and interfaces: - Design: `docs/design/{system-name}[/{subsystem-name}...]/{subsystem-name}.md` - Verification design: `docs/verification/{system-name}[/{subsystem-name}...]/{subsystem-name}.md` - Tests: `test/{SystemName}.Tests[/{SubsystemName}...]/{SubsystemName}Tests.{ext}` +- **Context Files**: `docs/design/{system-name}.md`, `docs/reqstream/{system-name}.yaml` ## `{SystemName}-{SubsystemName}[-{SubsystemName}...]-{UnitName}` Review (one per unit) -Reviews individual software unit implementation: - - **Purpose**: Proves the unit is designed, implemented, and tested to satisfy its requirements - **Title**: "Review that {SystemName} {SubsystemName} {UnitName} Implementation is Correct" - **Scope**: Complete unit review including all artifacts @@ -197,11 +210,11 @@ Reviews individual software unit implementation: - Tests (C# example): `test/{SystemName}.Tests[/{SubsystemName}...]/{UnitName}Tests.cs` - Source (snake_case C++ example): `src/{system_name}[/{subsystem_name}...]/{unit_name}.cpp` - Tests (snake_case C++ example): `test/{system_name}_tests[/{subsystem_name}...]/{unit_name}_tests.cpp` +- **Context Files**: Parent system design + requirements; add subsystem design + + requirements for each subsystem level above the unit. ## `OTS-{OtsName}` Review (one per OTS item) -Reviews OTS item integration design, requirements, and verification evidence: - - **Purpose**: Proves that the OTS item provides the required functionality and is correctly integrated - **Title**: "Review that {OtsName} Provides Required Functionality" - **Scope**: No local source code; review covers integration design, requirements, and verification evidence @@ -214,8 +227,6 @@ Reviews OTS item integration design, requirements, and verification evidence: ## `Shared-{PackageName}` Review (one per Shared Package) -Reviews Shared Package integration design, requirements, and verification evidence: - - **Purpose**: Proves that the Shared Package provides the required advertised features and is correctly integrated - **Title**: "Review that {PackageName} Provides Required Features" - **Scope**: No local source code; review covers integration design, requirements, and verification evidence @@ -229,10 +240,9 @@ extensions (`.cs`, `.cpp`/`.hpp`, `.py`, etc.). Adapt to your repository's langu # Quality Checks -Before submitting ReviewMark configuration, verify: - - [ ] `.reviewmark.yaml` exists at repository root with proper structure - [ ] Review-set organization follows the standard hierarchy patterns - [ ] Each review-set focuses on a single compliance question (single focus principle) - [ ] File patterns use correct glob syntax and match intended files - [ ] Review-set file counts remain manageable (context management principle) +- [ ] Context configured per the Context Files section diff --git a/.github/standards/software-items.md b/.github/standards/software-items.md index 6c29525..3514228 100644 --- a/.github/standards/software-items.md +++ b/.github/standards/software-items.md @@ -130,3 +130,8 @@ the item is correct, well-designed, and proven to work: - **Verification Design** - HOW the requirements will be tested (applies to all item types) - **Source code** - The implementation of the design (local units only; not applicable to OTS or Shared Package) - **Tests** - PROOF the item does WHAT it is required to do (applies to all item types) + +Where the repository models its software structure in SysML2, each item's part def carries +`comment` metadata pointing at these same artifact locations (`sourceRef`/`testRef`/ +`designRef`/`verificationRef`/`reqRef`) so agents can query them directly — see +`sysml2-modeling.md`. diff --git a/.github/standards/sysml2-modeling.md b/.github/standards/sysml2-modeling.md new file mode 100644 index 0000000..c5558e1 --- /dev/null +++ b/.github/standards/sysml2-modeling.md @@ -0,0 +1,232 @@ +--- +name: SysML2 Modeling +description: Follow these standards when creating or modifying the SysML2 architecture + model, its rendered views, or the software structure it feeds into design documentation. +globs: ["docs/sysml2/**/*.sysml"] +--- + +# SysML2 Modeling Standard + +## Required Standards + +Read these standards first before applying this standard: + +- **`software-items.md`** - Software categorization (System/Subsystem/Unit/OTS/Shared Package) +- **`design-documentation.md`** - Design document structure that embeds the diagrams this + standard produces + +## Purpose + +The repository's software structure is modeled in SysML2 under `docs/sysml2/` rather than +hand-maintained as prose or an ASCII tree. The model is the authoritative, machine-queryable +source of structure; rendered diagrams and `docs/design/introduction.md`'s narrative are +generated/derived artifacts. AI agents should query the model (see `sysml2tools-query` +skill) before deep-diving into source code to understand what a piece of the system is, +why it exists, and what it depends on. + +## Repository Structure + +```text +docs/sysml2/ +├── model/ +│ ├── {system-name}.sysml # system-level part def only (no subsystems/units inline) +│ ├── {system-name}/ +│ │ ├── {subsystem-name}.sysml # subsystem part def; nests further for sub-subsystems +│ │ └── {subsystem-name}/ +│ │ └── {unit-name}.sysml # one file per unit +│ ├── ots.sysml # OTS dependency parts (optional; if OTS items exist) +│ └── shared.sysml # Shared Package parts (optional; if Shared Packages exist) +└── views/ + └── design-views.sysml # named view usages rendered for the design document +``` + +`docs/sysml2/model/` mirrors the same folder shape as `docs/design/`, `docs/reqstream/`, and +`docs/verification/` — one `.sysml` file per System/Subsystem/Unit, at the same nesting depth +as that item's companion design/requirements/verification files. This keeps each file small +and keeps PRs that touch one unit's model from producing unrelated diffs in unrelated units. +`docs/sysml2/views/` is a sibling of `model/`, not nested inside it, so a single +`docs/sysml2/model/**/*.sysml` glob never needs to exclude view files (`sysml2tools` has no +exclude-glob syntax). + +There is no separate "stable entry point" file — a repository may contain multiple systems, +so no single alias name would generalize. Agents discover the system(s) present by running +`query list --kind "part def"` or `query find` (see the `sysml2tools-query` skill) over +`docs/sysml2/model/**/*.sysml`, not by assuming a fixed name. + +Always pass the full set of `.sysml` files (or an equivalent glob) to every `sysml2tools` +invocation — the model spans multiple files and cross-references between them; files sharing +the same `package Name { ... }` merge into one namespace automatically with no `import` +required, as long as all files are passed together. As of `sysml2tools` 0.1.0-beta.5, +`lint` and `render` both expand `*`/`**` glob patterns internally (recursing correctly into +subdirectories), so pass a single **quoted** glob string (e.g. `'docs/sysml2/**/*.sysml'`) +and let the tool resolve it — do not rely on the shell to expand it, and do not quote-strip +the pattern before it reaches the tool. Quoting keeps the behavior identical across +PowerShell and bash, since neither shell needs to (or reliably does) expand `**` itself. + +## Model Content + +- `{system-name}.sysml` defines one `part def` for the System only, with `part` usages + referencing its direct Subsystems/Units (defined in their own files, see below). +- Each `{subsystem-name}.sysml` / `{unit-name}.sysml` defines exactly one `part def`, with a + `doc /* ... */` comment stating its purpose — mirroring what would otherwise be written as + prose in `docs/design/introduction.md`'s Software Structure section. Subsystem files add + `part` usages for their own direct children (nested subsystems or units), matching the + Software Item Hierarchy in `software-items.md`. +- `ots.sysml` / `shared.sysml` define one `part def` per OTS item / Shared Package, referenced + as `part` usages from the system(s) that depend on them. + +## Artifact-Location Comments + +Every System/Subsystem/Unit `part def` records where its companion artifacts live, as named +`comment` elements — not `attribute`s (attribute values are not surfaced by `sysml2tools query +describe`, even in JSON output; comments are). Comments have zero effect on rendered diagrams +(verified: a part def with several comments attached renders with no extra nodes or size +change) and are fully returned by `query describe`, in declaration order, as +`Comment: ...` summary lines — this is how an agent gets every artifact location for a unit +in a single query, without grepping the source tree. + +Use these comment names, in this order, when applicable to the item: + +```sysml +part def {UnitName} { + doc /* One-line purpose statement. */ + + comment sourceRef /* Source: {path to the unit's source file} */ + comment testRef /* Test: {path to the unit's test file} */ + comment designRef /* Design: {path to the unit's design doc} */ + comment verificationRef /* Verification: {path to the unit's verification doc} */ + comment reqRef /* Requirements: {path to the unit's reqstream file} */ +} +``` + +Not every item has all five: + +- **Systems and Subsystems** have no `sourceRef` (no single source file represents a whole + system or subsystem) — use `testRef` for the subsystem-level test file when one exists. +- **Units without a dedicated companion doc** (e.g. small data-model types documented inline + within their subsystem's design doc rather than in their own file) point `designRef` / + `verificationRef` / `reqRef` at the subsystem-level doc, with a short parenthetical note, + e.g. `/* Design: docs/design/{system}/{subsystem}.md (documented as a supporting value type) */`. +- **Units without a dedicated test file** (exercised only indirectly through another unit's + tests) omit `testRef` entirely rather than pointing at an unrelated test file. +- **OTS items** have no `sourceRef`/`testRef` (no local integration code); use `designRef` + (when the optional design doc exists) / `verificationRef` / `reqRef` only. + +This is prose-searchable metadata only — it is not a substitute for the authoritative +requirements/design/verification artifacts, and it does not replace ReqStream as the +requirements source of truth. (This repository currently keeps requirements traceability in +ReqStream; a future migration to native SysML2 `requirement`/`satisfy` modeling is a separate, +not-yet-scheduled change.) + +## Views (`docs/sysml2/views/design-views.sysml`) + +Views control what gets rendered into diagrams for the design document. Use named `view` +**usages** (not `view def` **definitions**) — `expose` is only valid inside a usage: + +```sysml +package {SystemName} { + view SoftwareStructureView { + expose {SystemName}; // whole package: system + subsystems + units + } + + view {SystemName}View { + expose {SystemName}System; // system def only, not expanded into subsystems + } + + view {SubsystemName}View { + expose {SubsystemName}; // one subsystem def only + } +} +``` + +**Critical distinction** (do not confuse these — this cost significant trial-and-error to +discover): `expose ;` is what scopes a rendered diagram's content (the union of the +named element's containment subtree). `render ;` selects a rendering *style* (e.g. +`asInterconnectionDiagram`) — it has **no effect on scope**. `expose` is only legal inside a named +`view Name { ... }` **usage**; it is a syntax/semantic error inside a `view def Name { ... }` +**definition**. `expose` targets must be `::`-qualified or locally-resolvable names, not +dotted member-access chains (`expose foo.bar;` is invalid — use `expose Bar;`). + +**Naming convention** — one `View` suffix per rendered diagram, no `System`/`Subsystem` +suffix duplication: + +- `SoftwareStructureView` - full detail: every system, subsystem, and unit in one diagram +- `{SystemName}View` - one per system, direct members only (not expanded into subsystems) +- `{SubsystemName}View` - one per subsystem (at any nesting depth), that subsystem's own + members only + +When a repository has multiple systems, `SoftwareStructureView` may expose each system's +package individually (`expose {SystemNameA}; expose {SystemNameB};`) or the whole workspace, +whichever produces a single coherent overview diagram. + +## Diagram Embedding + +Render with a single quoted recursive glob for the model tree, plus the views file +(`sysml2tools` 0.1.0-beta.5+ expands and recurses `**` internally, so no shell-side globbing +or explicit per-file listing is needed): + +```pwsh +dotnet sysml2tools render ` + --output docs/design/generated --format svg ` + 'docs/sysml2/model/**/*.sysml' ` + 'docs/sysml2/views/design-views.sysml' +``` + +With multiple views declared and no `--view` flag, `sysml2tools` renders every declared view +in one invocation, one file per view, using each view's own name as the filename +(`{ViewName}.svg`) — no post-render rename step is needed. + +Embed diagrams in `docs/design/` per this rule: every design doc for an item embeds the +diagram for the narrowest view that still shows that item's own immediate structure — + +- `docs/design/introduction.md` — `SoftwareStructureView.svg` (the full-detail overview) +- `docs/design/{system-name}.md` and every unit doc for a unit directly under the system + (no subsystem parent) — `{SystemName}View.svg` +- `docs/design/{system-name}/{subsystem-name}.md` and every unit doc nested under that + subsystem (at any depth) — `{SubsystemName}View.svg` + +Place the image directly under the file's top-level heading, before its first prose +subsection, e.g. `![{Name} Structure]({ViewName}.svg)`. + +## Build and Lint Integration + +- `sysml2tools lint` belongs in `lint.ps1`'s compliance-tools section, **not** as a separate + step in the CI design-document job — `lint.ps1` gates every later job (including document + generation) transitively, so linting the model there is both earlier and non-duplicated. + Pass a single quoted recursive glob, e.g. `dotnet sysml2tools lint 'docs/sysml2/**/*.sysml'` + — `sysml2tools` (0.1.0-beta.5+) expands and recurses this itself, so no + `Get-ChildItem`/shell-side globbing is needed. +- The CI design-document job renders the views (see the render command above) before running + Pandoc, so generated SVGs exist before HTML generation. Rename/stable-filename workarounds + are unnecessary since view names are stable by definition. Pass the model and views globs as + separate quoted arguments (e.g. `'docs/sysml2/model/**/*.sysml' 'docs/sysml2/views/design-views.sysml'`) + — plain PowerShell (the default shell) is sufficient; no `shell: bash`/`shopt -s globstar` + workaround is needed. +- Add `sysml2tools` to `.config/dotnet-tools.json` (`demaconsulting.sysml2tools.tool`) and to + `.versionmark.yaml`'s captured tool list. + +## Fallback + +If the model is stale, doesn't yet cover an item, or a query returns nothing useful, fall +back to `grep`/`glob`/reading source directly. When work adds or changes a Unit/Subsystem, +update the corresponding `.sysml` model file in the same change — this mirrors the existing +requirement to keep `docs/design/*.md` and `docs/reqstream/*.yaml` companion artifacts in +sync. + +## Quality Checks + +- [ ] Every System/Subsystem/Unit in `docs/design/introduction.md` has a matching `part def` + in its own file under `docs/sysml2/model/`, at the same folder depth as its companion + design/reqstream/verification files, with a purpose `doc` comment +- [ ] Every Unit-level `part def` has `sourceRef`/`testRef`/`designRef`/`verificationRef`/ + `reqRef` comments where applicable (see Artifact-Location Comments for documented + exceptions); System/Subsystem `part def`s have `testRef`/`designRef`/`verificationRef`/ + `reqRef` but no `sourceRef` +- [ ] `docs/sysml2/views/design-views.sysml` uses `view Name { expose ...; }` usages, not + `view def` definitions +- [ ] View names follow the `SoftwareStructureView` / `{SystemName}View` / + `{SubsystemName}View` convention +- [ ] `sysml2tools lint` passes on all `.sysml` files +- [ ] Rendered diagrams are embedded in every design doc per the Diagram Embedding rule +- [ ] `sysml2tools` is present in `lint.ps1`, `.config/dotnet-tools.json`, and + `.versionmark.yaml` diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9ff5f3f..0999118 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -377,7 +377,7 @@ jobs: dotnet versionmark --capture --job-id "build-docs" \ --output "artifacts/versionmark-build-docs.json" -- \ dotnet git node npm pandoc weasyprint sarifmark sonarmark reqstream \ - buildmark versionmark reviewmark fileassert + buildmark versionmark reviewmark fileassert sysml2tools echo "✓ Tool versions captured" # === PREPARE DOCUMENT OUTPUT === @@ -636,6 +636,20 @@ jobs: shell: bash run: mkdir -p docs/design/generated + - name: Run SysML2Tools self-validation + run: > + dotnet sysml2tools + --validate + --results artifacts/sysml2tools-self-validation.trx + + - name: Render Software Structure diagrams with SysML2Tools + shell: pwsh + run: > + dotnet sysml2tools render + --output docs/design/generated --format svg + 'docs/sysml2/model/**/*.sysml' + 'docs/sysml2/views/design-views.sysml' + - name: Generate Design HTML with Pandoc shell: bash run: > diff --git a/.reviewmark.yaml b/.reviewmark.yaml index 3a45515..65cc8cd 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -11,6 +11,7 @@ needs-review: - '**/*.cs' # All C# source and test files - docs/reqstream/**/*.yaml # Requirements files - docs/design/**/*.md # Design documentation files + - docs/sysml2/**/*.sysml # SysML2 architecture model and views - docs/verification/**/*.md # Verification documentation files - docs/user_guide/**/*.md # User guide documentation - '!**/obj/**' # Exclude build output @@ -27,36 +28,54 @@ evidence-source: type: url location: https://raw.githubusercontent.com/demaconsulting/TestResults/reviews/index.json +# Context included for all reviews - the software structure narrative every reviewer +# needs for orientation before evaluating a specific review-set's files. +context: + - docs/design/introduction.md + # Review sets following hierarchical scope principles. # Each review-set focuses on a single compliance question with manageable file counts. reviews: - # Purpose + # Purpose (only one per repository) - id: Purpose - title: Review that Advertised Features Match System Design + title: Review that README and User Guide are Coherent and Complete + context: + - '!docs/design/introduction.md' paths: - README.md - - src/DemaConsulting.TestResults/NamespaceDoc.cs - - src/DemaConsulting.TestResults/IO/NamespaceDoc.cs - docs/user_guide/**/*.md - - docs/reqstream/test-results-library.yaml + + # Decomposition (only one per repository) + - id: Decomposition + title: Review that TestResultsLibrary Decomposition Addresses the Stated Purpose + context: + - README.md + - docs/user_guide/**/*.md + paths: + - requirements.yaml - docs/design/introduction.md - - docs/design/test-results-library.md + - docs/sysml2/**/*.sysml # TestResults - Specials - id: TestResults-Architecture title: Review that TestResults Library Architecture Satisfies Requirements + context: + - README.md + - docs/user_guide/**/*.md paths: - docs/reqstream/test-results-library.yaml - docs/design/introduction.md - docs/design/test-results-library.md - docs/verification/introduction.md - docs/verification/test-results-library.md + - src/DemaConsulting.TestResults/NamespaceDoc.cs - test/DemaConsulting.TestResults.Tests/TestResultsLibraryTests.cs - id: TestResults-Design title: Review that TestResults Library Design is Consistent and Complete - paths: + context: - docs/reqstream/test-results-library.yaml + paths: - docs/reqstream/test-results-library/platform-requirements.yaml - docs/design/introduction.md - docs/design/ots.md @@ -65,8 +84,9 @@ reviews: - id: TestResults-Verification title: Review that TestResults Library Verification is Consistent and Complete - paths: + context: - docs/reqstream/test-results-library.yaml + paths: - docs/verification/introduction.md - docs/verification/ots.md - docs/verification/test-results-library.md @@ -74,50 +94,72 @@ reviews: - id: TestResults-AllRequirements title: Review that All TestResults Library Requirements are Complete - paths: - - requirements.yaml + context: + - docs/design/test-results-library.md - docs/reqstream/test-results-library.yaml + paths: - docs/reqstream/test-results-library/**/*.yaml - docs/reqstream/ots/**/*.yaml # TestResults - IO - id: TestResults-IO title: Review that TestResults IO Satisfies Subsystem Requirements + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml paths: - docs/reqstream/test-results-library/io.yaml - docs/design/test-results-library/io.md - docs/verification/test-results-library/io.md + - src/DemaConsulting.TestResults/IO/NamespaceDoc.cs - test/DemaConsulting.TestResults.Tests/IO/IOTests.cs # TestResults - TestOutcome - id: TestResults-TestOutcome title: Review that TestResults TestOutcome Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml paths: - docs/reqstream/test-results-library/test-outcome.yaml - docs/design/test-results-library/test-outcome.md + - docs/verification/test-results-library/test-outcome.md - src/DemaConsulting.TestResults/TestOutcome.cs - test/DemaConsulting.TestResults.Tests/TestOutcomeTests.cs # TestResults - TestResult - id: TestResults-TestResult title: Review that TestResults TestResult Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml paths: - docs/reqstream/test-results-library/test-result.yaml - docs/design/test-results-library/test-result.md + - docs/verification/test-results-library/test-result.md - src/DemaConsulting.TestResults/TestResult.cs - test/DemaConsulting.TestResults.Tests/TestResultTests.cs # TestResults - TestResults - id: TestResults-TestResults title: Review that TestResults TestResults Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml paths: - docs/reqstream/test-results-library/test-results.yaml - docs/design/test-results-library/test-results.md + - docs/verification/test-results-library/test-results.md - src/DemaConsulting.TestResults/TestResults.cs - test/DemaConsulting.TestResults.Tests/TestResultsTests.cs - id: TestResults-IO-Serializer title: Review that TestResults IO Serializer Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml + - docs/design/test-results-library/io.md + - docs/reqstream/test-results-library/io.yaml paths: - docs/reqstream/test-results-library/io/serializer.yaml - docs/design/test-results-library/io/serializer.md @@ -127,6 +169,11 @@ reviews: - id: TestResults-IO-SerializerHelpers title: Review that TestResults IO SerializerHelpers Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml + - docs/design/test-results-library/io.md + - docs/reqstream/test-results-library/io.yaml paths: - docs/reqstream/test-results-library/io/serializer-helpers.yaml - docs/design/test-results-library/io/serializer-helpers.md @@ -135,6 +182,11 @@ reviews: - id: TestResults-IO-TrxSerializer title: Review that TestResults IO TrxSerializer Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml + - docs/design/test-results-library/io.md + - docs/reqstream/test-results-library/io.yaml paths: - docs/reqstream/test-results-library/io/trx-serializer.yaml - docs/design/test-results-library/io/trx-serializer.md @@ -146,6 +198,11 @@ reviews: - id: TestResults-IO-JUnitSerializer title: Review that TestResults IO JUnitSerializer Implementation is Correct + context: + - docs/design/test-results-library.md + - docs/reqstream/test-results-library.yaml + - docs/design/test-results-library/io.md + - docs/reqstream/test-results-library/io.yaml paths: - docs/reqstream/test-results-library/io/junit-serializer.yaml - docs/design/test-results-library/io/junit-serializer.md diff --git a/.versionmark.yaml b/.versionmark.yaml index 85f1418..a726403 100644 --- a/.versionmark.yaml +++ b/.versionmark.yaml @@ -77,3 +77,8 @@ tools: apimark-msbuild: command: dotnet list src/DemaConsulting.TestResults/DemaConsulting.TestResults.csproj package regex: '(?i)DemaConsulting\.ApiMark\.MSBuild\s+(?\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)' + + # sysml2tools (DemaConsulting.Sysml2Tools.Tool from dotnet tool list) + sysml2tools: + command: dotnet tool list + regex: '(?i)demaconsulting\.sysml2tools\.tool\s+(?\d+\.\d+\.\d+(?:-[a-zA-Z0-9.]+)?)' diff --git a/AGENTS.md b/AGENTS.md index 7fbbb4f..8df7e71 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,6 +21,7 @@ │ ├── requirements_doc/ │ ├── requirements_report/ │ ├── reqstream/ +│ ├── sysml2/ │ ├── user_guide/ │ └── verification/ ├── src/ @@ -44,10 +45,12 @@ This repository follows a reference template for structure and file conventions. # Codebase Navigation (ALL Agents) -When working with source code, design, or requirements artifacts, read -`docs/design/introduction.md` first. It provides the software structure, -folder layout, and companion artifact locations. Use it as the primary map -before searching the filesystem. +When working with source code, design, or requirements artifacts, query the SysML2 +architecture model under `docs/sysml2/` first (see the `sysml2tools-query` skill) to +understand software structure, purpose, and relationships. Fall back to +`docs/design/introduction.md` for the human-facing narrative, folder layout, and +companion artifact locations, and use it as the primary map when the model doesn't +yet cover something. # Key Configuration Files @@ -62,6 +65,7 @@ before searching the filesystem. - **`package.json`** - Node.js dependencies for formatting tools - **`requirements.yaml`** - Root requirements file with includes - **`pip-requirements.txt`** - Python dependencies for yamllint and yamlfix +- **`docs/sysml2/`** - SysML2 architecture model; authoritative source for software structure - **`fix.ps1`** - Applies all auto-fixers silently (dotnet format, markdown, YAML). Always exits 0. - **`build.ps1`** - Builds the solution and runs all tests. @@ -78,6 +82,7 @@ from `.github/standards/`. Use this matrix to determine which to load: - **Design docs**: `software-items.md`, `design-documentation.md`, `technical-documentation.md` - **Verification docs**: `software-items.md`, `verification-documentation.md`, `technical-documentation.md` - **Review configuration**: `software-items.md`, `reviewmark-usage.md` +- **Software structure**: `sysml2-modeling.md` - **Any documentation**: `technical-documentation.md` Load only the standards relevant to your specific task scope. @@ -132,7 +137,7 @@ responsibility - invoke the lint-fix agent once before submitting a pull request ## CI Quality Tools CI runs `lint.ps1` which checks: markdownlint-cli2, cspell, yamllint, dotnet format, -reqstream, versionmark, and reviewmark. +reqstream, versionmark, reviewmark, and sysml2tools. # Scope Discipline (ALL Agents Must Follow) diff --git a/docs/design/introduction.md b/docs/design/introduction.md index 9398957..628def3 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -32,15 +32,18 @@ OTS software items used in this repository: ## Software Structure -- **TestResultsLibrary** (System) - .NET library for reading and writing test result files in TRX and JUnit XML formats - - **IO** (Subsystem) - translates between the in-memory model and XML result formats - - Serializer (Unit) - identifies XML result formats and delegates deserialization - - SerializerHelpers (Unit) - provides Utf8StringWriter for XML declarations - - TrxSerializer (Unit) - serializes and deserializes TRX test result documents - - JUnitSerializer (Unit) - serializes and deserializes JUnit XML test result documents - - TestOutcome (Unit) - defines supported test outcomes and classification helpers - - TestResult (Unit) - represents one test case result with metadata and output - - TestResults (Unit) - represents a complete test run and its ordered results +The full software structure — every System, Subsystem, and Unit and how they relate — is +modeled in SysML2 under `docs/sysml2/`. Agents should query that model (see the +`sysml2tools-query` skill) rather than parse this diagram or maintain a hand-written tree. +The diagram below is rendered directly from the model and is the authoritative overview: + +![Software Structure](SoftwareStructureView.svg) + +**TestResultsLibrary** (System) is the .NET library for reading and writing test result +files in TRX and JUnit XML formats. Its **IO** (Subsystem) translates between the in-memory +model and XML result formats through four units: Serializer, SerializerHelpers, +TrxSerializer, and JUnitSerializer. Three further units — TestOutcome, TestResult, and +TestResults — sit directly under the system and define the shared in-memory model. **OTS Dependencies:** @@ -56,6 +59,10 @@ OTS software items used in this repository: - xUnit (OTS) - ApiMark (OTS) +These OTS items are build-pipeline and documentation tooling, not runtime dependencies of the +shipped library, so they are not modeled as SysML2 system parts; each is fully documented in +`docs/design/ots.md` and `docs/design/ots/`. + ## Folder Layout ```text diff --git a/docs/design/test-results-library.md b/docs/design/test-results-library.md index 0cf41de..7e7ce38 100644 --- a/docs/design/test-results-library.md +++ b/docs/design/test-results-library.md @@ -1,5 +1,7 @@ # TestResultsLibrary +![TestResultsLibrary Structure](TestResultsLibraryView.svg) + ## Architecture TestResultsLibrary uses a format-neutral in-memory model as the center of the design. diff --git a/docs/design/test-results-library/io.md b/docs/design/test-results-library/io.md index 04b1659..970b537 100644 --- a/docs/design/test-results-library/io.md +++ b/docs/design/test-results-library/io.md @@ -1,5 +1,7 @@ ## IO +![IO Structure](IOView.svg) + ### Overview The IO subsystem translates between the format-neutral in-memory model and external XML test diff --git a/docs/design/test-results-library/io/junit-serializer.md b/docs/design/test-results-library/io/junit-serializer.md index 643dc29..ca5e5f5 100644 --- a/docs/design/test-results-library/io/junit-serializer.md +++ b/docs/design/test-results-library/io/junit-serializer.md @@ -1,5 +1,7 @@ ### JUnitSerializer +![IO Structure](IOView.svg) + #### Purpose The JUnitSerializer unit converts between the shared in-memory model and JUnit XML test diff --git a/docs/design/test-results-library/io/serializer-helpers.md b/docs/design/test-results-library/io/serializer-helpers.md index 6664d1e..cbf7f86 100644 --- a/docs/design/test-results-library/io/serializer-helpers.md +++ b/docs/design/test-results-library/io/serializer-helpers.md @@ -1,5 +1,7 @@ ### SerializerHelpers +![IO Structure](IOView.svg) + #### Purpose The SerializerHelpers unit provides shared infrastructure used by both XML serializers. Its @@ -14,7 +16,7 @@ by both serializer units when saving XML to a string. **Encoding**: `Encoding` - Overridden property that always returns `Encoding.UTF8` so the XML prolog declares `encoding="utf-8"`. -#### Key Properties +#### Key Methods **Encoding**: Read-only property override that reports UTF-8 as the writer encoding. diff --git a/docs/design/test-results-library/io/serializer.md b/docs/design/test-results-library/io/serializer.md index bf65a8c..77ff9de 100644 --- a/docs/design/test-results-library/io/serializer.md +++ b/docs/design/test-results-library/io/serializer.md @@ -1,5 +1,7 @@ ### Serializer +![IO Structure](IOView.svg) + #### Purpose The Serializer unit is the IO subsystem facade for callers that do not know the incoming diff --git a/docs/design/test-results-library/io/trx-serializer.md b/docs/design/test-results-library/io/trx-serializer.md index 67689da..39a5185 100644 --- a/docs/design/test-results-library/io/trx-serializer.md +++ b/docs/design/test-results-library/io/trx-serializer.md @@ -1,5 +1,7 @@ ### TrxSerializer +![IO Structure](IOView.svg) + #### Purpose The TrxSerializer unit converts between the shared in-memory model and Microsoft TRX test diff --git a/docs/design/test-results-library/test-outcome.md b/docs/design/test-results-library/test-outcome.md index 1a3e273..feef43a 100644 --- a/docs/design/test-results-library/test-outcome.md +++ b/docs/design/test-results-library/test-outcome.md @@ -1,5 +1,7 @@ ## TestOutcome +![TestResultsLibrary Structure](TestResultsLibraryView.svg) + ### Purpose The TestOutcome unit defines the complete set of execution outcomes that the library can diff --git a/docs/design/test-results-library/test-result.md b/docs/design/test-results-library/test-result.md index 6da8962..7aa6af2 100644 --- a/docs/design/test-results-library/test-result.md +++ b/docs/design/test-results-library/test-result.md @@ -1,5 +1,7 @@ ## TestResult +![TestResultsLibrary Structure](TestResultsLibraryView.svg) + ### Purpose The TestResult unit represents one executed or scheduled test case. It stores identity, diff --git a/docs/design/test-results-library/test-results.md b/docs/design/test-results-library/test-results.md index f77d34d..00d7a6d 100644 --- a/docs/design/test-results-library/test-results.md +++ b/docs/design/test-results-library/test-results.md @@ -1,5 +1,7 @@ ## TestResults +![TestResultsLibrary Structure](TestResultsLibraryView.svg) + ### Purpose The TestResults unit represents a complete test run. It groups ordered `TestResult` diff --git a/docs/sysml2/model/test-results-library.sysml b/docs/sysml2/model/test-results-library.sysml new file mode 100644 index 0000000..8e87bfc --- /dev/null +++ b/docs/sysml2/model/test-results-library.sysml @@ -0,0 +1,21 @@ +package TestResultsLibrary { + doc + /* + * TestResultsLibrary is a .NET library for reading and writing test result files in + * TRX and JUnit XML formats. + */ + + part def TestResultsLibrarySystem { + doc /* The TestResultsLibrary system as a whole. */ + + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/TestResultsLibraryTests.cs */ + comment designRef /* Design: docs/design/test-results-library.md */ + comment verificationRef /* Verification: docs/verification/test-results-library.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library.yaml */ + + part io : IOSubsystem; + part testOutcome : TestOutcome; + part testResult : TestResult; + part testResults : TestResults; + } +} diff --git a/docs/sysml2/model/test-results-library/io.sysml b/docs/sysml2/model/test-results-library/io.sysml new file mode 100644 index 0000000..eb3a989 --- /dev/null +++ b/docs/sysml2/model/test-results-library/io.sysml @@ -0,0 +1,15 @@ +package TestResultsLibrary { + part def IOSubsystem { + doc /* Translates between the in-memory model and XML result formats. */ + + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/IO/IOTests.cs */ + comment designRef /* Design: docs/design/test-results-library/io.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/io.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/io.yaml */ + + part serializer : Serializer; + part serializerHelpers : SerializerHelpers; + part trxSerializer : TrxSerializer; + part junitSerializer : JUnitSerializer; + } +} diff --git a/docs/sysml2/model/test-results-library/io/junit-serializer.sysml b/docs/sysml2/model/test-results-library/io/junit-serializer.sysml new file mode 100644 index 0000000..92f20cc --- /dev/null +++ b/docs/sysml2/model/test-results-library/io/junit-serializer.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def JUnitSerializer { + doc /* Serializes and deserializes JUnit XML test result documents. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/IO/JUnitSerializer.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/IO/JUnitSerializerTests.cs */ + comment designRef /* Design: docs/design/test-results-library/io/junit-serializer.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/io/junit-serializer.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/io/junit-serializer.yaml */ + } +} diff --git a/docs/sysml2/model/test-results-library/io/serializer-helpers.sysml b/docs/sysml2/model/test-results-library/io/serializer-helpers.sysml new file mode 100644 index 0000000..387aaf6 --- /dev/null +++ b/docs/sysml2/model/test-results-library/io/serializer-helpers.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def SerializerHelpers { + doc /* Provides Utf8StringWriter for XML declarations. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/IO/SerializerHelpers.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/IO/SerializerHelpersTests.cs */ + comment designRef /* Design: docs/design/test-results-library/io/serializer-helpers.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/io/serializer-helpers.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/io/serializer-helpers.yaml */ + } +} diff --git a/docs/sysml2/model/test-results-library/io/serializer.sysml b/docs/sysml2/model/test-results-library/io/serializer.sysml new file mode 100644 index 0000000..1f9c87c --- /dev/null +++ b/docs/sysml2/model/test-results-library/io/serializer.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def Serializer { + doc /* Identifies XML result formats and delegates deserialization. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/IO/Serializer.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/IO/SerializerTests.cs */ + comment designRef /* Design: docs/design/test-results-library/io/serializer.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/io/serializer.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/io/serializer.yaml */ + } +} diff --git a/docs/sysml2/model/test-results-library/io/trx-serializer.sysml b/docs/sysml2/model/test-results-library/io/trx-serializer.sysml new file mode 100644 index 0000000..511a5fe --- /dev/null +++ b/docs/sysml2/model/test-results-library/io/trx-serializer.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def TrxSerializer { + doc /* Serializes and deserializes TRX test result documents. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/IO/TrxSerializer.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/IO/TrxSerializerTests.cs */ + comment designRef /* Design: docs/design/test-results-library/io/trx-serializer.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/io/trx-serializer.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/io/trx-serializer.yaml */ + } +} diff --git a/docs/sysml2/model/test-results-library/test-outcome.sysml b/docs/sysml2/model/test-results-library/test-outcome.sysml new file mode 100644 index 0000000..ac87f00 --- /dev/null +++ b/docs/sysml2/model/test-results-library/test-outcome.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def TestOutcome { + doc /* Defines supported test outcomes and classification helpers. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/TestOutcome.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/TestOutcomeTests.cs */ + comment designRef /* Design: docs/design/test-results-library/test-outcome.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/test-outcome.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/test-outcome.yaml */ + } +} diff --git a/docs/sysml2/model/test-results-library/test-result.sysml b/docs/sysml2/model/test-results-library/test-result.sysml new file mode 100644 index 0000000..b315c90 --- /dev/null +++ b/docs/sysml2/model/test-results-library/test-result.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def TestResult { + doc /* Represents one test case result with metadata and output. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/TestResult.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/TestResultTests.cs */ + comment designRef /* Design: docs/design/test-results-library/test-result.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/test-result.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/test-result.yaml */ + } +} diff --git a/docs/sysml2/model/test-results-library/test-results.sysml b/docs/sysml2/model/test-results-library/test-results.sysml new file mode 100644 index 0000000..f8560af --- /dev/null +++ b/docs/sysml2/model/test-results-library/test-results.sysml @@ -0,0 +1,11 @@ +package TestResultsLibrary { + part def TestResults { + doc /* Represents a complete test run and its ordered results. */ + + comment sourceRef /* Source: src/DemaConsulting.TestResults/TestResults.cs */ + comment testRef /* Test: test/DemaConsulting.TestResults.Tests/TestResultsTests.cs */ + comment designRef /* Design: docs/design/test-results-library/test-results.md */ + comment verificationRef /* Verification: docs/verification/test-results-library/test-results.md */ + comment reqRef /* Requirements: docs/reqstream/test-results-library/test-results.yaml */ + } +} diff --git a/docs/sysml2/views/design-views.sysml b/docs/sysml2/views/design-views.sysml new file mode 100644 index 0000000..08ab8fb --- /dev/null +++ b/docs/sysml2/views/design-views.sysml @@ -0,0 +1,18 @@ +// Views rendered into docs/design/generated/ for the Design document. +// Reopens the TestResultsLibrary package so each 'expose' statement can reference +// its target part def directly. Per SysML2Tools syntax, 'expose' is only valid +// inside a named 'view' usage (not a 'view def' definition), and it - not +// 'render' - is what scopes the rendered diagram content. +package TestResultsLibrary { + view SoftwareStructureView { + expose TestResultsLibrary; + } + + view TestResultsLibraryView { + expose TestResultsLibrarySystem; + } + + view IOView { + expose IOSubsystem; + } +} diff --git a/lint.ps1 b/lint.ps1 index 8959539..1739b08 100644 --- a/lint.ps1 +++ b/lint.ps1 @@ -75,6 +75,7 @@ if (-not $skipNpm) { # [PROJECT-SPECIFIC] Add additional npm-based lint checks here. # --- Compliance Tools --- +# Runs compliance tools: reqstream, versionmark, reviewmark, sysml2tools. Write-Host "Linting: compliance tools..." $skipDotnetTools = $false dotnet tool restore > $null @@ -89,6 +90,11 @@ if (-not $skipDotnetTools) { dotnet reviewmark --lint if ($LASTEXITCODE -ne 0) { $lintError = $true } + + if (Test-Path docs/sysml2) { + dotnet sysml2tools lint 'docs/sysml2/**/*.sysml' + if ($LASTEXITCODE -ne 0) { $lintError = $true } + } } # [PROJECT-SPECIFIC] Add additional dotnet tool checks here.