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 3207e7b..e12009a 100644 --- a/.cspell.yaml +++ b/.cspell.yaml @@ -28,7 +28,9 @@ words: - dogfooding - enation - fileassert + - filesystemglobbing - fontconfig + - htmlagilitypack - initialise - initialized - initialisation @@ -38,6 +40,7 @@ words: - Pango - pandoc - pandoctool + - pdfpig - recognized - recognise - recognises @@ -53,12 +56,15 @@ words: - serialises - sonarcloud - sonarmark + - sysml + - sysml2tools - unrecognized - unrecognised - versionmark - Weasyprint - weasyprinttool - xunit + - yamldotnet - yamlfix # Exclude common build artifacts, dependencies, and vendored third-party code 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 a113f11..1ac04c4 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -463,7 +463,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 === @@ -722,6 +722,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/.gitignore b/.gitignore index 2d385e3..0abd133 100644 --- a/.gitignore +++ b/.gitignore @@ -90,6 +90,7 @@ __pycache__/ # Generated documentation docs/**/*.html docs/**/*.pdf +docs/design/generated/ !docs/template/** docs/requirements_doc/requirements.md docs/requirements_doc/justifications.md diff --git a/.reviewmark.yaml b/.reviewmark.yaml index 1588d0a..cd3dc93 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -13,6 +13,7 @@ needs-review: - "docs/reqstream/**/*.yaml" - "docs/design/**/*.md" - "docs/verification/**/*.md" + - "docs/sysml2/**/*.sysml" - "!**/obj/**" - "!**/bin/**" @@ -24,21 +25,38 @@ evidence-source: type: url location: https://raw.githubusercontent.com/demaconsulting/FileAssert/reviews/index.json +# Global context shown to every reviewer for orientation (not fingerprinted). +context: + - docs/design/introduction.md + # Review sets following standardized patterns for hierarchical compliance coverage reviews: # Purpose Review (only one per repository) - - id: FileAssert-Purpose - title: Review that Advertised Features Match System Design + - id: Purpose + title: Review that README and User Guide are Coherent and Complete + context: + - "!docs/design/introduction.md" # exclude design intro from user-facing review paths: - "README.md" # project readme - "docs/user_guide/**/*.md" # user guide - - "docs/reqstream/file-assert.yaml" # system requirements + + # Decomposition Review (only one per repository) + - id: Decomposition + title: Review that FileAssert Decomposition Addresses the Stated Purpose + context: + - "README.md" + - "docs/user_guide/**/*.md" + paths: + - "requirements.yaml" # root requirements file - "docs/design/introduction.md" # design introduction - - "docs/design/file-assert.md" # system design + - "docs/sysml2/**/*.sysml" # SysML2 model (authoritative structure) # FileAssert-Architecture Review (one per system) - id: FileAssert-Architecture title: Review that FileAssert Architecture Satisfies Requirements + context: + - "README.md" + - "docs/user_guide/**/*.md" paths: - "docs/reqstream/file-assert.yaml" # system requirements - "docs/design/introduction.md" # design introduction @@ -51,8 +69,9 @@ reviews: # FileAssert-Design Review (one per system) - id: FileAssert-Design title: Review that FileAssert Design is Consistent and Complete + context: + - "docs/reqstream/file-assert.yaml" paths: - - "docs/reqstream/file-assert.yaml" # system requirements - "docs/reqstream/file-assert/platform-requirements.yaml" # platform requirements - "docs/design/introduction.md" # design introduction - "docs/design/file-assert.md" # system design overview @@ -65,6 +84,9 @@ reviews: # FileAssert-AllRequirements Review (one per system) - id: FileAssert-AllRequirements title: Review that All FileAssert Requirements are Complete + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "requirements.yaml" # root requirements file - "docs/reqstream/**/*.yaml" # all requirements files @@ -72,6 +94,9 @@ reviews: # FileAssert-Cli Review (one per subsystem) - id: FileAssert-Cli title: Review that FileAssert Cli Satisfies Subsystem Requirements + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "docs/reqstream/file-assert/cli.yaml" # subsystem requirements - "docs/design/file-assert/cli.md" # subsystem design @@ -82,6 +107,9 @@ reviews: # FileAssert-Configuration Review (one per subsystem) - id: FileAssert-Configuration title: Review that FileAssert Configuration Satisfies Subsystem Requirements + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "docs/reqstream/file-assert/configuration.yaml" # subsystem requirements - "docs/design/file-assert/configuration.md" # subsystem design @@ -91,6 +119,9 @@ reviews: # FileAssert-Modeling Review (one per subsystem) - id: FileAssert-Modeling title: Review that FileAssert Modeling Satisfies Subsystem Requirements + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "docs/reqstream/file-assert/modeling.yaml" # subsystem requirements - "docs/design/file-assert/modeling.md" # subsystem design @@ -100,6 +131,9 @@ reviews: # FileAssert-Utilities Review (one per subsystem) - id: FileAssert-Utilities title: Review that FileAssert Utilities Satisfies Subsystem Requirements + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "docs/reqstream/file-assert/utilities.yaml" # subsystem requirements - "docs/design/file-assert/utilities.md" # subsystem design @@ -109,6 +143,9 @@ reviews: # FileAssert-SelfTest Review (one per subsystem) - id: FileAssert-SelfTest title: Review that FileAssert SelfTest Satisfies Subsystem Requirements + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "docs/reqstream/file-assert/selftest.yaml" # subsystem requirements - "docs/design/file-assert/selftest.md" # subsystem design @@ -118,6 +155,11 @@ reviews: # FileAssert-Cli-Context Review (one per unit) - id: FileAssert-Cli-Context title: Review that FileAssert Cli Context Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/cli.md" + - "docs/reqstream/file-assert/cli.yaml" paths: - "docs/reqstream/file-assert/cli/context.yaml" # requirements - "docs/design/file-assert/cli/context.md" # design @@ -129,6 +171,9 @@ reviews: # FileAssert-Program Review (one per unit) - id: FileAssert-Program title: Review that FileAssert Program Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" paths: - "docs/reqstream/file-assert/program.yaml" # requirements - "docs/design/file-assert/program.md" # design @@ -139,6 +184,11 @@ reviews: # FileAssert-SelfTest-Validation Review (one per unit) - id: FileAssert-SelfTest-Validation title: Review that FileAssert SelfTest Validation Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/selftest.md" + - "docs/reqstream/file-assert/selftest.yaml" paths: - "docs/reqstream/file-assert/selftest/validation.yaml" # requirements - "docs/design/file-assert/selftest/validation.md" # design @@ -149,6 +199,11 @@ reviews: # FileAssert-Utilities-PathHelpers Review (one per unit) - id: FileAssert-Utilities-PathHelpers title: Review that FileAssert Utilities PathHelpers Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/utilities.md" + - "docs/reqstream/file-assert/utilities.yaml" paths: - "docs/reqstream/file-assert/utilities/path-helpers.yaml" # requirements - "docs/design/file-assert/utilities/path-helpers.md" # design @@ -159,6 +214,11 @@ reviews: # FileAssert-Utilities-TemporaryDirectory Review (one per unit) - id: FileAssert-Utilities-TemporaryDirectory title: Review that FileAssert Utilities TemporaryDirectory Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/utilities.md" + - "docs/reqstream/file-assert/utilities.yaml" paths: - "docs/reqstream/file-assert/utilities/temporary-directory.yaml" # requirements - "docs/design/file-assert/utilities/temporary-directory.md" # design @@ -169,6 +229,11 @@ reviews: # FileAssert-Modeling-FileAssertRule Review (one per unit) - id: FileAssert-Modeling-FileAssertRule title: Review that FileAssert Modeling FileAssertRule Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-rule.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-rule.md" # design @@ -179,6 +244,11 @@ reviews: # FileAssert-Modeling-FileAssertFile Review (one per unit) - id: FileAssert-Modeling-FileAssertFile title: Review that FileAssert Modeling FileAssertFile Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-file.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-file.md" # design @@ -189,6 +259,11 @@ reviews: # FileAssert-Modeling-FileAssertTest Review (one per unit) - id: FileAssert-Modeling-FileAssertTest title: Review that FileAssert Modeling FileAssertTest Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-test.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-test.md" # design @@ -199,6 +274,11 @@ reviews: # FileAssert-Configuration-FileAssertConfig Review (one per unit) - id: FileAssert-Configuration-FileAssertConfig title: Review that FileAssert Configuration FileAssertConfig Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/configuration.md" + - "docs/reqstream/file-assert/configuration.yaml" paths: - "docs/reqstream/file-assert/configuration/file-assert-config.yaml" # requirements - "docs/design/file-assert/configuration/file-assert-config.md" # design @@ -209,6 +289,11 @@ reviews: # FileAssert-Configuration-FileAssertData Review (one per unit) - id: FileAssert-Configuration-FileAssertData title: Review that FileAssert Configuration FileAssertData Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/configuration.md" + - "docs/reqstream/file-assert/configuration.yaml" paths: - "docs/reqstream/file-assert/configuration/file-assert-data.yaml" # requirements - "docs/design/file-assert/configuration/file-assert-data.md" # design @@ -219,6 +304,11 @@ reviews: # FileAssert-Modeling-FileAssertTextAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertTextAssert title: Review that FileAssert Modeling FileAssertTextAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-text-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-text-assert.md" # design @@ -229,6 +319,11 @@ reviews: # FileAssert-Modeling-FileAssertPdfAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertPdfAssert title: Review that FileAssert Modeling FileAssertPdfAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-pdf-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-pdf-assert.md" # design @@ -239,6 +334,11 @@ reviews: # FileAssert-Modeling-FileAssertXmlAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertXmlAssert title: Review that FileAssert Modeling FileAssertXmlAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-xml-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-xml-assert.md" # design @@ -249,6 +349,11 @@ reviews: # FileAssert-Modeling-FileAssertHtmlAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertHtmlAssert title: Review that FileAssert Modeling FileAssertHtmlAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-html-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-html-assert.md" # design @@ -259,6 +364,11 @@ reviews: # FileAssert-Modeling-FileAssertYamlAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertYamlAssert title: Review that FileAssert Modeling FileAssertYamlAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-yaml-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-yaml-assert.md" # design @@ -269,6 +379,11 @@ reviews: # FileAssert-Modeling-FileAssertJsonAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertJsonAssert title: Review that FileAssert Modeling FileAssertJsonAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-json-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-json-assert.md" # design @@ -279,6 +394,11 @@ reviews: # FileAssert-Modeling-FileAssertZipAssert Review (one per unit) - id: FileAssert-Modeling-FileAssertZipAssert title: Review that FileAssert Modeling FileAssertZipAssert Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/modeling.md" + - "docs/reqstream/file-assert/modeling.yaml" paths: - "docs/reqstream/file-assert/modeling/file-assert-zip-assert.yaml" # requirements - "docs/design/file-assert/modeling/file-assert-zip-assert.md" # design @@ -289,6 +409,11 @@ reviews: # FileAssert-Cli-IContext Review (one per unit) - id: FileAssert-Cli-IContext title: Review that FileAssert Cli IContext Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/cli.md" + - "docs/reqstream/file-assert/cli.yaml" paths: - "docs/reqstream/file-assert/cli/i-context.yaml" # requirements - "docs/design/file-assert/cli/i-context.md" # design @@ -300,6 +425,11 @@ reviews: # FileAssert-Utilities-IFileContainer Review (one per unit) - id: FileAssert-Utilities-IFileContainer title: Review that FileAssert Utilities IFileContainer Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/utilities.md" + - "docs/reqstream/file-assert/utilities.yaml" paths: - "docs/reqstream/file-assert/utilities/i-file-container.yaml" # requirements - "docs/design/file-assert/utilities/i-file-container.md" # design @@ -310,6 +440,11 @@ reviews: # FileAssert-Utilities-DirectoryFileContainer Review (one per unit) - id: FileAssert-Utilities-DirectoryFileContainer title: Review that FileAssert Utilities DirectoryFileContainer Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/utilities.md" + - "docs/reqstream/file-assert/utilities.yaml" paths: - "docs/reqstream/file-assert/utilities/directory-file-container.yaml" # requirements - "docs/design/file-assert/utilities/directory-file-container.md" # design @@ -320,6 +455,11 @@ reviews: # FileAssert-Utilities-ZipFileContainer Review (one per unit) - id: FileAssert-Utilities-ZipFileContainer title: Review that FileAssert Utilities ZipFileContainer Implementation is Correct + context: + - "docs/design/file-assert.md" + - "docs/reqstream/file-assert.yaml" + - "docs/design/file-assert/utilities.md" + - "docs/reqstream/file-assert/utilities.yaml" paths: - "docs/reqstream/file-assert/utilities/zip-file-container.yaml" # requirements - "docs/design/file-assert/utilities/zip-file-container.md" # design @@ -327,113 +467,121 @@ reviews: - "src/**/Utilities/ZipFileContainer.cs" # implementation - "test/**/Utilities/IFileContainerTests.cs" # unit tests - # FileAssert-OTS-BuildMark Review - - id: FileAssert-OTS-BuildMark - title: Review FileAssert OTS BuildMark Requirements and Verification + # OTS-BuildMark Review (one per OTS item) + - id: OTS-BuildMark + title: Review that BuildMark Provides Required Functionality paths: - "docs/reqstream/ots/buildmark.yaml" # OTS requirements - "docs/design/ots/buildmark.md" # OTS design - "docs/verification/ots/buildmark.md" # OTS verification - # FileAssert-Shared-FileAssert Review - - id: FileAssert-Shared-FileAssert - title: Review FileAssert Shared Package FileAssert Requirements and Verification + # Shared-FileAssert Review (one per Shared Package) + - id: Shared-FileAssert + title: Review that FileAssert Provides Required Features paths: - "docs/reqstream/shared/fileassert.yaml" # Shared Package requirements - "docs/design/shared/fileassert.md" # Shared Package design - "docs/verification/shared/fileassert.md" # Shared Package verification - # FileAssert-OTS-Pandoc Review - - id: FileAssert-OTS-Pandoc - title: Review FileAssert OTS Pandoc Requirements and Verification + # OTS-Pandoc Review (one per OTS item) + - id: OTS-Pandoc + title: Review that Pandoc Provides Required Functionality paths: - "docs/reqstream/ots/pandoc.yaml" # OTS requirements - "docs/design/ots/pandoc.md" # OTS design - "docs/verification/ots/pandoc.md" # OTS verification - # FileAssert-OTS-ReqStream Review - - id: FileAssert-OTS-ReqStream - title: Review FileAssert OTS ReqStream Requirements and Verification + # OTS-ReqStream Review (one per OTS item) + - id: OTS-ReqStream + title: Review that ReqStream Provides Required Functionality paths: - "docs/reqstream/ots/reqstream.yaml" # OTS requirements - "docs/design/ots/reqstream.md" # OTS design - "docs/verification/ots/reqstream.md" # OTS verification - # FileAssert-OTS-ReviewMark Review - - id: FileAssert-OTS-ReviewMark - title: Review FileAssert OTS ReviewMark Requirements and Verification + # OTS-ReviewMark Review (one per OTS item) + - id: OTS-ReviewMark + title: Review that ReviewMark Provides Required Functionality paths: - "docs/reqstream/ots/reviewmark.yaml" # OTS requirements - "docs/design/ots/reviewmark.md" # OTS design - "docs/verification/ots/reviewmark.md" # OTS verification - # FileAssert-OTS-SarifMark Review - - id: FileAssert-OTS-SarifMark - title: Review FileAssert OTS SarifMark Requirements and Verification + # OTS-SarifMark Review (one per OTS item) + - id: OTS-SarifMark + title: Review that SarifMark Provides Required Functionality paths: - "docs/reqstream/ots/sarifmark.yaml" # OTS requirements - "docs/design/ots/sarifmark.md" # OTS design - "docs/verification/ots/sarifmark.md" # OTS verification - # FileAssert-OTS-SonarMark Review - - id: FileAssert-OTS-SonarMark - title: Review FileAssert OTS SonarMark Requirements and Verification + # OTS-SonarMark Review (one per OTS item) + - id: OTS-SonarMark + title: Review that SonarMark Provides Required Functionality paths: - "docs/reqstream/ots/sonarmark.yaml" # OTS requirements - "docs/design/ots/sonarmark.md" # OTS design - "docs/verification/ots/sonarmark.md" # OTS verification - # FileAssert-OTS-VersionMark Review - - id: FileAssert-OTS-VersionMark - title: Review FileAssert OTS VersionMark Requirements and Verification + # OTS-SysML2Tools Review (one per OTS item) + - id: OTS-SysML2Tools + title: Review that SysML2Tools Provides Required Functionality + paths: + - "docs/reqstream/ots/sysml2tools.yaml" # OTS requirements + - "docs/design/ots/sysml2tools.md" # OTS design + - "docs/verification/ots/sysml2tools.md" # OTS verification + + # OTS-VersionMark Review (one per OTS item) + - id: OTS-VersionMark + title: Review that VersionMark Provides Required Functionality paths: - "docs/reqstream/ots/versionmark.yaml" # OTS requirements - "docs/design/ots/versionmark.md" # OTS design - "docs/verification/ots/versionmark.md" # OTS verification - # FileAssert-OTS-WeasyPrint Review - - id: FileAssert-OTS-WeasyPrint - title: Review FileAssert OTS WeasyPrint Requirements and Verification + # OTS-WeasyPrint Review (one per OTS item) + - id: OTS-WeasyPrint + title: Review that WeasyPrint Provides Required Functionality paths: - "docs/reqstream/ots/weasyprint.yaml" # OTS requirements - "docs/design/ots/weasyprint.md" # OTS design - "docs/verification/ots/weasyprint.md" # OTS verification - # FileAssert-OTS-xUnit Review - - id: FileAssert-OTS-xUnit - title: Review FileAssert OTS xUnit Requirements and Verification + # OTS-xUnit Review (one per OTS item) + - id: OTS-xUnit + title: Review that xUnit Provides Required Functionality paths: - "docs/reqstream/ots/xunit.yaml" # OTS requirements - "docs/design/ots/xunit.md" # OTS design - "docs/verification/ots/xunit.md" # OTS verification - # FileAssert-OTS-YamlDotNet Review - - id: FileAssert-OTS-YamlDotNet - title: Review FileAssert OTS YamlDotNet Requirements and Verification + # OTS-YamlDotNet Review (one per OTS item) + - id: OTS-YamlDotNet + title: Review that YamlDotNet Provides Required Functionality paths: - "docs/reqstream/ots/yamldotnet.yaml" # OTS requirements - "docs/design/ots/yamldotnet.md" # OTS design - "docs/verification/ots/yamldotnet.md" # OTS verification - # FileAssert-OTS-PdfPig Review - - id: FileAssert-OTS-PdfPig - title: Review FileAssert OTS PdfPig Requirements and Verification + # OTS-PdfPig Review (one per OTS item) + - id: OTS-PdfPig + title: Review that PdfPig Provides Required Functionality paths: - "docs/reqstream/ots/pdfpig.yaml" # OTS requirements - "docs/design/ots/pdfpig.md" # OTS design - "docs/verification/ots/pdfpig.md" # OTS verification - # FileAssert-OTS-HtmlAgilityPack Review - - id: FileAssert-OTS-HtmlAgilityPack - title: Review FileAssert OTS HtmlAgilityPack Requirements and Verification + # OTS-HtmlAgilityPack Review (one per OTS item) + - id: OTS-HtmlAgilityPack + title: Review that HtmlAgilityPack Provides Required Functionality paths: - "docs/reqstream/ots/htmlagilitypack.yaml" # OTS requirements - "docs/design/ots/htmlagilitypack.md" # OTS design - "docs/verification/ots/htmlagilitypack.md" # OTS verification - # FileAssert-OTS-FileSystemGlobbing Review - - id: FileAssert-OTS-FileSystemGlobbing - title: Review FileAssert OTS FileSystemGlobbing Requirements and Verification + # OTS-FileSystemGlobbing Review (one per OTS item) + - id: OTS-FileSystemGlobbing + title: Review that FileSystemGlobbing Provides Required Functionality paths: - "docs/reqstream/ots/filesystemglobbing.yaml" # OTS requirements - "docs/design/ots/filesystemglobbing.md" # OTS design 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 1f54a8b..bfcc580 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,6 +19,7 @@ │ ├── requirements_doc/ │ ├── requirements_report/ │ ├── reqstream/ +│ ├── sysml2/ │ ├── user_guide/ │ └── verification/ ├── src/ @@ -42,10 +43,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 @@ -60,6 +63,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. @@ -76,6 +80,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. @@ -130,7 +135,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 d698f6b..e069943 100644 --- a/docs/design/definition.yaml +++ b/docs/design/definition.yaml @@ -9,6 +9,7 @@ input-files: - docs/design/file-assert/program.md - docs/design/file-assert/cli.md - docs/design/file-assert/cli/context.md + - docs/design/file-assert/cli/i-context.md - docs/design/file-assert/configuration.md - docs/design/file-assert/configuration/file-assert-config.md - docs/design/file-assert/configuration/file-assert-data.md @@ -22,11 +23,15 @@ input-files: - docs/design/file-assert/modeling/file-assert-html-assert.md - docs/design/file-assert/modeling/file-assert-yaml-assert.md - docs/design/file-assert/modeling/file-assert-json-assert.md + - docs/design/file-assert/modeling/file-assert-zip-assert.md - docs/design/file-assert/utilities.md - docs/design/file-assert/utilities/path-helpers.md + - docs/design/file-assert/utilities/temporary-directory.md + - docs/design/file-assert/utilities/i-file-container.md + - docs/design/file-assert/utilities/directory-file-container.md + - docs/design/file-assert/utilities/zip-file-container.md - docs/design/file-assert/selftest.md - docs/design/file-assert/selftest/validation.md - - docs/design/file-assert/ots-dependencies.md - docs/design/ots.md - docs/design/ots/buildmark.md - docs/design/ots/pandoc.md @@ -37,6 +42,11 @@ input-files: - docs/design/ots/versionmark.md - docs/design/ots/weasyprint.md - docs/design/ots/xunit.md + - docs/design/ots/yamldotnet.md + - docs/design/ots/pdfpig.md + - docs/design/ots/htmlagilitypack.md + - docs/design/ots/filesystemglobbing.md + - docs/design/ots/sysml2tools.md - docs/design/shared.md - docs/design/shared/fileassert.md template: template.html diff --git a/docs/design/file-assert.md b/docs/design/file-assert.md index d3dd06d..bb9eed5 100644 --- a/docs/design/file-assert.md +++ b/docs/design/file-assert.md @@ -1,5 +1,7 @@ # FileAssert System Design +![FileAssert System Structure](FileAssertView.svg) + ## Overview FileAssert is a .NET command-line tool for asserting file properties using YAML-defined test diff --git a/docs/design/file-assert/cli.md b/docs/design/file-assert/cli.md index c1e23fd..6cf1946 100644 --- a/docs/design/file-assert/cli.md +++ b/docs/design/file-assert/cli.md @@ -1,5 +1,7 @@ ## Cli Subsystem Design +![Cli Structure](CliView.svg) + ### Overview The Cli subsystem is responsible for translating the raw command-line argument array into a diff --git a/docs/design/file-assert/cli/context.md b/docs/design/file-assert/cli/context.md index 31448fd..36f180d 100644 --- a/docs/design/file-assert/cli/context.md +++ b/docs/design/file-assert/cli/context.md @@ -1,5 +1,7 @@ ### Context Design +![Cli Structure](CliView.svg) + #### Overview `Context` is the command-line argument parser and I/O owner for FileAssert. It translates the diff --git a/docs/design/file-assert/cli/i-context.md b/docs/design/file-assert/cli/i-context.md index 6162fba..9ef4dea 100644 --- a/docs/design/file-assert/cli/i-context.md +++ b/docs/design/file-assert/cli/i-context.md @@ -1,5 +1,7 @@ ### IContext Design +![Cli Structure](CliView.svg) + #### Overview `IContext` is the output contract interface for reporting assertion results and errors within diff --git a/docs/design/file-assert/configuration.md b/docs/design/file-assert/configuration.md index 651d208..b793356 100644 --- a/docs/design/file-assert/configuration.md +++ b/docs/design/file-assert/configuration.md @@ -1,5 +1,7 @@ ## Configuration Subsystem Design +![Configuration Structure](ConfigurationView.svg) + ### Overview The Configuration subsystem is responsible for reading the YAML test-suite configuration file diff --git a/docs/design/file-assert/configuration/file-assert-config.md b/docs/design/file-assert/configuration/file-assert-config.md index b1f089d..63026e4 100644 --- a/docs/design/file-assert/configuration/file-assert-config.md +++ b/docs/design/file-assert/configuration/file-assert-config.md @@ -1,5 +1,7 @@ ### FileAssertConfig Design +![Configuration Structure](ConfigurationView.svg) + #### Overview The `FileAssertConfig` class is the top-level entry point for the FileAssert tool's diff --git a/docs/design/file-assert/configuration/file-assert-data.md b/docs/design/file-assert/configuration/file-assert-data.md index eb7a737..dc2541f 100644 --- a/docs/design/file-assert/configuration/file-assert-data.md +++ b/docs/design/file-assert/configuration/file-assert-data.md @@ -1,5 +1,7 @@ ### FileAssertData Design +![Configuration Structure](ConfigurationView.svg) + #### Overview `FileAssertData` is the set of YAML data transfer objects (DTOs) used by YamlDotNet to diff --git a/docs/design/file-assert/modeling.md b/docs/design/file-assert/modeling.md index d1d65a5..aa253cc 100644 --- a/docs/design/file-assert/modeling.md +++ b/docs/design/file-assert/modeling.md @@ -1,5 +1,7 @@ ## Modeling Subsystem Design +![Modeling Structure](ModelingView.svg) + ### Overview The Modeling subsystem contains the domain objects that represent a FileAssert test suite at diff --git a/docs/design/file-assert/modeling/file-assert-file.md b/docs/design/file-assert/modeling/file-assert-file.md index 89ad875..aa98b8b 100644 --- a/docs/design/file-assert/modeling/file-assert-file.md +++ b/docs/design/file-assert/modeling/file-assert-file.md @@ -1,5 +1,7 @@ ### FileAssertFile Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertFile` class locates files on disk using a glob pattern, enforces diff --git a/docs/design/file-assert/modeling/file-assert-html-assert.md b/docs/design/file-assert/modeling/file-assert-html-assert.md index 9e9216c..e759043 100644 --- a/docs/design/file-assert/modeling/file-assert-html-assert.md +++ b/docs/design/file-assert/modeling/file-assert-html-assert.md @@ -1,5 +1,7 @@ ### FileAssertHtmlAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertHtmlAssert` class attempts to parse a matched file as an HTML document using diff --git a/docs/design/file-assert/modeling/file-assert-json-assert.md b/docs/design/file-assert/modeling/file-assert-json-assert.md index 18910af..9e7a561 100644 --- a/docs/design/file-assert/modeling/file-assert-json-assert.md +++ b/docs/design/file-assert/modeling/file-assert-json-assert.md @@ -1,5 +1,7 @@ ### FileAssertJsonAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertJsonAssert` class attempts to parse a matched file as a JSON document using diff --git a/docs/design/file-assert/modeling/file-assert-pdf-assert.md b/docs/design/file-assert/modeling/file-assert-pdf-assert.md index a20a19a..e0bb183 100644 --- a/docs/design/file-assert/modeling/file-assert-pdf-assert.md +++ b/docs/design/file-assert/modeling/file-assert-pdf-assert.md @@ -1,5 +1,7 @@ ### FileAssertPdfAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertPdfAssert` class attempts to parse a matched file as a PDF document using diff --git a/docs/design/file-assert/modeling/file-assert-rule.md b/docs/design/file-assert/modeling/file-assert-rule.md index 019a631..9e44f85 100644 --- a/docs/design/file-assert/modeling/file-assert-rule.md +++ b/docs/design/file-assert/modeling/file-assert-rule.md @@ -1,5 +1,7 @@ ### FileAssertRule Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertRule` class hierarchy provides the content validation rules used by diff --git a/docs/design/file-assert/modeling/file-assert-test.md b/docs/design/file-assert/modeling/file-assert-test.md index e30550e..b1bc475 100644 --- a/docs/design/file-assert/modeling/file-assert-test.md +++ b/docs/design/file-assert/modeling/file-assert-test.md @@ -1,5 +1,7 @@ ### FileAssertTest Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertTest` class represents a named, tagged test within a FileAssert diff --git a/docs/design/file-assert/modeling/file-assert-text-assert.md b/docs/design/file-assert/modeling/file-assert-text-assert.md index 402500b..bf651b7 100644 --- a/docs/design/file-assert/modeling/file-assert-text-assert.md +++ b/docs/design/file-assert/modeling/file-assert-text-assert.md @@ -1,5 +1,7 @@ ### FileAssertTextAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertTextAssert` class applies a collection of `FileAssertRule` instances to the diff --git a/docs/design/file-assert/modeling/file-assert-xml-assert.md b/docs/design/file-assert/modeling/file-assert-xml-assert.md index 10d793b..1d6e8f7 100644 --- a/docs/design/file-assert/modeling/file-assert-xml-assert.md +++ b/docs/design/file-assert/modeling/file-assert-xml-assert.md @@ -1,5 +1,7 @@ ### FileAssertXmlAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertXmlAssert` class attempts to parse a matched file as an XML document using diff --git a/docs/design/file-assert/modeling/file-assert-yaml-assert.md b/docs/design/file-assert/modeling/file-assert-yaml-assert.md index 78f76f9..90cbf74 100644 --- a/docs/design/file-assert/modeling/file-assert-yaml-assert.md +++ b/docs/design/file-assert/modeling/file-assert-yaml-assert.md @@ -1,5 +1,7 @@ ### FileAssertYamlAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertYamlAssert` class attempts to parse a matched file as a YAML document using diff --git a/docs/design/file-assert/modeling/file-assert-zip-assert.md b/docs/design/file-assert/modeling/file-assert-zip-assert.md index fa7caff..ee011d3 100644 --- a/docs/design/file-assert/modeling/file-assert-zip-assert.md +++ b/docs/design/file-assert/modeling/file-assert-zip-assert.md @@ -1,5 +1,7 @@ ### FileAssertZipAssert Design +![Modeling Structure](ModelingView.svg) + #### Overview The `FileAssertZipAssert` class validates the contents of a zip archive by applying the full diff --git a/docs/design/file-assert/ots-dependencies.md b/docs/design/file-assert/ots-dependencies.md deleted file mode 100644 index 2509b9b..0000000 --- a/docs/design/file-assert/ots-dependencies.md +++ /dev/null @@ -1,94 +0,0 @@ -## OTS Dependencies Design - -### Overview - -FileAssert relies on several off-the-shelf (OTS) tools and libraries that are integrated -into the build, quality, and traceability pipeline. This document describes each OTS -dependency, its purpose, and how its correct operation is verified. - -### OTS Tools - -#### ReqStream - -| Attribute | Value | -| :----------- | :----------------------------------------------------------------- | -| Purpose | Requirements traceability enforcement | -| Role | Verifies every requirement is covered by at least one passing test | -| Verification | Build fails if any requirement has no passing test evidence | - -ReqStream reads requirements from `docs/reqstream/**/*.yaml` and cross-references them -against TRX test result files. It enforces that every requirement listed is traceable to a -passing test, providing continuous compliance evidence for formal reviews. - -#### ReviewMark - -| Attribute | Value | -| :----------- | :------------------------------------------------------------------ | -| Purpose | File review status enforcement | -| Role | Ensures all source files have been formally reviewed | -| Verification | Build fails if any file in a review-set lacks a valid review record | - -ReviewMark reads review records from the repository and validates that every file -included in a review-set has a recorded review. This provides a continuous audit trail -for compliance with formal code review requirements. - -#### SonarMark - -| Attribute | Value | -| :----------- | :--------------------------------------------------------- | -| Purpose | SonarCloud quality gate reporting | -| Role | Reports the SonarCloud quality gate status in build output | -| Verification | Build fails if the SonarCloud quality gate is not passing | - -SonarMark queries the SonarCloud API and surfaces the quality gate result as a build -step. Failures in code quality metrics (coverage, duplications, maintainability) are -caught before merging. - -#### SarifMark - -| Attribute | Value | -| :----------- | :--------------------------------------------------------------- | -| Purpose | CodeQL SARIF report generation | -| Role | Converts CodeQL SARIF output into a human-readable build summary | -| Verification | Build fails if SARIF results contain open security alerts | - -SarifMark processes the SARIF files produced by CodeQL and generates a Markdown -summary report. Any open high-severity alerts cause the build to fail, enforcing -zero-tolerance for unaddressed security findings. - -#### BuildMark - -| Attribute | Value | -| :----------- | :-------------------------------------------------------------------------- | -| Purpose | Tool version documentation | -| Role | Captures and records the versions of all build tools used in a pipeline run | -| Verification | Version records are included in the build artifact for audit purposes | - -BuildMark interrogates installed tool versions and writes a version manifest to the -build output. This ensures that the exact tool versions used to produce a release are -permanently recorded and reproducible. - -#### VersionMark - -| Attribute | Value | -| :----------- | :------------------------------------------------------------------ | -| Purpose | Version tracking | -| Role | Injects the current version into build output and assembly metadata | -| Verification | The published NuGet package version matches the repository tag | - -VersionMark reads the version from a central configuration file and propagates it to -all artifacts produced by the build. This eliminates manual version updates and ensures -consistency between the NuGet package version, assembly version, and release tag. - -#### xUnit - -| Attribute | Value | -| :----------- | :----------------------------------------------------------------------------------- | -| Purpose | Unit test framework | -| Role | Provides the test runner, assertion library, and TRX result output used by all tests | -| Verification | All tests must pass; TRX files are consumed by ReqStream for traceability | - -xUnit (version 3) is the unit test framework for all C# tests in this repository. -It provides `[Fact]`, `[Collection]`, and the assertion methods used throughout -the test suite. TRX output format is enabled so that ReqStream can parse test results -and verify requirements coverage. diff --git a/docs/design/file-assert/program.md b/docs/design/file-assert/program.md index 6b0e48b..70ef749 100644 --- a/docs/design/file-assert/program.md +++ b/docs/design/file-assert/program.md @@ -1,5 +1,7 @@ ## Program Design +![FileAssert System Structure](FileAssertView.svg) + ### Purpose `Program` is the static entry-point class for the FileAssert tool. It constructs the execution diff --git a/docs/design/file-assert/selftest.md b/docs/design/file-assert/selftest.md index 4ea0f10..85273b2 100644 --- a/docs/design/file-assert/selftest.md +++ b/docs/design/file-assert/selftest.md @@ -1,5 +1,7 @@ ## SelfTest Subsystem Design +![SelfTest Structure](SelfTestView.svg) + ### Overview The SelfTest subsystem provides built-in self-validation functionality that verifies the core diff --git a/docs/design/file-assert/selftest/validation.md b/docs/design/file-assert/selftest/validation.md index 88eac16..0827b10 100644 --- a/docs/design/file-assert/selftest/validation.md +++ b/docs/design/file-assert/selftest/validation.md @@ -1,5 +1,7 @@ ### Validation Design +![SelfTest Structure](SelfTestView.svg) + #### Overview `Validation` is a static class that implements the self-validation test runner for FileAssert. diff --git a/docs/design/file-assert/utilities.md b/docs/design/file-assert/utilities.md index e36f5ed..2f77747 100644 --- a/docs/design/file-assert/utilities.md +++ b/docs/design/file-assert/utilities.md @@ -1,5 +1,7 @@ ## Utilities Subsystem Design +![Utilities Structure](UtilitiesView.svg) + ### Overview The Utilities subsystem provides shared helper functionality used by other subsystems. It diff --git a/docs/design/file-assert/utilities/directory-file-container.md b/docs/design/file-assert/utilities/directory-file-container.md index 80084e8..0a3c58a 100644 --- a/docs/design/file-assert/utilities/directory-file-container.md +++ b/docs/design/file-assert/utilities/directory-file-container.md @@ -1,5 +1,7 @@ ### DirectoryFileContainer Design +![Utilities Structure](UtilitiesView.svg) + #### Purpose `DirectoryFileContainer` is the filesystem implementation of `IFileContainer`. It exposes a local diff --git a/docs/design/file-assert/utilities/i-file-container.md b/docs/design/file-assert/utilities/i-file-container.md index 8b499a6..266bf2b 100644 --- a/docs/design/file-assert/utilities/i-file-container.md +++ b/docs/design/file-assert/utilities/i-file-container.md @@ -1,5 +1,7 @@ ### IFileContainer Design +![Utilities Structure](UtilitiesView.svg) + #### Purpose `IFileContainer` is the uniform file-access abstraction used by all asserters in FileAssert. diff --git a/docs/design/file-assert/utilities/path-helpers.md b/docs/design/file-assert/utilities/path-helpers.md index d570d65..a07789c 100644 --- a/docs/design/file-assert/utilities/path-helpers.md +++ b/docs/design/file-assert/utilities/path-helpers.md @@ -1,5 +1,7 @@ ### PathHelpers Design +![Utilities Structure](UtilitiesView.svg) + #### Overview `PathHelpers` is a static utility class that provides a safe path-combination method. It diff --git a/docs/design/file-assert/utilities/temporary-directory.md b/docs/design/file-assert/utilities/temporary-directory.md index f23f65f..9114cb0 100644 --- a/docs/design/file-assert/utilities/temporary-directory.md +++ b/docs/design/file-assert/utilities/temporary-directory.md @@ -1,5 +1,7 @@ ### TemporaryDirectory Design +![Utilities Structure](UtilitiesView.svg) + #### Overview `TemporaryDirectory` is a disposable utility class that creates a uniquely-named temporary diff --git a/docs/design/file-assert/utilities/zip-file-container.md b/docs/design/file-assert/utilities/zip-file-container.md index bf5d90e..cab222b 100644 --- a/docs/design/file-assert/utilities/zip-file-container.md +++ b/docs/design/file-assert/utilities/zip-file-container.md @@ -1,5 +1,7 @@ ### ZipFileContainer Design +![Utilities Structure](UtilitiesView.svg) + #### Purpose `ZipFileContainer` is the zip archive implementation of `IFileContainer`. It wraps a `ZipArchive` diff --git a/docs/design/introduction.md b/docs/design/introduction.md index ad70b0c..806e8af 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -1,126 +1,72 @@ # Introduction -This document provides the detailed design for the FileAssert tool, a .NET command-line application -for asserting file properties using YAML-defined test suites. +This document provides the detailed design for FileAssert — a .NET command-line application for +asserting file properties using YAML-defined test suites. It covers local software items (systems, +subsystems, and units), the OTS software items they consume, and the FileAssert shared package +consumed by this project's own build pipeline. ## Purpose -The purpose of this document is to describe the internal design of each software unit that comprises -FileAssert. 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. +The purpose of this document is to define the design for each software item in FileAssert — full +architectural and detailed design for local items (systems, subsystems, and units), and integration +and usage design for OTS software items and the shared package. 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 units: - -- **Program** — entry point and execution orchestrator (`Program.cs`) -- **IContext** — output contract interface for reporting assertion results (`IContext.cs`) -- **Context** — command-line argument parser and I/O owner (`Context.cs`) -- **FileAssertConfig** — top-level configuration loader and test runner (`FileAssertConfig.cs`) -- **FileAssertData** — YAML data transfer objects for configuration deserialization (`FileAssertData.cs`) -- **FileAssertTest** — named test with file assertions and tag filtering (`FileAssertTest.cs`) -- **FileAssertFile** — glob pattern matcher with count constraints and content rules (`FileAssertFile.cs`) -- **FileAssertRule** — abstract content validation rule hierarchy (`FileAssertRule.cs`) -- **FileAssertTextAssert** — text content assertions (`FileAssertTextAssert.cs`) -- **FileAssertPdfAssert** — PDF document assertions (`FileAssertPdfAssert.cs`) -- **FileAssertXmlAssert** — XML document assertions (`FileAssertXmlAssert.cs`) -- **FileAssertHtmlAssert** — HTML document assertions (`FileAssertHtmlAssert.cs`) -- **FileAssertYamlAssert** — YAML document assertions (`FileAssertYamlAssert.cs`) -- **FileAssertJsonAssert** — JSON document assertions (`FileAssertJsonAssert.cs`) -- **FileAssertZipAssert** — zip archive entry assertions (`FileAssertZipAssert.cs`) -- **IFileContainer** — uniform file-access abstraction over directories and zip archives (`IFileContainer.cs`) -- **DirectoryFileContainer** — filesystem implementation of IFileContainer (`DirectoryFileContainer.cs`) -- **ZipFileContainer** — zip archive implementation of IFileContainer (`ZipFileContainer.cs`) -- **PathHelpers** — safe path-combination utility (`PathHelpers.cs`) -- **TemporaryDirectory** — disposable temporary directory utility (`TemporaryDirectory.cs`) -- **Validation** — self-validation test runner (`Validation.cs`) - -The following cross-cutting design topics are also covered: - -- **OTS Dependencies** — off-the-shelf tool dependencies and their roles (`file-assert/ots-dependencies.md`) +This document covers the following software items: + +Local items: + +- **FileAssert**: system, subsystem, and unit design for all local components. + +OTS items: + +- **BuildMark**: integration and usage design. +- **FileSystemGlobbing**: integration and usage design. +- **HtmlAgilityPack**: integration and usage design. +- **Pandoc**: integration and usage design. +- **PdfPig**: 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. +- **YamlDotNet**: integration and usage design. + +Shared packages: + +- **FileAssert**: integration and usage design. The following topics are out of scope: -- External library internals (YamlDotNet, Microsoft.Extensions.FileSystemGlobbing, - DemaConsulting.TestResults) +- External library internals - Build pipeline configuration - Deployment and packaging -- Test projects are out of scope. +- Test projects ## Software Structure -The following tree shows how the FileAssert software items are organized across the system, -subsystem, and unit levels: - -```text -FileAssert (System) -├── Program (Unit) -├── Cli (Subsystem) -│ ├── IContext (Unit) -│ └── Context (Unit) -├── Configuration (Subsystem) -│ ├── FileAssertConfig (Unit) -│ └── FileAssertData (Unit) -├── Modeling (Subsystem) -│ ├── FileAssertTest (Unit) -│ ├── FileAssertFile (Unit) -│ ├── FileAssertRule (Unit) -│ ├── FileAssertTextAssert (Unit) -│ ├── FileAssertPdfAssert (Unit) -│ ├── FileAssertXmlAssert (Unit) -│ ├── FileAssertHtmlAssert (Unit) -│ ├── FileAssertYamlAssert (Unit) -│ ├── FileAssertJsonAssert (Unit) -│ └── FileAssertZipAssert (Unit) -├── Utilities (Subsystem) -│ ├── IFileContainer (Unit) -│ ├── DirectoryFileContainer (Unit) -│ ├── ZipFileContainer (Unit) -│ ├── PathHelpers (Unit) -│ └── TemporaryDirectory (Unit) -└── SelfTest (Subsystem) - └── Validation (Unit) -``` - -Each unit is described in detail in its own chapter within this document. +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. + +![Software Structure](SoftwareStructureView.svg) ## 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.FileAssert/ -├── Program.cs — entry point and execution orchestrator -├── Cli/ -│ ├── IContext.cs — output contract interface for asserters and scoping -│ └── Context.cs — command-line argument parser and I/O owner -├── Configuration/ -│ ├── FileAssertConfig.cs — top-level configuration loader and test runner -│ └── FileAssertData.cs — YAML data transfer objects -├── Modeling/ -│ ├── FileAssertTest.cs — named test with file assertions and tag filtering -│ ├── FileAssertFile.cs — glob pattern matcher with count constraints and rules -│ ├── FileAssertRule.cs — abstract content validation rule hierarchy -│ ├── FileAssertTextAssert.cs — text content assertions -│ ├── FileAssertPdfAssert.cs — PDF document assertions (PdfPig) -│ ├── FileAssertXmlAssert.cs — XML document assertions (System.Xml.Linq/XPath) -│ ├── FileAssertHtmlAssert.cs — HTML document assertions (HtmlAgilityPack) -│ ├── FileAssertYamlAssert.cs — YAML document assertions (YamlDotNet) -│ ├── FileAssertJsonAssert.cs — JSON document assertions (System.Text.Json) -│ └── FileAssertZipAssert.cs — zip archive entry assertions (System.IO.Compression) -├── Utilities/ -│ ├── IFileContainer.cs — uniform file-access abstraction interface -│ ├── DirectoryFileContainer.cs — filesystem implementation of IFileContainer -│ ├── ZipFileContainer.cs — zip archive implementation of IFileContainer -│ ├── PathHelpers.cs — safe path-combination utility -│ └── TemporaryDirectory.cs — disposable temporary directory utility -└── SelfTest/ - └── Validation.cs — self-validation test runner -``` - -The test project mirrors the same layout under `test/DemaConsulting.FileAssert.Tests/`. +- **src/** - source files and projects + - **DemaConsulting.FileAssert/** - FileAssert system source + - **Cli/** - Cli subsystem + - **Configuration/** - Configuration subsystem + - **Modeling/** - Modeling subsystem + - **Utilities/** - Utilities subsystem + - **SelfTest/** - SelfTest subsystem ## Document Conventions diff --git a/docs/design/ots.md b/docs/design/ots.md index 8fee35d..3102a3f 100644 --- a/docs/design/ots.md +++ b/docs/design/ots.md @@ -1,20 +1,25 @@ # OTS Integration Design -FileAssert relies on ten off-the-shelf (OTS) tools that support CI/CD automation, documentation -generation, and compliance checking. This chapter describes the overall OTS integration strategy -and introduces each tool's role in the pipeline. +FileAssert relies on fourteen off-the-shelf (OTS) tools and libraries that support CI/CD +automation, documentation generation, compliance checking, and core assertion functionality. This +chapter describes the overall OTS integration strategy and introduces each item's role in the +pipeline or product. ## Integration Strategy -The OTS items used by this project fall into three functional groups: +The OTS items used by this project fall into four functional groups: - **Build pipeline tools** — dotnet global tools installed via `.config/dotnet-tools.json` and invoked by the GitHub Actions workflow. Each tool performs a distinct step such as capturing - build metadata, asserting document correctness, or publishing compliance reports. + build metadata, asserting document correctness, validating the architecture model, or publishing + compliance reports. - **Test framework** — the xUnit NuGet packages referenced by the test project and consumed automatically by `dotnet test`. - **Document generation** — Pandoc converts Markdown to HTML and WeasyPrint converts HTML to PDF; both are installed as dotnet global tools via `.config/dotnet-tools.json`. +- **Production code libraries** — NuGet packages referenced directly by the main + `DemaConsulting.FileAssert` project to implement assertion functionality: YamlDotNet, PdfPig, + HtmlAgilityPack, and FileSystemGlobbing. All dotnet global tools are pinned to specific versions in `.config/dotnet-tools.json` and restored with `dotnet tool restore` at the beginning of each CI job. This ensures reproducible @@ -22,17 +27,22 @@ builds and provides an audit record of which tool version produced each release ## OTS Item Summary -| OTS Item | Role | -| :---------- | :--------------------------------------------------------------------------- | -| BuildMark | Generates build-notes documentation from GitHub Actions metadata | -| Pandoc | Converts Markdown source documents to HTML for each document collection | -| ReqStream | Enforces requirements traceability against TRX test-result files | -| ReviewMark | Generates review plan and review report from the review configuration | -| SarifMark | Converts CodeQL SARIF results into a human-readable Markdown report | -| SonarMark | Generates a SonarCloud quality and security metrics report | -| VersionMark | Captures and publishes tool-version information for each CI job | -| WeasyPrint | Converts HTML documents to PDF for release artifact archiving | -| xUnit | Discovers, executes, and reports unit tests; produces TRX output | +| OTS Item | Role | +| :----------------- | :---------------------------------------------------------------------------- | +| BuildMark | Generates build-notes documentation from GitHub Actions metadata | +| Pandoc | Converts Markdown source documents to HTML for each document collection | +| ReqStream | Enforces requirements traceability against TRX test-result files | +| ReviewMark | Generates review plan and review report from the review configuration | +| SarifMark | Converts CodeQL SARIF results into a human-readable Markdown report | +| SonarMark | Generates a SonarCloud quality and security metrics report | +| SysML2Tools | Validates the SysML2 architecture model and renders its views to SVG diagrams | +| VersionMark | Captures and publishes tool-version information for each CI job | +| WeasyPrint | Converts HTML documents to PDF for release artifact archiving | +| xUnit | Discovers, executes, and reports unit tests; produces TRX output | +| YamlDotNet | Parses and deserializes YAML configuration and documents under test | +| PdfPig | Parses PDF documents under test for `pdf:` assertions | +| HtmlAgilityPack | Parses HTML documents under test for `html:` XPath assertions | +| FileSystemGlobbing | Resolves glob patterns against candidate files for `count:`/file matching | > **Note**: FileAssert is not an OTS item for this project. Because this project consumes an > earlier released version of its own package in CI, it is classified as a **Shared Package**. @@ -48,9 +58,14 @@ Detailed design for each OTS item is provided in the following sections of this - See _ReviewMark OTS Design_ for the review plan and report generation tool. - See _SarifMark OTS Design_ for the CodeQL SARIF report tool. - See _SonarMark OTS Design_ for the SonarCloud quality report tool. +- See _SysML2Tools OTS Design_ for the architecture model validation and diagram rendering tool. - See _VersionMark OTS Design_ for the tool-version capture and publish tool. - See _WeasyPrint OTS Design_ for the HTML-to-PDF conversion tool. - See _xUnit OTS Design_ for the unit-testing framework. +- See _YamlDotNet OTS Design_ for the YAML parsing and deserialization library. +- See _PdfPig OTS Design_ for the PDF parsing library. +- See _HtmlAgilityPack OTS Design_ for the HTML parsing library. +- See _FileSystemGlobbing OTS Design_ for the glob pattern-matching library. ## Selection Criteria @@ -83,17 +98,22 @@ manifest outside of the design artifact set. ## General Integration Approach -OTS items in this project fall into two integration categories: +OTS items in this project fall into three integration categories: - **dotnet global tools** (BuildMark, Pandoc, ReqStream, ReviewMark, SarifMark, - SonarMark, VersionMark, WeasyPrint) — installed globally in the CI environment via + SonarMark, SysML2Tools, VersionMark, WeasyPrint) — installed globally in the CI environment via `dotnet tool restore` from `.config/dotnet-tools.json` and invoked as command-line executables within GitHub Actions workflow steps. No wrapper code is written; tools are invoked directly with documented command-line flags. A non-zero exit code from any tool step causes the CI job - to fail immediately, consistent with the GitHub Actions default `fail-fast` behaviour. + to fail immediately, consistent with the GitHub Actions default `fail-fast` behavior. - **NuGet package** (xUnit) — referenced in the test project file and consumed through standard - .NET package restore. No explicit initialisation or configuration code is required beyond the + .NET package restore. No explicit initialization or configuration code is required beyond the test-project target framework declaration. +- **NuGet package libraries** (YamlDotNet, PdfPig, HtmlAgilityPack, FileSystemGlobbing) — + referenced directly by the main `DemaConsulting.FileAssert` project and invoked through their + public API from production code to implement assertion functionality. Each library is wrapped + by a thin FileAssert-owned adapter (the corresponding `FileAssert*Assert`/`IFileContainer` + unit) rather than being exposed directly to configuration authors. Error handling across all tool invocations relies on exit-code contracts documented in each tool's own user guide. No custom error-recovery logic is applied. diff --git a/docs/design/ots/sysml2tools.md b/docs/design/ots/sysml2tools.md new file mode 100644 index 0000000..59bdfe7 --- /dev/null +++ b/docs/design/ots/sysml2tools.md @@ -0,0 +1,52 @@ +## SysML2Tools OTS Design + +DemaConsulting.SysML2Tools is a .NET dotnet global 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 FileAssert'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/reqstream/ots/sysml2tools.yaml b/docs/reqstream/ots/sysml2tools.yaml new file mode 100644 index 0000000..90804e8 --- /dev/null +++ b/docs/reqstream/ots/sysml2tools.yaml @@ -0,0 +1,38 @@ +--- +# SysML2Tools OTS Software Requirements +# +# Requirements for the SysML2Tools architecture modeling tool functionality. + +sections: + - title: OTS Software Requirements + sections: + - title: SysML2Tools Requirements + requirements: + - id: FileAssert-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: FileAssert-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 + + - id: FileAssert-OTS-SysML2Tools + title: SysML2Tools shall validate the SysML2 model and render its declared views to SVG diagrams. + justification: | + Composite requirement covering lint and render behaviors. This is a non-requirement + grouping node; verification evidence is carried by the atomic child requirements, + each of which covers one behavior (lint and render). + tags: [ots] + children: + - FileAssert-OTS-SysML2Tools-Lint + - FileAssert-OTS-SysML2Tools-Render diff --git a/docs/sysml2/model/file-assert.sysml b/docs/sysml2/model/file-assert.sysml new file mode 100644 index 0000000..0436f50 --- /dev/null +++ b/docs/sysml2/model/file-assert.sysml @@ -0,0 +1,33 @@ +package FileAssert { + import OtsDependencies::*; + import SharedDependencies::*; + + doc + /* + * FileAssert is a .NET command-line application for asserting file properties + * using YAML-defined test suites. + */ + + part def FileAssertSystem { + doc /* The FileAssert system as a whole. */ + + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/IntegrationTests.cs */ + comment designRef /* Design: docs/design/file-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert.yaml */ + + part program : Program; + part cli : CliSubsystem; + part configuration : ConfigurationSubsystem; + part modeling : ModelingSubsystem; + part utilities : UtilitiesSubsystem; + part selfTest : SelfTestSubsystem; + + part yamlDotNet : YamlDotNet; + part pdfPig : PdfPig; + part htmlAgilityPack : HtmlAgilityPack; + part fileSystemGlobbing : FileSystemGlobbing; + + part fileAssertSharedPackage : FileAssertSharedPackage; + } +} diff --git a/docs/sysml2/model/file-assert/cli.sysml b/docs/sysml2/model/file-assert/cli.sysml new file mode 100644 index 0000000..fad0514 --- /dev/null +++ b/docs/sysml2/model/file-assert/cli.sysml @@ -0,0 +1,13 @@ +package FileAssert { + part def CliSubsystem { + doc /* Command-line argument parsing and output-reporting contract. */ + + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Cli/CliTests.cs */ + comment designRef /* Design: docs/design/file-assert/cli.md */ + comment verificationRef /* Verification: docs/verification/file-assert/cli.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/cli.yaml */ + + part iContext : IContext; + part context : Context; + } +} diff --git a/docs/sysml2/model/file-assert/cli/context.sysml b/docs/sysml2/model/file-assert/cli/context.sysml new file mode 100644 index 0000000..5117965 --- /dev/null +++ b/docs/sysml2/model/file-assert/cli/context.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def Context { + doc /* Command-line argument parser and I/O owner implementing IContext. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Cli/Context.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Cli/ContextTests.cs */ + comment designRef /* Design: docs/design/file-assert/cli/context.md */ + comment verificationRef /* Verification: docs/verification/file-assert/cli/context.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/cli/context.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/cli/i-context.sysml b/docs/sysml2/model/file-assert/cli/i-context.sysml new file mode 100644 index 0000000..c561493 --- /dev/null +++ b/docs/sysml2/model/file-assert/cli/i-context.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def IContext { + doc /* Output contract interface for reporting assertion results and scoping. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Cli/IContext.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Cli/ScopedContextTests.cs */ + comment designRef /* Design: docs/design/file-assert/cli/i-context.md */ + comment verificationRef /* Verification: docs/verification/file-assert/cli/i-context.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/cli/i-context.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/configuration.sysml b/docs/sysml2/model/file-assert/configuration.sysml new file mode 100644 index 0000000..e5ae8cc --- /dev/null +++ b/docs/sysml2/model/file-assert/configuration.sysml @@ -0,0 +1,13 @@ +package FileAssert { + part def ConfigurationSubsystem { + doc /* Top-level configuration loading, deserialization, and test execution. */ + + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Configuration/ConfigurationTests.cs */ + comment designRef /* Design: docs/design/file-assert/configuration.md */ + comment verificationRef /* Verification: docs/verification/file-assert/configuration.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/configuration.yaml */ + + part fileAssertConfig : FileAssertConfig; + part fileAssertData : FileAssertData; + } +} diff --git a/docs/sysml2/model/file-assert/configuration/file-assert-config.sysml b/docs/sysml2/model/file-assert/configuration/file-assert-config.sysml new file mode 100644 index 0000000..85d55da --- /dev/null +++ b/docs/sysml2/model/file-assert/configuration/file-assert-config.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertConfig { + doc /* Top-level configuration loader and test runner. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Configuration/FileAssertConfig.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Configuration/FileAssertConfigTests.cs */ + comment designRef /* Design: docs/design/file-assert/configuration/file-assert-config.md */ + comment verificationRef /* Verification: docs/verification/file-assert/configuration/file-assert-config.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/configuration/file-assert-config.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/configuration/file-assert-data.sysml b/docs/sysml2/model/file-assert/configuration/file-assert-data.sysml new file mode 100644 index 0000000..17f0005 --- /dev/null +++ b/docs/sysml2/model/file-assert/configuration/file-assert-data.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertData { + doc /* YAML data transfer objects for configuration deserialization. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Configuration/FileAssertData.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Configuration/FileAssertConfigTests.cs */ + comment designRef /* Design: docs/design/file-assert/configuration/file-assert-data.md */ + comment verificationRef /* Verification: docs/verification/file-assert/configuration/file-assert-data.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/configuration/file-assert-data.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling.sysml b/docs/sysml2/model/file-assert/modeling.sysml new file mode 100644 index 0000000..16c5cee --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling.sysml @@ -0,0 +1,21 @@ +package FileAssert { + part def ModelingSubsystem { + doc /* Test-suite data model and content-assertion rule implementations. */ + + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/ModelingTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling.yaml */ + + part fileAssertTest : FileAssertTest; + part fileAssertFile : FileAssertFile; + part fileAssertRule : FileAssertRule; + part fileAssertTextAssert : FileAssertTextAssert; + part fileAssertPdfAssert : FileAssertPdfAssert; + part fileAssertXmlAssert : FileAssertXmlAssert; + part fileAssertHtmlAssert : FileAssertHtmlAssert; + part fileAssertYamlAssert : FileAssertYamlAssert; + part fileAssertJsonAssert : FileAssertJsonAssert; + part fileAssertZipAssert : FileAssertZipAssert; + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-file.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-file.sysml new file mode 100644 index 0000000..100e7d3 --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-file.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertFile { + doc /* Glob pattern matcher with count constraints and content rules. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertFile.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertFileTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-file.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-file.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-file.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-html-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-html-assert.sysml new file mode 100644 index 0000000..b32fbfe --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-html-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertHtmlAssert { + doc /* HTML document assertions (HtmlAgilityPack). */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertHtmlAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertHtmlAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-html-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-html-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-html-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-json-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-json-assert.sysml new file mode 100644 index 0000000..2d9829d --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-json-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertJsonAssert { + doc /* JSON document assertions (System.Text.Json). */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertJsonAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertJsonAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-json-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-json-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-json-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-pdf-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-pdf-assert.sysml new file mode 100644 index 0000000..8c66cef --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-pdf-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertPdfAssert { + doc /* PDF document assertions (PdfPig). */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertPdfAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertPdfAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-pdf-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-pdf-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-pdf-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-rule.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-rule.sysml new file mode 100644 index 0000000..c5773b7 --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-rule.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertRule { + doc /* Abstract content validation rule hierarchy. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertRule.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertRuleTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-rule.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-rule.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-rule.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-test.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-test.sysml new file mode 100644 index 0000000..8f7b849 --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-test.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertTest { + doc /* Named test with file assertions and tag filtering. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertTest.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertTestTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-test.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-test.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-test.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-text-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-text-assert.sysml new file mode 100644 index 0000000..d5a9f0b --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-text-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertTextAssert { + doc /* Text content assertions. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertTextAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertTextAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-text-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-text-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-text-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-xml-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-xml-assert.sysml new file mode 100644 index 0000000..cd47a57 --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-xml-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertXmlAssert { + doc /* XML document assertions (System.Xml.Linq/XPath). */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertXmlAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertXmlAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-xml-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-xml-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-xml-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-yaml-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-yaml-assert.sysml new file mode 100644 index 0000000..0110780 --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-yaml-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertYamlAssert { + doc /* YAML document assertions (YamlDotNet). */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertYamlAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertYamlAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-yaml-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-yaml-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-yaml-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/modeling/file-assert-zip-assert.sysml b/docs/sysml2/model/file-assert/modeling/file-assert-zip-assert.sysml new file mode 100644 index 0000000..1332781 --- /dev/null +++ b/docs/sysml2/model/file-assert/modeling/file-assert-zip-assert.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def FileAssertZipAssert { + doc /* Zip archive entry assertions (System.IO.Compression). */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Modeling/FileAssertZipAssert.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Modeling/FileAssertZipAssertTests.cs */ + comment designRef /* Design: docs/design/file-assert/modeling/file-assert-zip-assert.md */ + comment verificationRef /* Verification: docs/verification/file-assert/modeling/file-assert-zip-assert.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/modeling/file-assert-zip-assert.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/program.sysml b/docs/sysml2/model/file-assert/program.sysml new file mode 100644 index 0000000..e479830 --- /dev/null +++ b/docs/sysml2/model/file-assert/program.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def Program { + doc /* Entry point and execution orchestrator. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Program.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/ProgramTests.cs */ + comment designRef /* Design: docs/design/file-assert/program.md */ + comment verificationRef /* Verification: docs/verification/file-assert/program.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/program.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/selftest.sysml b/docs/sysml2/model/file-assert/selftest.sysml new file mode 100644 index 0000000..49c4975 --- /dev/null +++ b/docs/sysml2/model/file-assert/selftest.sysml @@ -0,0 +1,12 @@ +package FileAssert { + part def SelfTestSubsystem { + doc /* Self-validation test runner exercised at startup for OTS/BuildMark self-check evidence. */ + + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/SelfTest/ValidationTests.cs */ + comment designRef /* Design: docs/design/file-assert/selftest.md */ + comment verificationRef /* Verification: docs/verification/file-assert/selftest.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/selftest.yaml */ + + part validation : Validation; + } +} diff --git a/docs/sysml2/model/file-assert/selftest/validation.sysml b/docs/sysml2/model/file-assert/selftest/validation.sysml new file mode 100644 index 0000000..4265252 --- /dev/null +++ b/docs/sysml2/model/file-assert/selftest/validation.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def Validation { + doc /* Self-validation test runner. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/SelfTest/Validation.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/SelfTest/ValidationTests.cs */ + comment designRef /* Design: docs/design/file-assert/selftest/validation.md */ + comment verificationRef /* Verification: docs/verification/file-assert/selftest/validation.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/selftest/validation.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/utilities.sysml b/docs/sysml2/model/file-assert/utilities.sysml new file mode 100644 index 0000000..abada2c --- /dev/null +++ b/docs/sysml2/model/file-assert/utilities.sysml @@ -0,0 +1,16 @@ +package FileAssert { + part def UtilitiesSubsystem { + doc /* File-access abstraction and small supporting helpers. */ + + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Utilities/UtilitiesTests.cs */ + comment designRef /* Design: docs/design/file-assert/utilities.md */ + comment verificationRef /* Verification: docs/verification/file-assert/utilities.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/utilities.yaml */ + + part iFileContainer : IFileContainer; + part directoryFileContainer : DirectoryFileContainer; + part zipFileContainer : ZipFileContainer; + part pathHelpers : PathHelpers; + part temporaryDirectory : TemporaryDirectory; + } +} diff --git a/docs/sysml2/model/file-assert/utilities/directory-file-container.sysml b/docs/sysml2/model/file-assert/utilities/directory-file-container.sysml new file mode 100644 index 0000000..da0b2cb --- /dev/null +++ b/docs/sysml2/model/file-assert/utilities/directory-file-container.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def DirectoryFileContainer { + doc /* Filesystem implementation of IFileContainer. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Utilities/DirectoryFileContainer.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Utilities/IFileContainerTests.cs */ + comment designRef /* Design: docs/design/file-assert/utilities/directory-file-container.md */ + comment verificationRef /* Verification: docs/verification/file-assert/utilities/directory-file-container.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/utilities/directory-file-container.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/utilities/i-file-container.sysml b/docs/sysml2/model/file-assert/utilities/i-file-container.sysml new file mode 100644 index 0000000..87e83e0 --- /dev/null +++ b/docs/sysml2/model/file-assert/utilities/i-file-container.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def IFileContainer { + doc /* Uniform file-access abstraction over directories and zip archives. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Utilities/IFileContainer.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Utilities/IFileContainerTests.cs */ + comment designRef /* Design: docs/design/file-assert/utilities/i-file-container.md */ + comment verificationRef /* Verification: docs/verification/file-assert/utilities/i-file-container.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/utilities/i-file-container.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/utilities/path-helpers.sysml b/docs/sysml2/model/file-assert/utilities/path-helpers.sysml new file mode 100644 index 0000000..b1e40e2 --- /dev/null +++ b/docs/sysml2/model/file-assert/utilities/path-helpers.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def PathHelpers { + doc /* Safe path-combination utility. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Utilities/PathHelpers.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Utilities/PathHelpersTests.cs */ + comment designRef /* Design: docs/design/file-assert/utilities/path-helpers.md */ + comment verificationRef /* Verification: docs/verification/file-assert/utilities/path-helpers.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/utilities/path-helpers.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/utilities/temporary-directory.sysml b/docs/sysml2/model/file-assert/utilities/temporary-directory.sysml new file mode 100644 index 0000000..c8f277d --- /dev/null +++ b/docs/sysml2/model/file-assert/utilities/temporary-directory.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def TemporaryDirectory { + doc /* Disposable temporary directory utility. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Utilities/TemporaryDirectory.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Utilities/TemporaryDirectoryTests.cs */ + comment designRef /* Design: docs/design/file-assert/utilities/temporary-directory.md */ + comment verificationRef /* Verification: docs/verification/file-assert/utilities/temporary-directory.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/utilities/temporary-directory.yaml */ + } +} diff --git a/docs/sysml2/model/file-assert/utilities/zip-file-container.sysml b/docs/sysml2/model/file-assert/utilities/zip-file-container.sysml new file mode 100644 index 0000000..f5f47bf --- /dev/null +++ b/docs/sysml2/model/file-assert/utilities/zip-file-container.sysml @@ -0,0 +1,11 @@ +package FileAssert { + part def ZipFileContainer { + doc /* Zip archive implementation of IFileContainer. */ + + comment sourceRef /* Source: src/DemaConsulting.FileAssert/Utilities/ZipFileContainer.cs */ + comment testRef /* Test: test/DemaConsulting.FileAssert.Tests/Utilities/IFileContainerTests.cs */ + comment designRef /* Design: docs/design/file-assert/utilities/zip-file-container.md */ + comment verificationRef /* Verification: docs/verification/file-assert/utilities/zip-file-container.md */ + comment reqRef /* Requirements: docs/reqstream/file-assert/utilities/zip-file-container.yaml */ + } +} diff --git a/docs/sysml2/model/ots.sysml b/docs/sysml2/model/ots.sysml new file mode 100644 index 0000000..7bf1ec3 --- /dev/null +++ b/docs/sysml2/model/ots.sysml @@ -0,0 +1,35 @@ +package OtsDependencies { + doc /* Off-the-shelf (OTS) dependencies used by FileAssert. */ + + part def YamlDotNet { + doc /* OTS: YamlDotNet. */ + + comment designRef /* Design: docs/design/ots/yamldotnet.md */ + comment verificationRef /* Verification: docs/verification/ots/yamldotnet.md */ + comment reqRef /* Requirements: docs/reqstream/ots/yamldotnet.yaml */ + } + + part def PdfPig { + doc /* OTS: PdfPig. */ + + comment designRef /* Design: docs/design/ots/pdfpig.md */ + comment verificationRef /* Verification: docs/verification/ots/pdfpig.md */ + comment reqRef /* Requirements: docs/reqstream/ots/pdfpig.yaml */ + } + + part def HtmlAgilityPack { + doc /* OTS: HtmlAgilityPack. */ + + comment designRef /* Design: docs/design/ots/htmlagilitypack.md */ + comment verificationRef /* Verification: docs/verification/ots/htmlagilitypack.md */ + comment reqRef /* Requirements: docs/reqstream/ots/htmlagilitypack.yaml */ + } + + part def FileSystemGlobbing { + doc /* OTS: FileSystemGlobbing. */ + + comment designRef /* Design: docs/design/ots/filesystemglobbing.md */ + comment verificationRef /* Verification: docs/verification/ots/filesystemglobbing.md */ + comment reqRef /* Requirements: docs/reqstream/ots/filesystemglobbing.yaml */ + } +} diff --git a/docs/sysml2/model/shared.sysml b/docs/sysml2/model/shared.sysml new file mode 100644 index 0000000..157ab75 --- /dev/null +++ b/docs/sysml2/model/shared.sysml @@ -0,0 +1,11 @@ +package SharedDependencies { + doc /* Shared Packages consumed by FileAssert. */ + + part def FileAssertSharedPackage { + doc /* Shared Package: an earlier FileAssert release consumed as a CI dependency of this repository's own build pipeline. */ + + comment designRef /* Design: docs/design/shared/fileassert.md */ + comment verificationRef /* Verification: docs/verification/shared/fileassert.md */ + comment reqRef /* Requirements: docs/reqstream/shared/fileassert.yaml */ + } +} diff --git a/docs/sysml2/views/design-views.sysml b/docs/sysml2/views/design-views.sysml new file mode 100644 index 0000000..da57416 --- /dev/null +++ b/docs/sysml2/views/design-views.sysml @@ -0,0 +1,34 @@ +// Views rendered into docs/design/generated/ for the Design document. +// Reopens the FileAssert 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 FileAssert { + view SoftwareStructureView { + expose FileAssert; + } + + view FileAssertView { + expose FileAssertSystem; + } + + view CliView { + expose CliSubsystem; + } + + view ConfigurationView { + expose ConfigurationSubsystem; + } + + view ModelingView { + expose ModelingSubsystem; + } + + view UtilitiesView { + expose UtilitiesSubsystem; + } + + view SelfTestView { + expose SelfTestSubsystem; + } +} diff --git a/docs/user_guide/introduction.md b/docs/user_guide/introduction.md index 52a5763..a2d81e2 100644 --- a/docs/user_guide/introduction.md +++ b/docs/user_guide/introduction.md @@ -328,10 +328,17 @@ tests: | `json[].count` | Exact number of matched JSON nodes | | `json[].min` | Minimum number of matched JSON nodes | | `json[].max` | Maximum number of matched JSON nodes | -| `zip:` | Zip archive entry assertions (fails if not a valid zip) | -| `zip.entries[].pattern` | Glob pattern matching zip entry names | -| `zip.entries[].min` | Minimum number of matching entries | -| `zip.entries[].max` | Maximum number of matching entries | +| `zip:` | Zip archive assertions (fails if file is not a valid zip) | +| `zip.files[].pattern` | Glob pattern selecting zip archive entry names | +| `zip.files[].min` | Minimum number of matching zip entries | +| `zip.files[].max` | Maximum number of matching zip entries | +| `zip.files[].text` | Text content assertions applied to each matching zip entry | +| `zip.files[].pdf` | PDF assertions applied to each matching zip entry | +| `zip.files[].xml` | XML assertions applied to each matching zip entry | +| `zip.files[].html` | HTML assertions applied to each matching zip entry | +| `zip.files[].yaml` | YAML assertions applied to each matching zip entry | +| `zip.files[].json` | JSON assertions applied to each matching zip entry | +| `zip.files[].zip` | Nested zip assertions (zip-in-zip) | # Command-Line Options diff --git a/docs/verification/definition.yaml b/docs/verification/definition.yaml index 313eab9..651780b 100644 --- a/docs/verification/definition.yaml +++ b/docs/verification/definition.yaml @@ -10,6 +10,7 @@ input-files: - docs/verification/file-assert/program.md - docs/verification/file-assert/cli.md - docs/verification/file-assert/cli/context.md + - docs/verification/file-assert/cli/i-context.md - docs/verification/file-assert/configuration.md - docs/verification/file-assert/configuration/file-assert-config.md - docs/verification/file-assert/configuration/file-assert-data.md @@ -23,8 +24,13 @@ input-files: - docs/verification/file-assert/modeling/file-assert-html-assert.md - docs/verification/file-assert/modeling/file-assert-yaml-assert.md - docs/verification/file-assert/modeling/file-assert-json-assert.md + - docs/verification/file-assert/modeling/file-assert-zip-assert.md - docs/verification/file-assert/utilities.md - docs/verification/file-assert/utilities/path-helpers.md + - docs/verification/file-assert/utilities/temporary-directory.md + - docs/verification/file-assert/utilities/i-file-container.md + - docs/verification/file-assert/utilities/directory-file-container.md + - docs/verification/file-assert/utilities/zip-file-container.md - docs/verification/file-assert/selftest.md - docs/verification/file-assert/selftest/validation.md - docs/verification/ots.md @@ -37,6 +43,11 @@ input-files: - docs/verification/ots/versionmark.md - docs/verification/ots/weasyprint.md - docs/verification/ots/xunit.md + - docs/verification/ots/yamldotnet.md + - docs/verification/ots/pdfpig.md + - docs/verification/ots/htmlagilitypack.md + - docs/verification/ots/filesystemglobbing.md + - docs/verification/ots/sysml2tools.md - docs/verification/shared.md - docs/verification/shared/fileassert.md template: template.html diff --git a/docs/verification/introduction.md b/docs/verification/introduction.md index 57612a4..0cd33d8 100644 --- a/docs/verification/introduction.md +++ b/docs/verification/introduction.md @@ -58,6 +58,7 @@ The following OTS items are also covered: - **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 @@ -66,56 +67,6 @@ The following OTS items are also covered: - **HtmlAgilityPack** — HTML parsing library - **FileSystemGlobbing** — glob pattern-matching library -## Software Structure - -The following tree shows the software items covered by this document: - -```text -FileAssert (System) -├── Program (Unit) -├── Cli (Subsystem) -│ ├── Context (Unit) -│ └── IContext (Unit) -├── Configuration (Subsystem) -│ ├── FileAssertConfig (Unit) -│ └── FileAssertData (Unit) -├── Modeling (Subsystem) -│ ├── FileAssertTest (Unit) -│ ├── FileAssertFile (Unit) -│ ├── FileAssertRule (Unit) -│ ├── FileAssertTextAssert (Unit) -│ ├── FileAssertPdfAssert (Unit) -│ ├── FileAssertXmlAssert (Unit) -│ ├── FileAssertHtmlAssert (Unit) -│ ├── FileAssertYamlAssert (Unit) -│ ├── FileAssertJsonAssert (Unit) -│ └── FileAssertZipAssert (Unit) -├── Utilities (Subsystem) -│ ├── PathHelpers (Unit) -│ ├── TemporaryDirectory (Unit) -│ ├── IFileContainer (Unit) -│ ├── DirectoryFileContainer (Unit) -│ └── ZipFileContainer (Unit) -└── SelfTest (Subsystem) - └── Validation (Unit) - -OTS Items -├── BuildMark -├── FileAssert -├── Pandoc -├── ReqStream -├── ReviewMark -├── SarifMark -├── SonarMark -├── VersionMark -├── WeasyPrint -├── xUnit -├── YamlDotNet -├── PdfPig -├── HtmlAgilityPack -└── FileSystemGlobbing -``` - ## Companion Artifact Structure In-house items have corresponding artifacts in parallel directory trees: diff --git a/docs/verification/ots.md b/docs/verification/ots.md index 1b25538..550c814 100644 --- a/docs/verification/ots.md +++ b/docs/verification/ots.md @@ -10,17 +10,18 @@ FileAssert CI pipeline. OTS software items used by FileAssert are verified by one of two complementary approaches, depending on the nature of the item: -- **Authored integration tests**: Items whose correct behaviour cannot be inferred purely from - pipeline success (xUnit) are verified by named test scenarios that exercise the specific - features required by this project. Each scenario identifies a test method, the expected - outcome, and the requirement it covers. +- **Authored integration tests**: Items whose correct behavior cannot be inferred purely from + pipeline success (xUnit, YamlDotNet, PdfPig, HtmlAgilityPack, FileSystemGlobbing) are verified + by named test scenarios that exercise the specific features required by this project. Each + scenario identifies a test method, the expected outcome, and the requirement it covers. -- **CI pipeline evidence**: Items whose primary function is to produce artefacts consumed by +- **CI pipeline evidence**: Items whose primary function is to produce artifacts consumed by downstream pipeline steps (BuildMark, Pandoc, ReqStream, ReviewMark, SarifMark, SonarMark, - VersionMark, WeasyPrint) are verified by a chain of transitive evidence: the item executes in - CI, produces its expected output, and a subsequent step (typically a FileAssert assertion or a - ReqStream enforce check) fails the build if the output is absent or malformed. A passing - pipeline run therefore constitutes evidence that each item performed its required function. + SysML2Tools, VersionMark, WeasyPrint) are verified by a chain of transitive evidence: the item + executes in CI, produces its expected output, and a subsequent step (typically a FileAssert + assertion or a ReqStream enforce check) fails the build if the output is absent or malformed. A + passing pipeline run therefore constitutes evidence that each item performed its required + function. Per-item verification details, test scenarios, and requirements mappings are documented in the individual files under `docs/verification/ots/`. @@ -29,14 +30,15 @@ individual files under `docs/verification/ots/`. The following evidence is collected and retained for each OTS item: -- **xUnit**: TRX result files generated by `dotnet test` during CI. Each TRX file is consumed by - `reqstream --enforce` to confirm that all named test scenarios have a recorded passing result. +- **xUnit, YamlDotNet, PdfPig, HtmlAgilityPack, FileSystemGlobbing**: TRX result files generated + by `dotnet test` during CI. Each TRX file is consumed by `reqstream --enforce` to confirm that + all named test scenarios have a recorded passing result. - **All other OTS items**: A passing CI pipeline run, including Pandoc HTML generation, WeasyPrint PDF rendering, FileAssert assertions on every generated document, and `reqstream --enforce` with - no unmet requirements. The combined CI log and artefacts constitute the qualification record. + no unmet requirements. The combined CI log and artifacts constitute the qualification record. -All CI artefacts are retained as GitHub Actions run artefacts and are accessible from the +All CI artifacts are retained as GitHub Actions run artifacts and are accessible from the FileAssert releases page. ## Regression Approach @@ -74,6 +76,10 @@ The following OTS software items are used by FileAssert and are verified in this - **SonarMark** — retrieves quality-gate and metrics data from SonarCloud and renders a markdown quality report; verified by Pandoc compilation and FileAssert PDF assertions. +- **SysML2Tools** — validates the SysML2 architecture model and renders its declared views to SVG + diagrams consumed by the design documentation; verified by CI pipeline lint success and by + Pandoc/WeasyPrint compilation of the design documents that embed the rendered diagrams. + - **VersionMark** — captures tool-version metadata from CI jobs and publishes a versions markdown document; verified by its inclusion in the Build Notes compilation. @@ -83,6 +89,20 @@ The following OTS software items are used by FileAssert and are verified in this - **xUnit** — discovers and executes unit tests and writes TRX result files; verified by self-validation test scenarios that confirm test discovery, execution, and reporting. +- **YamlDotNet** — parses and deserializes YAML configuration and documents under test for + `yaml:` dot-notation assertions; verified by authored test scenarios covering scalar, + sequence, and malformed-document handling. + +- **PdfPig** — parses PDF documents under test for `pdf:` assertions; verified by authored test + scenarios covering page count, metadata, and text extraction. + +- **HtmlAgilityPack** — parses HTML documents under test for `html:` XPath assertions; verified + by authored test scenarios covering well-formed and lenient HTML parsing. + +- **FileSystemGlobbing** — resolves glob patterns against candidate files for file-count and + content assertions; verified by authored test scenarios covering include/exclude pattern + matching. + ## Acceptance Criteria OTS item verification passes when all self-validation runs and integration test scenarios diff --git a/docs/verification/ots/sysml2tools.md b/docs/verification/ots/sysml2tools.md new file mode 100644 index 0000000..db11511 --- /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 FileAssert 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 (`WeasyPrint_DesignPdf`). 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 47e32de..5d792e7 100644 --- a/requirements.yaml +++ b/requirements.yaml @@ -44,3 +44,4 @@ includes: - docs/reqstream/ots/pdfpig.yaml - docs/reqstream/ots/htmlagilitypack.yaml - docs/reqstream/ots/filesystemglobbing.yaml + - docs/reqstream/ots/sysml2tools.yaml