From e0e50cee1e02667cba58e6f0ec9d7aa6290081a8 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Sat, 11 Jul 2026 10:12:16 -0400 Subject: [PATCH 1/3] 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, and clarify that OTS dependencies are documented separately and intentionally not modeled as SysML2 parts (build-time/pipeline tooling, not runtime composition) - Embed per-subsystem/unit diagrams across docs/design/template-dot-net-tool/** - Rework .reviewmark.yaml to add docs/sysml2/**/*.sysml to needs-review and add the OTS-SysML2Tools review-set - Document SysML2Tools as an OTS dependency: docs/reqstream/ots/sysml2tools.yaml, docs/design/ots/sysml2tools.md, docs/verification/ots/sysml2tools.md, wired into requirements.yaml, design/verification definition.yaml manifests, and ots.md summary pages - Add sysml, sysml2tools, demaconsulting to .cspell.yaml word list - Bring in agents/standards/skills prep for the SysML2 upgrade (AGENTS.md, sysml2-modeling.md standard, sysml2tools-query skill, updated design-documentation.md/reviewmark-usage.md/software-items.md standards, template-sync.agent.md, removal of unused cpp-language.md/cpp-testing.md standards) Verified via dotnet sysml2tools lint/render, dotnet reqstream/versionmark/ reviewmark --lint, pwsh ./lint.ps1, and a change-review + 11 formal-review passes (gpt-5.4-mini) across every affected review-set; all in-scope findings resolved (remaining findings in Utilities/SelfTest/Cli/Design review-sets are pre-existing issues unrelated to this change). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .config/dotnet-tools.json | 6 + .cspell.yaml | 3 + .github/agents/template-sync.agent.md | 2 + .github/skills/sysml2tools-query/SKILL.md | 145 +++++++++++ .github/standards/cpp-language.md | 100 -------- .github/standards/cpp-testing.md | 72 ------ .github/standards/design-documentation.md | 12 +- .github/standards/reviewmark-usage.md | 10 +- .github/standards/software-items.md | 5 + .github/standards/sysml2-modeling.md | 232 ++++++++++++++++++ .github/workflows/build.yaml | 16 +- .reviewmark.yaml | 20 +- .versionmark.yaml | 5 + AGENTS.md | 15 +- docs/design/definition.yaml | 1 + docs/design/introduction.md | 22 +- docs/design/ots.md | 1 + docs/design/ots/sysml2tools.md | 52 ++++ docs/design/template-dot-net-tool.md | 2 + docs/design/template-dot-net-tool/cli.md | 2 + .../template-dot-net-tool/cli/context.md | 2 + docs/design/template-dot-net-tool/program.md | 2 + .../design/template-dot-net-tool/self-test.md | 2 + .../self-test/validation.md | 2 + .../design/template-dot-net-tool/utilities.md | 2 + .../utilities/path-helpers.md | 2 + docs/reqstream/ots/sysml2tools.yaml | 27 ++ docs/sysml2/model/template-dot-net-tool.sysml | 21 ++ .../model/template-dot-net-tool/cli.sysml | 12 + .../template-dot-net-tool/cli/context.sysml | 11 + .../model/template-dot-net-tool/program.sysml | 11 + .../template-dot-net-tool/self-test.sysml | 12 + .../self-test/validation.sysml | 11 + .../template-dot-net-tool/utilities.sysml | 12 + .../utilities/path-helpers.sysml | 11 + docs/sysml2/views/design-views.sysml | 26 ++ docs/verification/definition.yaml | 1 + docs/verification/introduction.md | 28 +-- docs/verification/ots.md | 1 + docs/verification/ots/sysml2tools.md | 53 ++++ lint.ps1 | 7 +- requirements.yaml | 1 + 42 files changed, 747 insertions(+), 233 deletions(-) create mode 100644 .github/skills/sysml2tools-query/SKILL.md delete mode 100644 .github/standards/cpp-language.md delete mode 100644 .github/standards/cpp-testing.md create mode 100644 .github/standards/sysml2-modeling.md create mode 100644 docs/design/ots/sysml2tools.md create mode 100644 docs/reqstream/ots/sysml2tools.yaml create mode 100644 docs/sysml2/model/template-dot-net-tool.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/cli.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/cli/context.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/program.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/self-test.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/self-test/validation.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/utilities.sysml create mode 100644 docs/sysml2/model/template-dot-net-tool/utilities/path-helpers.sysml create mode 100644 docs/sysml2/views/design-views.sysml create mode 100644 docs/verification/ots/sysml2tools.md diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 337f9ec..7ccda75 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -61,6 +61,12 @@ "commands": [ "fileassert" ] + }, + "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 2dd7f9d..61e4996 100644 --- a/.cspell.yaml +++ b/.cspell.yaml @@ -22,6 +22,7 @@ words: - dcterms - DEMA - Dema + - demaconsulting - doctitle - docversion - errorlevel @@ -38,6 +39,8 @@ words: - setlocal - snupkg - sonarmark + - sysml + - sysml2tools - templatetool - venv - versionmark 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/cpp-language.md b/.github/standards/cpp-language.md deleted file mode 100644 index c424bf5..0000000 --- a/.github/standards/cpp-language.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -name: C++ Language -description: Follow these standards when developing C++ source code. -globs: ["**/*.cpp", "**/*.hpp", "**/*.h"] ---- - -# Required Standards - -Read these standards first before applying this standard: - -- **`coding-principles.md`** - Universal coding principles and quality gates - -# File Organization - -C++ projects use two parallel top-level folders — `include/` (public API) and -`src/` (implementation) — both mirroring the same system/subsystem/unit hierarchy -(test layout is covered in `cpp-testing.md`): - -```text -include/ -└── {system_name}/ - └── {subsystem_name}/ - └── {unit_name}.hpp # public API - installed with the package - -src/ -└── {system_name}/ - └── {subsystem_name}/ - ├── {unit_name}.cpp # implementation - └── {unit_name}_impl.hpp # internal header - not part of the public API -``` - -Subsystems may nest to any depth: `{system_name}[/{subsystem_name}...]/{unit_name}.hpp/cpp`. - -Protect every header with `#pragma once`. - -# Naming and Style Conventions - -- **Symbols**: `snake_case` for all identifiers - variables, functions, types, and - namespaces - to align with STL naming -- **Bracing**: 4-space Allman style - opening brace on its own line -- **Data objects**: use `struct` for passive data; may include simple constructors - or helper methods but must not encapsulate invariants (use `class` for those) - -# API Documentation and Literate Coding Example - -Use `///` C++ Doxygen line comments. - -```cpp -/// @brief Converts a raw sensor reading into a validated measurement. -/// -/// Clamping is preferred over throwing on out-of-range values because -/// sensor drift at range boundaries is expected; clamping produces a usable -/// result where rejection would discard valid near-boundary readings. -/// Stateless and thread-safe; the calibration profile is read but never modified. -/// -/// @param reading Raw sensor value. Must be finite (NaN and infinities are rejected). -/// @param calibration Calibration profile providing offset and range. -/// @returns Corrected value clamped to [calibration.minimum, calibration.maximum]. -/// @throws std::invalid_argument When reading is NaN or infinite. -double process_reading(double reading, const calibration_profile& calibration) -{ - // Reject invalid inputs before any calculation - non-finite readings cannot be - // corrected, and the calibration profile provides no offset or range to apply - if (!std::isfinite(reading)) - throw std::invalid_argument("reading must be a finite number"); - - // Apply the calibration offset to convert raw counts to physical units - double corrected = reading + calibration.offset; - - // Clamp to the operational range so consumers can rely on the documented contract - return std::clamp(corrected, calibration.minimum, calibration.maximum); -} -``` - -Key qualities demonstrated above: - -- **`@brief`** is a concise one-liner explaining *what* the function does -- **Extended description** carries the extended intent - *why* it exists, design decisions, - thread-safety, and side-effect disclosures -- **`@param` tags** state constraints so callers know what is valid without reading the body -- **`@returns`** documents the boundary guarantee so consumers can rely on the contract -- **`@throws`** names every thrown exception and the condition that triggers it -- **Inline block comments** follow the Literate Coding principles from - `coding-principles.md`, separating logical steps so reviewers can verify each - step against design intent - -# Code Formatting - -Apply clang-format using the repository `.clang-format` configuration: - -- **Format file**: `clang-format -i my_file.cpp` -- Run `pwsh ./fix.ps1` to apply across the project - -# Quality Checks - -- [ ] Zero compiler warnings (`-Wall -Wextra -Werror`) -- [ ] Doxygen documentation complete on all symbols -- [ ] clang-format applied (run `pwsh ./fix.ps1`) -- [ ] All headers protected with `#pragma once` -- [ ] No raw owning pointers - use `std::unique_ptr` or `std::shared_ptr` diff --git a/.github/standards/cpp-testing.md b/.github/standards/cpp-testing.md deleted file mode 100644 index 87431d2..0000000 --- a/.github/standards/cpp-testing.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -name: C++ Testing -description: Follow these standards when developing C++ tests. -globs: ["**/test/**/*.cpp", "**/tests/**/*.cpp", "**/*_test.cpp", "**/*_tests.cpp"] ---- - -# Required Standards - -Read these standards first before applying this standard: - -- **`testing-principles.md`** - Universal testing principles and dependency boundaries -- **`cpp-language.md`** - C++ language development standards - -# File Organization - -Test files mirror the `src/` tree under `test/`, with `_tests` appended to the -system folder name and each test file name: - -```text -test/ -└── {system_name}_tests/ - └── {subsystem_name}/ - └── {unit_name}_tests.cpp # unit tests for src/{system_name}[/{subsystem_name}...]/{unit_name}.cpp -``` - -# Package Reference - -Use `GTest` and `GMock` from the CMake `GTest` package. Link test targets with -`GTest::gtest_main` and `GTest::gmock`. - -# Test Style - -Test names appear in requirements traceability matrices - use the hierarchical -naming pattern with snake_case, split across the gtest suite and test name: - -- **System tests**: `TEST({system_name}_test, {functionality}_{scenario}_{expected_behavior})` -- **Subsystem tests**: `TEST({subsystem_name}_test, {functionality}_{scenario}_{expected_behavior})` -- **Unit tests**: `TEST({class_name}_test, {method_name}_{scenario}_{expected_behavior})` -- Use `TEST_F` with a fixture class when shared setup is needed - -```cpp -/// @brief Validates that an invalid email format throws std::invalid_argument. -TEST(user_validator_test, validate_email_invalid_format_throws) -{ - // Arrange: create a validator with default configuration - user_validator validator; - - // Act / Assert: email with no domain throws - EXPECT_THROW(validator.validate_email("not-an-email"), std::invalid_argument); -} -``` - -# gtest/gmock Specifics - -These are non-obvious behaviors that differ from common assumptions: - -- **`EXPECT_*` vs `ASSERT_*`**: `ASSERT_*` aborts the test immediately; prefer - `EXPECT_*` for independent checks to surface all failures in one run -- **`EXPECT_CALL` placement**: all mock expectations must be set up in Arrange, - before the Act step - expectations placed after the call under test are never triggered -- **`NiceMock` vs `StrictMock`**: bare mocks warn on unexpected calls; `NiceMock` - silences them; `StrictMock` makes them failures - choose deliberately - -# Quality Checks - -- [ ] All tests follow AAA pattern with descriptive section comments -- [ ] Test suite and test names follow hierarchical naming pattern above -- [ ] Each test verifies single, specific behavior (no shared state between tests) -- [ ] Both success and failure scenarios covered including edge cases -- [ ] External dependencies mocked with GMock -- [ ] Tests linked to requirements with source filters where needed -- [ ] Test results generated in JUnit XML format for ReqStream compatibility (`--gtest_output=xml`) 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 e1c3771..bc73da6 100644 --- a/.github/standards/reviewmark-usage.md +++ b/.github/standards/reviewmark-usage.md @@ -40,6 +40,7 @@ needs-review: - "!**/obj/**" - "requirements.yaml" - "docs/reqstream/**/*.yaml" + - "docs/sysml2/**/*.sysml" - "README.md" - "docs/user_guide/**/*.md" - "docs/design/**/*.md" @@ -120,15 +121,16 @@ placeholders are always PascalCase (e.g., `{SystemName}`). ## `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 +- **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) and requirements.yaml - (the structural tree); no system-level detail +- **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` + - SysML2 model: `docs/sysml2/**/*.sysml` - **Context Files**: `README.md`, `docs/user_guide/**/*.md` ## `{SystemName}-Architecture` Review (one per system) 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 c618ce8..408ef50 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -480,7 +480,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 === @@ -739,6 +739,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 9ecf55e..a980d32 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -13,6 +13,7 @@ needs-review: - "docs/design/**/*.md" # Design documentation files - "docs/verification/**/*.md" # Verification documentation files - "docs/user_guide/**/*.md" # User guide documentation + - "docs/sysml2/**/*.sysml" # SysML2 architecture model - "!**/obj/**" # Exclude build output - "!**/bin/**" # Exclude build output - "!node_modules/**" # Exclude npm dependencies @@ -51,6 +52,7 @@ reviews: paths: - requirements.yaml - docs/design/introduction.md + - "docs/sysml2/**/*.sysml" # TemplateTool - Specials - id: TemplateTool-Architecture @@ -74,6 +76,8 @@ reviews: - "docs/reqstream/template-dot-net-tool/platform-requirements.yaml" - "docs/design/introduction.md" - "docs/design/template-dot-net-tool/**/*.md" + - "docs/design/ots.md" + - "docs/verification/ots.md" - id: TemplateTool-AllRequirements title: Review of Template DotNet Tool requirements quality and traceability @@ -83,15 +87,6 @@ reviews: paths: - "docs/reqstream/template-dot-net-tool/**/*.yaml" - - id: OTS-Verification - title: Review of OTS software verification evidence - paths: - - "docs/reqstream/ots/*.yaml" - - "docs/design/ots.md" - - "docs/design/ots/*.md" - - "docs/verification/ots.md" - - "docs/verification/ots/*.md" - # TemplateTool - Program - id: TemplateTool-Program title: Review of Template DotNet Tool Program unit implementation @@ -233,6 +228,13 @@ reviews: - "docs/design/ots/sonarmark.md" - "docs/verification/ots/sonarmark.md" + - id: OTS-SysML2Tools + title: Review of SysML2Tools OTS verification evidence + paths: + - "docs/reqstream/ots/sysml2tools.yaml" + - "docs/design/ots/sysml2tools.md" + - "docs/verification/ots/sysml2tools.md" + - id: OTS-VersionMark title: Review of VersionMark OTS verification evidence paths: diff --git a/.versionmark.yaml b/.versionmark.yaml index 9275778..0074ac8 100644 --- a/.versionmark.yaml +++ b/.versionmark.yaml @@ -72,3 +72,8 @@ tools: fileassert: command: dotnet tool list regex: '(?i)demaconsulting\.fileassert\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 08949f4..cf5e111 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,6 +27,7 @@ │ ├── requirements_doc/ │ ├── requirements_report/ │ ├── reqstream/ +│ ├── sysml2/ │ ├── user_guide/ │ └── verification/ ├── src/ @@ -50,10 +51,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 @@ -68,6 +71,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. @@ -84,6 +88,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. @@ -138,7 +143,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/definition.yaml b/docs/design/definition.yaml index 506d1a9..ad5fdc0 100644 --- a/docs/design/definition.yaml +++ b/docs/design/definition.yaml @@ -27,6 +27,7 @@ input-files: - docs/design/ots/reviewmark.md - docs/design/ots/sarifmark.md - docs/design/ots/sonarmark.md + - docs/design/ots/sysml2tools.md - docs/design/ots/versionmark.md - docs/design/ots/weasyprint.md - docs/design/ots/xunit.md diff --git a/docs/design/introduction.md b/docs/design/introduction.md index 7ba656b..14b1a0c 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -35,6 +35,7 @@ This document covers the detailed design of the following software items: - **ReviewMark** — integration and usage design - **SarifMark** — integration and usage design - **SonarMark** — integration and usage design +- **SysML2Tools** — integration and usage design - **VersionMark** — integration and usage design - **WeasyPrint** — integration and usage design - **xUnit** — integration and usage design @@ -46,19 +47,15 @@ The following topics are out of scope: ## Software Structure -The following tree shows how the Template DotNet Tool software items are organized across the -system, subsystem, and unit levels: +The software structure is modeled in SysML2 under `docs/sysml2/` and rendered to the +diagram below by SysML2Tools as part of the build pipeline. AI agents should query the +SysML2 model directly (see the `sysml2tools-query` skill) rather than parsing this +diagram or the prose below. The model represents the shipped system's runtime composition +(subsystems and units) only; OTS dependencies below are build-time/pipeline tooling and are +intentionally not modeled as SysML2 parts, though each is fully documented as an OTS +dependency (design/verification/reqstream artifacts and `.reviewmark.yaml` review-sets). -```text -TemplateDotNetTool (System) -├── Program (Unit) -├── Cli (Subsystem) -│ └── Context (Unit) -├── SelfTest (Subsystem) -│ └── Validation (Unit) -└── Utilities (Subsystem) - └── PathHelpers (Unit) -``` +![Software Structure](SoftwareStructureView.svg) **OTS Dependencies:** @@ -69,6 +66,7 @@ TemplateDotNetTool (System) - ReviewMark (OTS) — file review enforcement tool - SarifMark (OTS) — SARIF report conversion tool - SonarMark (OTS) — SonarCloud quality report tool +- SysML2Tools (OTS) — architecture model validation and diagram rendering tool - VersionMark (OTS) — tool-version documentation tool - WeasyPrint (OTS) — HTML-to-PDF conversion tool - xUnit (OTS) — unit-testing framework diff --git a/docs/design/ots.md b/docs/design/ots.md index c3abed9..8f7fee8 100644 --- a/docs/design/ots.md +++ b/docs/design/ots.md @@ -20,6 +20,7 @@ The following OTS items have integration design documentation: - ReviewMark (_reviewmark.md_) — file review enforcement tool - SarifMark (_sarifmark.md_) — SARIF report conversion tool - SonarMark (_sonarmark.md_) — SonarCloud quality report tool +- SysML2Tools (_sysml2tools.md_) — architecture model validation and diagram rendering tool - VersionMark (_versionmark.md_) — tool-version documentation tool - WeasyPrint (_weasyprint.md_) — HTML-to-PDF conversion tool - xUnit (_xunit.md_) — unit-testing framework diff --git a/docs/design/ots/sysml2tools.md b/docs/design/ots/sysml2tools.md new file mode 100644 index 0000000..7b605ce --- /dev/null +++ b/docs/design/ots/sysml2tools.md @@ -0,0 +1,52 @@ +## SysML2Tools OTS Design + +DemaConsulting.SysML2Tools is a .NET local tool that lints a SysML2 architecture model +and renders its declared views to SVG diagrams consumed by the design documentation. + +### Purpose + +SysML2Tools provides the toolchain that keeps TemplateDotNetTool's architecture model +(`docs/sysml2/model/**/*.sysml`) and its declared views (`docs/sysml2/views/design-views.sysml`) +consistent with the design documentation. It validates the model for syntax and reference errors, +and renders each declared view to an SVG diagram embedded directly in the corresponding design +document (for example `docs/design/introduction.md` embeds `SoftwareStructureView.svg`). AI agents +also query the model directly via the `sysml2tools-query` skill rather than parsing the rendered +diagrams or hand-maintained prose. + +SysML2Tools is chosen because it is the reference implementation for the SysML v2 subset used by +this project's Continuous Compliance methodology, and it integrates directly with the same +dotnet-tool restore and CI pipeline used by the other pipeline tools. + +### Features Used + +- Model validation via `dotnet sysml2tools lint 'docs/sysml2/**/*.sysml'`, which reports syntax + errors and unresolved references without producing output files. +- View rendering via + `dotnet sysml2tools render --output docs/design/generated --format svg 'docs/sysml2/model/**/*.sysml' 'docs/sysml2/views/design-views.sysml'`, + which renders every `view` declared in `design-views.sysml` to an SVG file named after the view + (for example `SoftwareStructureView.svg`). +- Model querying via the `sysml2tools-query` skill, used by AI agents to answer structural and + traceability questions about the model without parsing the raw SysML2 source or the rendered + diagrams. + +### Integration Pattern + +SysML2Tools is installed as a .NET local tool defined in `.config/dotnet-tools.json` under the +package name `demaconsulting.sysml2tools.tool` and restored with `dotnet tool restore`. It operates +directly on the SysML2 source files under `docs/sysml2/`; no separate configuration file is +required. + +It is used in two places in the pipeline: + +- **Lint** (`lint.ps1`, all CI jobs and local pre-PR checks): `dotnet sysml2tools lint + 'docs/sysml2/**/*.sysml'` fails the build if the model contains syntax errors or unresolved + references. +- **Render** (`build.yaml`, build-docs job): `dotnet sysml2tools render` renders each declared view + to an SVG file in `docs/design/generated/`, immediately before Pandoc compiles the Design + document. The rendered SVGs sit alongside the compiled `design.html`, so the design Markdown + sources embed bare filenames (for example `![Software Structure](SoftwareStructureView.svg)`) + that Pandoc and the browser resolve relative to that directory. + +SysML2Tools reads only the local SysML2 model files and writes only local SVG output files; it +requires no external service or network access, and it has no transitive NuGet dependencies that +propagate to the main source project. It is a build-time tool only. diff --git a/docs/design/template-dot-net-tool.md b/docs/design/template-dot-net-tool.md index 669ac6e..c8661f1 100644 --- a/docs/design/template-dot-net-tool.md +++ b/docs/design/template-dot-net-tool.md @@ -1,5 +1,7 @@ # TemplateDotNetTool +![TemplateDotNetTool Structure](TemplateDotNetToolView.svg) + ## Architecture The Template DotNet Tool is a command-line application built on .NET. It is structured as one diff --git a/docs/design/template-dot-net-tool/cli.md b/docs/design/template-dot-net-tool/cli.md index 0ab2cf9..af971a5 100644 --- a/docs/design/template-dot-net-tool/cli.md +++ b/docs/design/template-dot-net-tool/cli.md @@ -1,5 +1,7 @@ ## Cli +![Cli Structure](CliView.svg) + ### Overview The `Cli` subsystem is the boundary between the host environment's command-line invocation and diff --git a/docs/design/template-dot-net-tool/cli/context.md b/docs/design/template-dot-net-tool/cli/context.md index 6610a76..cc7ea20 100644 --- a/docs/design/template-dot-net-tool/cli/context.md +++ b/docs/design/template-dot-net-tool/cli/context.md @@ -1,5 +1,7 @@ ### Context +![Cli Structure](CliView.svg) + #### Purpose `Context` handles command-line argument parsing and program output for one tool invocation. Its diff --git a/docs/design/template-dot-net-tool/program.md b/docs/design/template-dot-net-tool/program.md index a659d79..0e44bd6 100644 --- a/docs/design/template-dot-net-tool/program.md +++ b/docs/design/template-dot-net-tool/program.md @@ -1,5 +1,7 @@ ## Program +![TemplateDotNetTool Structure](TemplateDotNetToolView.svg) + ### Purpose `Program` is the entry point and execution orchestrator for the Template DotNet Tool. Its single diff --git a/docs/design/template-dot-net-tool/self-test.md b/docs/design/template-dot-net-tool/self-test.md index 792da61..560a8b0 100644 --- a/docs/design/template-dot-net-tool/self-test.md +++ b/docs/design/template-dot-net-tool/self-test.md @@ -1,5 +1,7 @@ ## SelfTest +![SelfTest Structure](SelfTestView.svg) + ### Overview The `SelfTest` subsystem provides the self-validation framework for the Template DotNet Tool. diff --git a/docs/design/template-dot-net-tool/self-test/validation.md b/docs/design/template-dot-net-tool/self-test/validation.md index 0ab861c..f9039fc 100644 --- a/docs/design/template-dot-net-tool/self-test/validation.md +++ b/docs/design/template-dot-net-tool/self-test/validation.md @@ -1,5 +1,7 @@ ### Validation +![SelfTest Structure](SelfTestView.svg) + #### Purpose `Validation` orchestrates the self-validation test suite. Its single responsibility is to run a diff --git a/docs/design/template-dot-net-tool/utilities.md b/docs/design/template-dot-net-tool/utilities.md index 54c7579..19dd2b7 100644 --- a/docs/design/template-dot-net-tool/utilities.md +++ b/docs/design/template-dot-net-tool/utilities.md @@ -1,5 +1,7 @@ ## Utilities +![Utilities Structure](UtilitiesView.svg) + ### Overview The `Utilities` subsystem provides shared utility functions for the Template DotNet Tool. It diff --git a/docs/design/template-dot-net-tool/utilities/path-helpers.md b/docs/design/template-dot-net-tool/utilities/path-helpers.md index 44e248a..b32b02b 100644 --- a/docs/design/template-dot-net-tool/utilities/path-helpers.md +++ b/docs/design/template-dot-net-tool/utilities/path-helpers.md @@ -1,5 +1,7 @@ ### PathHelpers +![Utilities Structure](UtilitiesView.svg) + #### Purpose `PathHelpers` is a static utility class that provides a safe path-combination method. Its diff --git a/docs/reqstream/ots/sysml2tools.yaml b/docs/reqstream/ots/sysml2tools.yaml new file mode 100644 index 0000000..e84ee35 --- /dev/null +++ b/docs/reqstream/ots/sysml2tools.yaml @@ -0,0 +1,27 @@ +--- +# SysML2Tools OTS Software Requirements +# +# Requirements for the SysML2Tools architecture modeling tool functionality. + +sections: + - title: OTS Software Requirements + sections: + - title: SysML2Tools Requirements + requirements: + - id: Template-OTS-SysML2Tools-Lint + title: SysML2Tools shall validate the SysML2 model for syntax and reference errors. + justification: | + Linting the model in CI catches broken references and syntax errors in the + architecture model before they reach the generated documentation. + tags: [ots] + tests: + - SysML2Tools_LintSelfTest + + - id: Template-OTS-SysML2Tools-Render + title: SysML2Tools shall render the declared views to SVG diagrams. + justification: | + The rendered diagrams are embedded in the design documentation, so a failure to + render must fail the build rather than silently omit a diagram. + tags: [ots] + tests: + - SysML2Tools_RenderSvgSelfTest diff --git a/docs/sysml2/model/template-dot-net-tool.sysml b/docs/sysml2/model/template-dot-net-tool.sysml new file mode 100644 index 0000000..3d57d89 --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool.sysml @@ -0,0 +1,21 @@ +package TemplateDotNetTool { + doc + /* + * TemplateDotNetTool is a template .NET command-line application demonstrating + * DemaConsulting's compliance/documentation tooling conventions. + */ + + part def TemplateDotNetToolSystem { + doc /* The TemplateDotNetTool system as a whole. */ + + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/IntegrationTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool.yaml */ + + part program : Program; + part cli : CliSubsystem; + part selfTest : SelfTestSubsystem; + part utilities : UtilitiesSubsystem; + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/cli.sysml b/docs/sysml2/model/template-dot-net-tool/cli.sysml new file mode 100644 index 0000000..d59a5ba --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/cli.sysml @@ -0,0 +1,12 @@ +package TemplateDotNetTool { + part def CliSubsystem { + doc /* Command-line argument parsing, output-channel management, and exit-code tracking. */ + + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/Cli/CliSubsystemTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/cli.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/cli.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/cli.yaml */ + + part context : Context; + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/cli/context.sysml b/docs/sysml2/model/template-dot-net-tool/cli/context.sysml new file mode 100644 index 0000000..623ddf9 --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/cli/context.sysml @@ -0,0 +1,11 @@ +package TemplateDotNetTool { + part def Context { + doc /* Command-line argument parser and I/O owner for one tool invocation. */ + + comment sourceRef /* Source: src/DemaConsulting.TemplateDotNetTool/Cli/Context.cs */ + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/Cli/ContextTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/cli/context.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/cli/context.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/cli/context.yaml */ + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/program.sysml b/docs/sysml2/model/template-dot-net-tool/program.sysml new file mode 100644 index 0000000..fbdbd0c --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/program.sysml @@ -0,0 +1,11 @@ +package TemplateDotNetTool { + part def Program { + doc /* Entry point and execution orchestrator. */ + + comment sourceRef /* Source: src/DemaConsulting.TemplateDotNetTool/Program.cs */ + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/ProgramTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/program.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/program.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/program.yaml */ + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/self-test.sysml b/docs/sysml2/model/template-dot-net-tool/self-test.sysml new file mode 100644 index 0000000..49ad092 --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/self-test.sysml @@ -0,0 +1,12 @@ +package TemplateDotNetTool { + part def SelfTestSubsystem { + doc /* Self-validation framework exercising the tool's own capabilities on demand. */ + + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/SelfTest/SelfTestSubsystemTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/self-test.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/self-test.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/self-test.yaml */ + + part validation : Validation; + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/self-test/validation.sysml b/docs/sysml2/model/template-dot-net-tool/self-test/validation.sysml new file mode 100644 index 0000000..999157c --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/self-test/validation.sysml @@ -0,0 +1,11 @@ +package TemplateDotNetTool { + part def Validation { + doc /* Orchestrates the self-validation test suite and reports pass/fail results. */ + + comment sourceRef /* Source: src/DemaConsulting.TemplateDotNetTool/SelfTest/Validation.cs */ + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/SelfTest/ValidationTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/self-test/validation.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/self-test/validation.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/self-test/validation.yaml */ + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/utilities.sysml b/docs/sysml2/model/template-dot-net-tool/utilities.sysml new file mode 100644 index 0000000..60613ba --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/utilities.sysml @@ -0,0 +1,12 @@ +package TemplateDotNetTool { + part def UtilitiesSubsystem { + doc /* Shared, independently testable helper functions used by other subsystems. */ + + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/Utilities/UtilitiesSubsystemTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/utilities.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/utilities.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/utilities.yaml */ + + part pathHelpers : PathHelpers; + } +} diff --git a/docs/sysml2/model/template-dot-net-tool/utilities/path-helpers.sysml b/docs/sysml2/model/template-dot-net-tool/utilities/path-helpers.sysml new file mode 100644 index 0000000..4604474 --- /dev/null +++ b/docs/sysml2/model/template-dot-net-tool/utilities/path-helpers.sysml @@ -0,0 +1,11 @@ +package TemplateDotNetTool { + part def PathHelpers { + doc /* Safe path-combination utility guarding against path-traversal. */ + + comment sourceRef /* Source: src/DemaConsulting.TemplateDotNetTool/Utilities/PathHelpers.cs */ + comment testRef /* Test: test/DemaConsulting.TemplateDotNetTool.Tests/Utilities/PathHelpersTests.cs */ + comment designRef /* Design: docs/design/template-dot-net-tool/utilities/path-helpers.md */ + comment verificationRef /* Verification: docs/verification/template-dot-net-tool/utilities/path-helpers.md */ + comment reqRef /* Requirements: docs/reqstream/template-dot-net-tool/utilities/path-helpers.yaml */ + } +} diff --git a/docs/sysml2/views/design-views.sysml b/docs/sysml2/views/design-views.sysml new file mode 100644 index 0000000..8cfa156 --- /dev/null +++ b/docs/sysml2/views/design-views.sysml @@ -0,0 +1,26 @@ +// Views rendered into docs/design/generated/ for the Design document. +// Reopens the TemplateDotNetTool 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 TemplateDotNetTool { + view SoftwareStructureView { + expose TemplateDotNetTool; + } + + view TemplateDotNetToolView { + expose TemplateDotNetToolSystem; + } + + view CliView { + expose CliSubsystem; + } + + view SelfTestView { + expose SelfTestSubsystem; + } + + view UtilitiesView { + expose UtilitiesSubsystem; + } +} diff --git a/docs/verification/definition.yaml b/docs/verification/definition.yaml index f6a1ae2..014fb91 100644 --- a/docs/verification/definition.yaml +++ b/docs/verification/definition.yaml @@ -27,6 +27,7 @@ input-files: - docs/verification/ots/reviewmark.md - docs/verification/ots/sarifmark.md - docs/verification/ots/sonarmark.md + - docs/verification/ots/sysml2tools.md - docs/verification/ots/versionmark.md - docs/verification/ots/weasyprint.md - docs/verification/ots/xunit.md diff --git a/docs/verification/introduction.md b/docs/verification/introduction.md index 18ebb89..21d4924 100644 --- a/docs/verification/introduction.md +++ b/docs/verification/introduction.md @@ -35,6 +35,7 @@ This document covers the verification design for the following software items: - **ReviewMark** — file review enforcement tool - **SarifMark** — SARIF report conversion tool - **SonarMark** — SonarCloud quality report tool +- **SysML2Tools** — architecture model validation and diagram rendering tool - **VersionMark** — tool-version documentation tool - **WeasyPrint** — HTML-to-PDF conversion tool - **xUnit** — unit-testing framework @@ -47,33 +48,6 @@ The following topics are out of scope: - The internal implementation of OTS software items is excluded; only integration and usage are verified -## Software Structure - -The following tree shows the software items covered by this document: - -```text -TemplateDotNetTool (System) -├── Program (Unit) -├── Cli (Subsystem) -│ └── Context (Unit) -├── SelfTest (Subsystem) -│ └── Validation (Unit) -└── Utilities (Subsystem) - └── PathHelpers (Unit) - -OTS Items -├── BuildMark -├── FileAssert -├── Pandoc -├── ReqStream -├── ReviewMark -├── SarifMark -├── SonarMark -├── VersionMark -├── WeasyPrint -└── xUnit -``` - ## Folder Layout The test folder structure mirrors the source subsystem breakdown: diff --git a/docs/verification/ots.md b/docs/verification/ots.md index c3ca567..c5a6f8e 100644 --- a/docs/verification/ots.md +++ b/docs/verification/ots.md @@ -23,6 +23,7 @@ The following OTS items have verification evidence in this section: - ReviewMark (_reviewmark.md_) — file review enforcement tool - SarifMark (_sarifmark.md_) — SARIF report conversion tool - SonarMark (_sonarmark.md_) — SonarCloud quality report tool +- SysML2Tools (_sysml2tools.md_) — architecture model validation and diagram rendering tool - VersionMark (_versionmark.md_) — tool-version documentation tool - WeasyPrint (_weasyprint.md_) — HTML-to-PDF conversion tool - xUnit (_xunit.md_) — unit-testing framework diff --git a/docs/verification/ots/sysml2tools.md b/docs/verification/ots/sysml2tools.md new file mode 100644 index 0000000..e0d3792 --- /dev/null +++ b/docs/verification/ots/sysml2tools.md @@ -0,0 +1,53 @@ +## SysML2Tools Verification + +This document provides the verification evidence for the `SysML2Tools` OTS software item. +Requirements for this OTS item are defined in the SysML2Tools OTS Software Requirements document. + +### Required Functionality + +DemaConsulting.SysML2Tools validates the SysML2 architecture model under `docs/sysml2/` for syntax +and reference errors, and renders each view declared in `docs/sysml2/views/design-views.sysml` to +an SVG diagram embedded in the design documentation. Both behaviors run in the same CI pipeline +that produces the compiled Design document, so a successful pipeline run is evidence that +SysML2Tools executed without error. + +### Verification Approach + +SysML2Tools is verified by a combination of authored self-validation evidence and CI pipeline +evidence: + +- **Self-validation evidence**: `dotnet sysml2tools --validate --results ` runs the + tool's built-in self-test suite, which exercises `lint` and `render --format svg` against known + model fixtures and writes a TRX file consumed by `reqstream --enforce` + (`SysML2Tools_LintSelfTest`, `SysML2Tools_RenderSvgSelfTest`). +- **Pipeline evidence**: `lint.ps1` runs `dotnet sysml2tools lint 'docs/sysml2/**/*.sysml'` against + the actual TemplateDotNetTool model and fails the build on any syntax or reference error. The + build-docs job runs `dotnet sysml2tools render` to produce one SVG file per declared view under + `docs/design/generated/`. Pandoc then compiles `docs/design/*.md`, which embed those SVG files by + filename; if a declared view failed to render, the missing image reference would cause a broken + image in the compiled Design HTML and PDF. WeasyPrint renders the result to PDF and FileAssert + asserts its content. A CI build failure at either step is evidence that SysML2Tools did not + produce the required model validation or diagrams against the real model. + +### Test Scenarios + +#### SysML2Tools_LintSelfTest + +**Scenario**: SysML2Tools is invoked with `--validate`, which exercises `lint` against a known-good +and a known-bad model fixture as part of its built-in self-test suite. + +**Expected**: Exits 0 with no reported syntax or reference errors for the valid fixture, and +correctly reports an error for the invalid fixture. + +#### SysML2Tools_RenderSvgSelfTest + +**Scenario**: SysML2Tools is invoked with `--validate`, which exercises `render --format svg` +against a known-good model fixture as part of its built-in self-test suite. + +**Expected**: Exits 0 and produces a non-empty SVG file for the fixture's declared view. + +### Acceptance Criteria + +N/A - Acceptance criteria are managed at the system integration level. This OTS item is considered +verified when the integration test scenarios that exercise its functionality pass in the CI +pipeline. diff --git a/lint.ps1 b/lint.ps1 index e4d68ac..89b344d 100644 --- a/lint.ps1 +++ b/lint.ps1 @@ -99,7 +99,7 @@ if (-not $skipNpm) { # } # --- DOTNET LINTING SECTION --- -# Runs compliance tools: reqstream, versionmark, reviewmark. +# Runs compliance tools: reqstream, versionmark, reviewmark, sysml2tools. Write-Host "Linting: compliance tools..." $skipDotnetTools = $false dotnet tool restore > $null @@ -114,6 +114,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 lint checks here. diff --git a/requirements.yaml b/requirements.yaml index ffa543e..4609fa6 100644 --- a/requirements.yaml +++ b/requirements.yaml @@ -20,3 +20,4 @@ includes: - docs/reqstream/ots/pandoc.yaml - docs/reqstream/ots/weasyprint.yaml - docs/reqstream/ots/fileassert.yaml + - docs/reqstream/ots/sysml2tools.yaml From 5f05f264e8dd3929f1b0f5b95401db9945f237a1 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Sat, 11 Jul 2026 11:59:37 -0400 Subject: [PATCH 2/3] Restructure docs/design/introduction.md to match template/FileAssert style - Trim the Scope section's local-items enumeration to a terser one-liner (matching the template's example and FileAssert's pattern) instead of listing every subsystem/unit individually - Remove the redundant OTS Dependencies bullet list and trailing sentence that followed the Software Structure diagram - that information already lives in Scope, and the template's Software Structure section is only the directing paragraph plus the rendered diagram - Convert Folder Layout from a hand-drawn fenced-tree to the template's bullet-list format - Align Purpose/opening paragraph wording with the template's example phrasing Re-verified clean by the change-review and Decomposition formal-review agents (gpt-5.4-mini) after this restructure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/introduction.md | 95 +++++++++++++------------------------ 1 file changed, 33 insertions(+), 62 deletions(-) diff --git a/docs/design/introduction.md b/docs/design/introduction.md index 14b1a0c..20f795a 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -1,44 +1,37 @@ # Introduction This document provides the detailed design for the Template DotNet Tool, a .NET command-line -application demonstrating best practices for DEMA Consulting DotNet Tools. +application demonstrating best practices for DEMA Consulting DotNet Tools. It covers local +software items (systems, subsystems, and units) and the OTS software items they consume. ## Purpose The purpose of this document is to describe the internal design of each software unit that comprises the Template DotNet Tool. It captures data models, algorithms, key methods, and inter-unit interactions at a level of detail sufficient for formal code review, compliance -verification, and future maintenance. The document does not restate requirements; it explains -how they are realized. +verification, and future maintenance. A reviewer should be able to understand how each item +satisfies its requirements without reading source code. The document does not restate +requirements; it explains how they are realized. ## Scope -This document covers the detailed design of the following software items: - -**Local items:** - -- **TemplateDotNetTool** — the system as a whole -- **Program** — entry point and execution orchestrator -- **Cli** subsystem - - **Context** — command-line argument parser and I/O owner -- **SelfTest** subsystem - - **Validation** — self-validation test runner -- **Utilities** subsystem - - **PathHelpers** — safe path combination utilities - -**OTS items:** - -- **BuildMark** — integration and usage design -- **FileAssert** — integration and usage design -- **Pandoc** — integration and usage design -- **ReqStream** — integration and usage design -- **ReviewMark** — integration and usage design -- **SarifMark** — integration and usage design -- **SonarMark** — integration and usage design -- **SysML2Tools** — integration and usage design -- **VersionMark** — integration and usage design -- **WeasyPrint** — integration and usage design -- **xUnit** — integration and usage design +Local items: + +- **TemplateDotNetTool**: system, subsystem, and unit design for all local components. + +OTS items: + +- **BuildMark**: integration and usage design. +- **FileAssert**: integration and usage design. +- **Pandoc**: integration and usage design. +- **ReqStream**: integration and usage design. +- **ReviewMark**: integration and usage design. +- **SarifMark**: integration and usage design. +- **SonarMark**: integration and usage design. +- **SysML2Tools**: integration and usage design. +- **VersionMark**: integration and usage design. +- **WeasyPrint**: integration and usage design. +- **xUnit**: integration and usage design. The following topics are out of scope: @@ -47,44 +40,22 @@ The following topics are out of scope: ## Software Structure -The software structure is modeled in SysML2 under `docs/sysml2/` and rendered to the -diagram below by SysML2Tools as part of the build pipeline. AI agents should query the -SysML2 model directly (see the `sysml2tools-query` skill) rather than parsing this -diagram or the prose below. The model represents the shipped system's runtime composition -(subsystems and units) only; OTS dependencies below are build-time/pipeline tooling and are -intentionally not modeled as SysML2 parts, though each is fully documented as an OTS -dependency (design/verification/reqstream artifacts and `.reviewmark.yaml` review-sets). +The software structure is modeled in SysML2 under `docs/sysml2/` and rendered to the diagram +below by SysML2Tools as part of the build pipeline. AI agents should query the SysML2 model +directly (see the `sysml2tools-query` skill) rather than parsing this diagram or the prose +elsewhere in this document. The model captures the shipped system's runtime composition only; +the OTS items listed in Scope above are build-time/pipeline tooling, documented separately +(see `docs/design/ots.md`) rather than modeled as SysML2 parts. ![Software Structure](SoftwareStructureView.svg) -**OTS Dependencies:** - -- BuildMark (OTS) — build-notes documentation tool -- FileAssert (OTS) — document assertion tool -- Pandoc (OTS) — Markdown-to-HTML conversion tool -- ReqStream (OTS) — requirements traceability tool -- ReviewMark (OTS) — file review enforcement tool -- SarifMark (OTS) — SARIF report conversion tool -- SonarMark (OTS) — SonarCloud quality report tool -- SysML2Tools (OTS) — architecture model validation and diagram rendering tool -- VersionMark (OTS) — tool-version documentation tool -- WeasyPrint (OTS) — HTML-to-PDF conversion tool -- xUnit (OTS) — unit-testing framework - -Each local unit is described in detail in its own chapter within this document. - ## Folder Layout -The source code folder structure mirrors the top-level subsystem breakdown above, giving -reviewers an explicit navigation aid from design to code: - -```text -src/ -└── DemaConsulting.TemplateDotNetTool/ — main application source - ├── Cli/ — command-line interface subsystem - ├── SelfTest/ — self-validation subsystem - └── Utilities/ — shared utilities subsystem -``` +- **src/** - source files and projects + - **DemaConsulting.TemplateDotNetTool/** - main application source + - **Cli/** - command-line interface subsystem + - **SelfTest/** - self-validation subsystem + - **Utilities/** - shared utilities subsystem ## Document Conventions From a79b6fb7fbe823401be257efe20a7cabe81cebd5 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Sat, 11 Jul 2026 12:29:42 -0400 Subject: [PATCH 3/3] Fix SysML2Tools OTS verification: assert rendered SVGs directly with FileAssert The verification approach previously claimed a missing rendered SVG would break the compiled Design HTML/PDF build - this is incorrect, since Pandoc/WeasyPrint silently omit missing images rather than failing. - Add SysML2Tools_DesignDiagramsSvg FileAssert test asserting the 5 expected rendered SVGs exist in docs/design/generated/ and are well-formed SVG/XML - Wire the new test into Template-OTS-SysML2Tools-Render's evidence - Rewrite the Verification Approach and add a Test Scenario in docs/verification/ots/sysml2tools.md - Update docs/design/ots/sysml2tools.md's Integration Pattern to note FileAssert's role in verifying the render output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .fileassert.yaml | 35 +++++++++++++++++++++ docs/design/ots/sysml2tools.md | 5 ++- docs/reqstream/ots/sysml2tools.yaml | 10 ++++-- docs/verification/ots/sysml2tools.md | 47 +++++++++++++++++++++------- 4 files changed, 83 insertions(+), 14 deletions(-) diff --git a/.fileassert.yaml b/.fileassert.yaml index 33045ce..4c0b8b2 100644 --- a/.fileassert.yaml +++ b/.fileassert.yaml @@ -143,6 +143,41 @@ tests: # --- DESIGN DOCUMENT --- + - name: SysML2Tools_DesignDiagramsSvg + description: "Software Structure diagrams were rendered by SysML2Tools" + tags: [design] + files: + - pattern: "docs/design/generated/SoftwareStructureView.svg" + count: 1 + min-size: 100 + xml: + - query: "//*[local-name()='svg']" + count: 1 + - pattern: "docs/design/generated/TemplateDotNetToolView.svg" + count: 1 + min-size: 100 + xml: + - query: "//*[local-name()='svg']" + count: 1 + - pattern: "docs/design/generated/CliView.svg" + count: 1 + min-size: 100 + xml: + - query: "//*[local-name()='svg']" + count: 1 + - pattern: "docs/design/generated/SelfTestView.svg" + count: 1 + min-size: 100 + xml: + - query: "//*[local-name()='svg']" + count: 1 + - pattern: "docs/design/generated/UtilitiesView.svg" + count: 1 + min-size: 100 + xml: + - query: "//*[local-name()='svg']" + count: 1 + - name: Pandoc_DesignHtml description: "Design HTML was generated by Pandoc" tags: [design] diff --git a/docs/design/ots/sysml2tools.md b/docs/design/ots/sysml2tools.md index 7b605ce..ed0d868 100644 --- a/docs/design/ots/sysml2tools.md +++ b/docs/design/ots/sysml2tools.md @@ -45,7 +45,10 @@ It is used in two places in the pipeline: to an SVG file in `docs/design/generated/`, immediately before Pandoc compiles the Design document. The rendered SVGs sit alongside the compiled `design.html`, so the design Markdown sources embed bare filenames (for example `![Software Structure](SoftwareStructureView.svg)`) - that Pandoc and the browser resolve relative to that directory. + that Pandoc and the browser resolve relative to that directory. A missing SVG does not fail the + Pandoc/WeasyPrint build - the compiled document simply omits the diagram - so FileAssert asserts + each expected SVG file exists and is well-formed XML immediately after the render step, providing + the actual pipeline evidence that render succeeded (see `docs/design/ots/fileassert.md`). SysML2Tools reads only the local SysML2 model files and writes only local SVG output files; it requires no external service or network access, and it has no transitive NuGet dependencies that diff --git a/docs/reqstream/ots/sysml2tools.yaml b/docs/reqstream/ots/sysml2tools.yaml index e84ee35..7c766dd 100644 --- a/docs/reqstream/ots/sysml2tools.yaml +++ b/docs/reqstream/ots/sysml2tools.yaml @@ -20,8 +20,14 @@ sections: - id: Template-OTS-SysML2Tools-Render title: SysML2Tools shall render the declared views to SVG diagrams. justification: | - The rendered diagrams are embedded in the design documentation, so a failure to - render must fail the build rather than silently omit a diagram. + The rendered diagrams are embedded in the design documentation. Self-validation + proves the render command works against known fixtures, but a compiled PDF with a + missing image reference does not fail the WeasyPrint build - it simply omits the + diagram silently. FileAssert therefore asserts, after the real render step, that + each declared view's SVG file actually exists in docs/design/generated and is + well-formed XML, which is the only evidence that render succeeded against this + project's actual model. tags: [ots] tests: - SysML2Tools_RenderSvgSelfTest + - SysML2Tools_DesignDiagramsSvg diff --git a/docs/verification/ots/sysml2tools.md b/docs/verification/ots/sysml2tools.md index e0d3792..4272282 100644 --- a/docs/verification/ots/sysml2tools.md +++ b/docs/verification/ots/sysml2tools.md @@ -13,21 +13,30 @@ SysML2Tools executed without error. ### Verification Approach -SysML2Tools is verified by a combination of authored self-validation evidence and CI pipeline -evidence: +SysML2Tools is verified by a combination of authored self-validation evidence and direct FileAssert +assertions on its actual pipeline output: - **Self-validation evidence**: `dotnet sysml2tools --validate --results ` runs the tool's built-in self-test suite, which exercises `lint` and `render --format svg` against known model fixtures and writes a TRX file consumed by `reqstream --enforce` - (`SysML2Tools_LintSelfTest`, `SysML2Tools_RenderSvgSelfTest`). -- **Pipeline evidence**: `lint.ps1` runs `dotnet sysml2tools lint 'docs/sysml2/**/*.sysml'` against - the actual TemplateDotNetTool model and fails the build on any syntax or reference error. The - build-docs job runs `dotnet sysml2tools render` to produce one SVG file per declared view under - `docs/design/generated/`. Pandoc then compiles `docs/design/*.md`, which embed those SVG files by - filename; if a declared view failed to render, the missing image reference would cause a broken - image in the compiled Design HTML and PDF. WeasyPrint renders the result to PDF and FileAssert - asserts its content. A CI build failure at either step is evidence that SysML2Tools did not - produce the required model validation or diagrams against the real model. + (`SysML2Tools_LintSelfTest`, `SysML2Tools_RenderSvgSelfTest`). This proves the tool's `lint` and + `render` commands work correctly in isolation, but does not prove they were actually invoked + successfully against this project's real model. +- **Lint pipeline evidence**: `lint.ps1` runs `dotnet sysml2tools lint 'docs/sysml2/**/*.sysml'` + against the actual TemplateDotNetTool model and fails the build on any syntax or reference error. + A build failure here is direct evidence that lint did not pass against the real model; a + successful build is direct evidence that it did. +- **Render pipeline evidence**: The build-docs job runs `dotnet sysml2tools render` to produce one + SVG file per declared view under `docs/design/generated/`, immediately before Pandoc compiles + `docs/design/*.md` (which embed those SVG files by filename) and WeasyPrint renders the result to + PDF. A missing SVG does **not** fail the Pandoc/WeasyPrint build - the compiled HTML/PDF simply + omits the diagram silently - so a successful Pandoc/WeasyPrint build is not sufficient evidence + that render succeeded. Instead, `SysML2Tools_DesignDiagramsSvg` is a FileAssert test that runs + immediately after the render step and directly asserts that each expected SVG file + (`SoftwareStructureView.svg`, `TemplateDotNetToolView.svg`, `CliView.svg`, `SelfTestView.svg`, + `UtilitiesView.svg`) exists in `docs/design/generated/`, has a non-trivial size, and is + well-formed XML with an `` root element. This is the only evidence that render actually + produced the required diagrams against the real model. ### Test Scenarios @@ -39,6 +48,8 @@ and a known-bad model fixture as part of its built-in self-test suite. **Expected**: Exits 0 with no reported syntax or reference errors for the valid fixture, and correctly reports an error for the invalid fixture. +**Requirement coverage**: `Template-OTS-SysML2Tools-Lint`. + #### SysML2Tools_RenderSvgSelfTest **Scenario**: SysML2Tools is invoked with `--validate`, which exercises `render --format svg` @@ -46,6 +57,20 @@ against a known-good model fixture as part of its built-in self-test suite. **Expected**: Exits 0 and produces a non-empty SVG file for the fixture's declared view. +**Requirement coverage**: `Template-OTS-SysML2Tools-Render`. + +#### SysML2Tools_DesignDiagramsSvg + +**Scenario**: FileAssert asserts, immediately after the real `dotnet sysml2tools render` step runs +against this project's actual model, that each of the five expected SVG files exists in +`docs/design/generated/`, has a non-trivial size, and is well-formed XML with an `` root +element. + +**Expected**: FileAssert exits 0, proving render produced every declared view's diagram against the +real model - not just the self-test's fixture. + +**Requirement coverage**: `Template-OTS-SysML2Tools-Render`. + ### Acceptance Criteria N/A - Acceptance criteria are managed at the system integration level. This OTS item is considered