From 132a0d4f972adb1505544d4164a7a9b03a4b11b2 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Thu, 9 Jul 2026 13:04:21 -0400 Subject: [PATCH 1/5] Update agents, standards, and skills Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/agents/developer.agent.md | 5 +- .github/agents/formal-review.agent.md | 13 +- .github/agents/implementation.agent.md | 54 ++-- .github/agents/lint-fix.agent.md | 3 +- .github/agents/planning.agent.md | 134 ++++++++++ .github/agents/quality.agent.md | 33 ++- .github/agents/template-sync.agent.md | 47 +++- .github/skills/sysml2tools-query/SKILL.md | 145 +++++++++++ .github/standards/coding-principles.md | 18 +- .github/standards/csharp-language.md | 3 - .github/standards/csharp-testing.md | 2 - .github/standards/design-documentation.md | 48 ++-- .github/standards/reqstream-usage.md | 22 +- .github/standards/reviewmark-usage.md | 202 +++++++-------- .github/standards/software-items.md | 43 ++-- .github/standards/sysml2-modeling.md | 232 ++++++++++++++++++ .github/standards/technical-documentation.md | 56 +---- .github/standards/testing-principles.md | 5 - .../standards/verification-documentation.md | 41 +--- AGENTS.md | 35 ++- 20 files changed, 832 insertions(+), 309 deletions(-) create mode 100644 .github/agents/planning.agent.md create mode 100644 .github/skills/sysml2tools-query/SKILL.md create mode 100644 .github/standards/sysml2-modeling.md diff --git a/.github/agents/developer.agent.md b/.github/agents/developer.agent.md index 5f208eb..5f2b988 100644 --- a/.github/agents/developer.agent.md +++ b/.github/agents/developer.agent.md @@ -19,7 +19,7 @@ Perform software development tasks by determining and applying appropriate stand If one exists, fetch it as the starting point; adjust placeholder names and heading depth to match the target path before writing the file - For each modified file, identify which companion artifacts need updating - (requirements, design docs, tests, review-sets) + (requirements, design docs, verification docs, tests, review-sets, README.md, user guides) - Include companion artifact updates in the work plan 4. **Execute work** following standards requirements and quality checks 5. **Formatting**: Run `pwsh ./fix.ps1` to silently apply all @@ -35,8 +35,7 @@ Perform software development tasks by determining and applying appropriate stand # Developer Agent Report **Result**: (SUCCEEDED|FAILED) - -## Work Summary +**Report**: `.agent-logs/developer-{subject}-{unique-id}.md` - **Files Modified**: {List of files created/modified/deleted} - **Languages Detected**: {Languages identified} diff --git a/.github/agents/formal-review.agent.md b/.github/agents/formal-review.agent.md index 7dd8e84..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 @@ -44,6 +46,7 @@ standards from the selection matrix in AGENTS.md. # Formal Review Report **Result**: (SUCCEEDED|FAILED) +**Report**: `.agent-logs/formal-review-{subject}-{unique-id}.md` ## Review Summary diff --git a/.github/agents/implementation.agent.md b/.github/agents/implementation.agent.md index 7cc0352..d94e880 100644 --- a/.github/agents/implementation.agent.md +++ b/.github/agents/implementation.agent.md @@ -28,36 +28,18 @@ The state-transitions include retrying a limited number of times: ## PLANNING State (start) -Call the **explore** agent as a sub-agent (built-in agent type) with: +Call the **planning** agent as a sub-agent (custom agent from `.github/agents/`) with: - **context**: the user's request + any previous quality findings + retry context -- **goal**: produce a verified implementation plan through these steps: - - 1. Investigate the codebase and develop a concrete implementation plan that - addresses the request - 2. **Identify companion artifact deliverables**: for every code change in the - plan, list the requirements files, design documents, and review-set entries - that must be created or updated - traceability must flow requirements → - design → code, so these are mandatory deliverables, not optional extras - 3. Review the plan for assumptions, weaknesses, and gaps - identify up to 5 - key assumptions and rate each as: - - **VERIFIED**: confirmed by codebase evidence - - **LIKELY**: consistent with codebase patterns but not directly confirmed - - **UNVERIFIED**: not confirmed by any evidence - 4. For any assumption rated UNVERIFIED or LIKELY, attempt to resolve it - through additional investigation and revise the plan to address identified - weaknesses - repeat the critique-and-strengthen cycle up to 2 additional - times if unresolved issues remain, but stop as soon as the plan is stable - 5. List up to 5 risks to the implementation - 6. Assess feasibility: can this be implemented in a single development pass? - 7. State a **recommendation**: GO or INCOMPLETE - GO if the plan is sound, or - INCOMPLETE if critical unknowns remain that only the user can resolve - -Once the explore sub-agent finishes: - -- IF recommendation is INCOMPLETE: Transition to REPORT with Result: INCOMPLETE, +- **goal**: produce a verified implementation plan, or a targeted plan to address + the identified quality issues if this is a retry + +Once the planning sub-agent finishes: + +- IF Result is FAILED: Transition to REPORT with Result: FAILED +- IF Result is INCOMPLETE: Transition to REPORT with Result: INCOMPLETE, listing the unknowns and what CAN be implemented once they are resolved -- OTHERWISE (GO): Transition to DEVELOPMENT +- OTHERWISE (SUCCEEDED): Transition to DEVELOPMENT ## DEVELOPMENT State @@ -76,7 +58,8 @@ Once the developer sub-agent finishes: Call the **quality** agent as a sub-agent (custom agent from `.github/agents/`) with: -- **context**: the user's request + development summary + files changed + previous issues (if any) +- **context**: the user's request + development summary + files changed + planning companion artifact table + + previous issues (if any) - **goal**: check the quality of the work performed for any issues Once the quality sub-agent finishes: @@ -92,6 +75,9 @@ Once the quality sub-agent finishes: this agent may report INCOMPLETE when the request cannot be implemented without information only the user can provide. +For full planning details (assumptions, risks, feasibility), read the planning +report file referenced in the planning agent's response. + Generate the completion report using the template below, then save it to `.agent-logs/{agent-name}-{subject}-{unique-id}.md` per the AGENTS.md reporting requirements, and return the summary to the caller. @@ -102,19 +88,20 @@ requirements, and return the summary to the caller. # Implementation Orchestration Report **Result**: (SUCCEEDED|FAILED|INCOMPLETE) -**Final State**: (PLANNING|DEVELOPMENT|QUALITY|REPORT) +**Report**: `.agent-logs/implementation-{subject}-{unique-id}.md` +**Last Active State**: (PLANNING|DEVELOPMENT|QUALITY) **Retry Count**: ## State Machine Execution -- **Planning Results**: {Implementation plan, assumption ratings, risks, and recommendation} +- **Planning Results**: {Planning report path; plan summary and SUCCEEDED/INCOMPLETE/FAILED result} - **Development Results**: {Summary of developer agent results} - **Quality Results**: {Summary of quality agent results} - **State Transitions**: {Log of state changes and decisions} ## Sub-Agent Coordination -- **Explore Agent (Planning)**: {Plan, assumption verdicts, top risks, GO/INCOMPLETE recommendation} +- **Planning Agent**: {Report file path, SUCCEEDED/INCOMPLETE/FAILED result, plan summary} - **Developer Agent**: {Development status and files modified} - **Quality Agent**: {Validation results and compliance status} @@ -123,4 +110,9 @@ requirements, and return the summary to the caller. - **Implementation Success**: {Overall completion status} - **Quality Compliance**: {Final quality validation status} - **Issues Resolved**: {Problems encountered and resolution attempts} + +## Unknowns (only when Result is INCOMPLETE) + +- **Unresolved Questions**: {List each question the user must answer} +- **What Can Proceed**: {Work that can be done without the missing information} ``` diff --git a/.github/agents/lint-fix.agent.md b/.github/agents/lint-fix.agent.md index 549e751..36d3ca1 100644 --- a/.github/agents/lint-fix.agent.md +++ b/.github/agents/lint-fix.agent.md @@ -68,8 +68,7 @@ submission, not during normal development. # Lint Fix Report **Result**: (SUCCEEDED|FAILED) - -## Summary +**Report**: `.agent-logs/lint-fix-{subject}-{unique-id}.md` - **Iterations**: {Number of fix-loop iterations performed} - **Files Modified**: {List of all files changed} diff --git a/.github/agents/planning.agent.md b/.github/agents/planning.agent.md new file mode 100644 index 0000000..20e75ee --- /dev/null +++ b/.github/agents/planning.agent.md @@ -0,0 +1,134 @@ +--- +name: planning +description: Planning agent that investigates the codebase, develops a verified implementation plan, and identifies all companion artifact deliverables. +user-invocable: true +--- + +# Planning Agent + +Investigate the codebase and produce a verified implementation plan with all +companion artifact deliverables. + +## Step 1 — Load Standards + +Read the relevant standards from `.github/standards/` using the selection matrix +in `AGENTS.md` based on the artifact types in scope for the request (requirements, +design, verification, documentation, code). + +## Step 2 — Investigate and Plan + +Read `docs/design/introduction.md` first (if present), then investigate the +codebase to develop a concrete implementation plan: + +- Identify all files to create, modify, or delete +- Describe the change required for each file + +## Step 3 — Identify Companion Artifact Deliverables + +For each planned change, assess the mandatory companion artifacts below (create/update/N/A +with justification): + +- **Requirements** — functional changes require a requirement entry +- **Design Documentation** — new or changed components require design docs +- **Verification Documentation** — new or changed components require verification docs +- **Tests** — functional changes require test coverage +- **Review Sets** — changes to the software item hierarchy (units or subsystems + added, removed, or reorganized) require review-set updates +- **README.md** — user-facing changes require README updates +- **User Guide** — user-facing features require user guide updates + +## Step 4 — Critique and Strengthen + +Identify up to 5 key assumptions and rate each: + +- **VERIFIED**: confirmed by codebase evidence +- **LIKELY**: consistent with codebase patterns but not directly confirmed +- **UNVERIFIED**: not confirmed by any evidence + +For UNVERIFIED or LIKELY assumptions, investigate further and revise the plan. +Repeat up to 2 more times, stopping when the plan is stable. + +## Step 5 — Risk Assessment + +List up to 5 risks with a brief mitigation for each. + +## Step 6 — Feasibility Assessment + +State whether this can be implemented in a single development pass and any +preconditions that affect feasibility. + +## Step 7 — Recommendation + +- **SUCCEEDED** — the plan is sound and the developer agent can proceed +- **INCOMPLETE** — critical unknowns remain that only the user can resolve; + list each unknown explicitly +- **FAILED** — investigation could not produce a viable plan + +# REPORT Phase + +Save the full analysis to `.agent-logs/planning-{subject}-{unique-id}.md` per +the AGENTS.md reporting requirements. + +Then respond to the caller with ONLY the lean structured summary below. + +# Report Template + +```markdown +# Planning Report + +**Result**: (SUCCEEDED|INCOMPLETE|FAILED) +**Request Summary**: {Brief restatement of the task as understood} +**Report**: `.agent-logs/planning-{subject}-{unique-id}.md` + +## Implementation Plan + +| File | Action | Description | +|------|--------|-------------| +| {path} | create/modify/delete | {what changes and why} | + +## Companion Artifact Deliverables + +| Category | File | Action | +|----------|------|--------| +| Requirements | {path} | create/update/N/A — {justification} | +| Design Documentation | {path} | create/update/N/A — {justification} | +| Verification Documentation | {path} | create/update/N/A — {justification} | +| Tests | {path} | create/update/N/A — {justification} | +| Review Sets | {path} | create/update/N/A — {justification} | +| README.md | {path} | create/update/N/A — {justification} | +| User Guide | {path} | create/update/N/A — {justification} | + +## Assumption Analysis + +| # | Assumption | Rating | Resolution | +|---|-----------|--------|------------| +| 1 | {assumption} | VERIFIED/LIKELY/UNVERIFIED | {resolution or N/A} | + +## Risk Assessment + +1. **[severity]** {risk} — {mitigation} + +## Feasibility Assessment + +{Single-pass or not, and why. Any preconditions.} + +## Unknowns + +{Only present when Result is INCOMPLETE. List each question the user must +resolve before implementation can proceed.} +``` + +# Lean Structured Response (returned to caller) + +```markdown +**Result**: (SUCCEEDED|INCOMPLETE|FAILED) +**Report**: `.agent-logs/planning-{subject}-{unique-id}.md` + +**Plan**: +{Repeat the Implementation Plan table} + +**Companion Artifacts**: +{Repeat the Companion Artifact Deliverables table} + +**Unknowns**: {Only if INCOMPLETE — list questions for the user} +``` diff --git a/.github/agents/quality.agent.md b/.github/agents/quality.agent.md index 380d11f..26fd251 100644 --- a/.github/agents/quality.agent.md +++ b/.github/agents/quality.agent.md @@ -13,14 +13,23 @@ Grade and validate software development work by ensuring compliance with project 1. **Analyze the task request AND completed work** to determine scope: identify which artifact categories were changed, and which *should have been changed* given the task - new user-visible features always require requirements, - design, and review-set coverage regardless of whether those files were touched; - test-only additions (corner-case tests, defensive boundary tests, regression - tests) do not require a corresponding requirement + design, verification docs, and README/user guide updates regardless of + whether those files were touched; Review Sets are always in scope when + the software item hierarchy changes (units or subsystems added, removed, or + reorganized); test-only additions (corner-case tests, defensive boundary + tests, regression tests) do not require a corresponding requirement; if a + planning companion artifact table is provided in context, cross-reference it + — any artifact listed as create/update must be covered in the evaluation and + FAIL if the artifact was not produced 2. **Read relevant standards** using the selection matrix in AGENTS.md 3. **Evaluate all in-scope categories** - N/A only when the task genuinely cannot affect a category; if the task introduces new user-visible features or - structural changes then Requirements, Design Documentation, and Review - Management are always in scope and FAIL if the artifacts were not updated + structural changes then Requirements, Design Documentation, and Verification + Documentation are always in scope and FAIL if the artifacts were not updated; + Documentation (README/user guide) is always in scope for user-facing changes + and FAIL if not updated; Review Sets are always in scope when the + software item hierarchy changes (units or subsystems added, removed, or + reorganized) and FAIL if review-sets were not updated 4. **Validate tool compliance** using ReqStream, ReviewMark, and build tools 5. **Generate focused quality report** per the AGENTS.md reporting requirements - save to `.agent-logs/{agent-name}-{subject}-{unique-id}.md` and return the summary to the caller @@ -36,6 +45,7 @@ For each checklist item in the template below, record as `(PASS|FAIL|N/A) - {one # Quality Assessment Report **Result**: (SUCCEEDED|FAILED) +**Report**: `.agent-logs/quality-{subject}-{unique-id}.md` **Overall Grade**: (PASS|FAIL) ## Required Fixes (only when Result is FAILED) @@ -50,13 +60,13 @@ Priority-ordered list of issues that MUST be resolved for the next retry: - **Evaluated**: {List sections assessed and why} - **Skipped**: {One-line per skipped section with reason, e.g., "Design - Documentation: N/A - no design files modified"} + Documentation: N/A - no component behavior, structure, or interface changed"} ## Requirements Compliance: (PASS|FAIL|N/A) - Were requirements created/updated for all functional changes? - Were source filters applied for platform-specific requirements? -- Is requirements traceability maintained to tests? +- Is forward traceability from requirements to verification artifacts preserved? ## Design Documentation Compliance: (PASS|FAIL|N/A) @@ -80,7 +90,14 @@ Priority-ordered list of issues that MUST be resolved for the next retry: - Are cross-hierarchy test dependencies documented in design docs? - Do all tests pass? -## Review Management Compliance: (PASS|FAIL|N/A) +## Verification Documentation Compliance: (PASS|FAIL|N/A) + +- Were verification documents created/updated for all new or changed components? +- Do verification documents include all mandatory sections (Verification Approach, Test Environment, + Acceptance Criteria, Test Scenarios)? +- Is requirements-to-test coverage tracked via the ReqStream trace matrix (not embedded in verification docs)? + +## Review Sets Compliance: (PASS|FAIL|N/A) - Were review-sets updated for structural changes? - Is review scope appropriate for change magnitude? diff --git a/.github/agents/template-sync.agent.md b/.github/agents/template-sync.agent.md index fc5c62a..baf5fa8 100644 --- a/.github/agents/template-sync.agent.md +++ b/.github/agents/template-sync.agent.md @@ -21,26 +21,37 @@ 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 + system subtrees beneath them - **One group per system subtree** in `docs/design/`, `docs/verification/`, `docs/reqstream/` - each subtree and all its descendants is one group # Orchestration -For each group intersecting the requested scope, call a sub-agent with: +For Audit mode, call an **explore** sub-agent (built-in) per group. +For Sync, Scaffold, and Recreate modes, call a **general-purpose** sub-agent (built-in) per group. + +For each group intersecting the requested scope, call the appropriate sub-agent with: - **context**: - Group scope and template URL from the `# Reference Template` section in `AGENTS.md` - Applicable standards from the `# Standards Application` matrix in `AGENTS.md` for the file types in the group scope - Project-specific names substitute for placeholders at matching path depth - (e.g. `SystemName` → `{SystemName}`, `system-name` → `{system-name}`) + (e.g. `MySystem` → `{SystemName}`, `my-system` → `{system-name}`) - For files within `{system-name}/` subtrees in `docs/design/`, `docs/verification/`, and `docs/reqstream/`: consult `docs/design/introduction.md` to determine whether each item is a subsystem or unit, then select the appropriate template (`subsystem-name.*` or `unit-name.*`) regardless of the item's folder depth — do not infer item type from path depth alone - - If a template counterpart cannot be fetched, skip the file and report it + - If a file has no template counterpart, skip it and report it as + "No template found" — this is not a failure + - If a file appears in `repository-map.md` but its template cannot be fetched, + report Result: FAILED and list the affected files - **goal**: - Based on the given mode: - **Audit** - fetch each template counterpart; compare headings; report missing @@ -78,9 +89,25 @@ For each group intersecting the requested scope, call a sub-agent with: `TODO:` placeholders in YAML string values (e.g. `title:`, `justification:`) are content placeholders — always resolve them to real content; infer from README, related files, sibling docs, and path; if confident write directly; - if ambiguous offer 2–3 concrete options and ask the user; keep asking until - they answer - never leave a TODO or TEMPLATE-DIRECTIVE in the output unless - the user explicitly requests it + if ambiguous, **do not ask interactively** — return the unresolved questions + in the result so the orchestrator can ask the user and re-invoke; never leave + a TODO or TEMPLATE-DIRECTIVE in the output unless the user explicitly requests it + - Return results in this format for each file in the group: + + ```markdown + ### {file-path} + + - **Template**: {template path or "not found"} + - **Missing sections**: {list or "none"} + - **Heading depth issues**: {list or "none"} + - **Content format issues**: {list or "none"} *(Recreate only)* + - **Action**: (Reported | Sections added | Created | Rebuilt | No template found) + - **Unresolved Questions**: {list or "none"} + ``` + +If any sub-agent returns unresolved questions, collect them, ask the user, then +re-invoke the affected sub-agent(s) with the answers before assembling the final report. +If questions remain unresolved after asking the user, report Result: INCOMPLETE. Collect sub-agent results and assemble the final report. @@ -89,7 +116,8 @@ Collect sub-agent results and assemble the final report. ```markdown # Template Sync Report -**Result**: (SUCCEEDED|FAILED) +**Result**: (SUCCEEDED|FAILED|INCOMPLETE) +**Report**: `.agent-logs/template-sync-{subject}-{unique-id}.md` **Mode**: (Audit|Sync|Scaffold|Recreate) ## Files @@ -102,8 +130,13 @@ Collect sub-agent results and assemble the final report. - **Content format issues**: {list of sections where intra-section content did not match the template comment's prescribed format, or "none"} *(Recreate only)* - **Action**: (Reported | Sections added | Created | Rebuilt | No template found) +- **Unresolved Questions**: {list or "none"} ## Summary - **Conformant**: {count} | **Deviations**: {count} | **Updated**: {count} + +## Unknowns (only when Result is INCOMPLETE) + +- **Unresolved Questions**: {List each placeholder or ambiguity the user must resolve} ``` 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/coding-principles.md b/.github/standards/coding-principles.md index 9e67fbb..6797c61 100644 --- a/.github/standards/coding-principles.md +++ b/.github/standards/coding-principles.md @@ -3,11 +3,6 @@ name: Coding Principles description: Follow these standards when developing any software code. --- -# Coding Principles Standards - -This document defines universal coding principles and quality standards for software development within -Continuous Compliance environments. - # Core Principles ## Literate Coding @@ -20,10 +15,9 @@ All code MUST follow literate programming principles: matches design intent without reading the full codebase - **Logical Separation**: Complex functions use block comments to separate and describe logical steps within the implementation -- **Full Symbol Documentation**: ALL symbols have comprehensive documentation - because reviewers and auditors must verify every implementation detail, not - just the public interface - access-level specifics (public, protected, - private, internal, etc.) vary by language; see the language-specific standard +- **Full Symbol Documentation**: ALL symbols have comprehensive documentation — + not just the public interface, because reviewers and auditors must verify every + implementation detail. Access-level specifics vary by language; see the language-specific standard. - **Clarity Over Cleverness**: Code should be immediately understandable by team members ## API Documentation @@ -79,13 +73,13 @@ interface correctly without reading the implementation: ## Universal Anti-Patterns -- **Skip Literate Coding**: Don't skip literate programming comments - they are required for maintainability -- **Ignore Compiler Warnings**: Don't ignore compiler warnings - they exist for quality enforcement +- **Skip Literate Coding**: Don't skip literate programming comments +- **Ignore Compiler Warnings**: Don't ignore compiler warnings - **Hidden Dependencies**: Don't create untestable code with hidden dependencies - **Hidden Functionality**: Don't implement functionality without requirement traceability because untraced functionality cannot be validated during audits - **Monolithic Functions**: Don't write monolithic functions with multiple responsibilities -- **Overcomplicated Solutions**: Don't make solutions more complex than necessary - favor simplicity and clarity +- **Overcomplicated Solutions**: Don't make solutions more complex than necessary - **Premature Optimization**: Don't optimize for performance before establishing correctness - **Copy-Paste Programming**: Don't duplicate logic - extract common functionality into reusable components - **Magic Numbers**: Don't use unexplained constants - either name them or add clear comments diff --git a/.github/standards/csharp-language.md b/.github/standards/csharp-language.md index 6df39cd..ec05a25 100644 --- a/.github/standards/csharp-language.md +++ b/.github/standards/csharp-language.md @@ -12,9 +12,6 @@ Read these standards first before applying this standard: # API Documentation and Literate Coding Example -The example below demonstrates good XmlDoc API documentation combined with -literate coding comments. - ```csharp /// /// Converts a raw sensor reading into a validated measurement ready for downstream consumers. diff --git a/.github/standards/csharp-testing.md b/.github/standards/csharp-testing.md index 181de02..1f93b72 100644 --- a/.github/standards/csharp-testing.md +++ b/.github/standards/csharp-testing.md @@ -66,8 +66,6 @@ These are non-obvious v3 behaviors that differ from v2 or common assumptions: # Quality Checks -Before submitting C# tests, verify: - - [ ] All tests follow AAA pattern with clear section comments - [ ] Test names follow hierarchical naming pattern above - [ ] Each test verifies single, specific behavior (no shared state between tests) diff --git a/.github/standards/design-documentation.md b/.github/standards/design-documentation.md index 1fd9893..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 @@ -28,7 +30,8 @@ docs/design/ └── {package-name}.md # heading depth ## ``` -Subsystems may nest recursively. Each file's heading depth equals its folder depth under `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. # introduction.md (MANDATORY) @@ -36,15 +39,15 @@ 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` # System Design (MANDATORY) -Create `{system-name}.md` (`#` heading) and `{system-name}/` folder. All sections mandatory; -write "N/A - {justification}" rather than removing any section: +Create `{system-name}.md` (`#` heading) and `{system-name}/` folder: - **Architecture**: software items, relationships, and collaboration - **External Interfaces**: name, direction, format, constraints @@ -55,11 +58,7 @@ write "N/A - {justification}" rather than removing any section: # Subsystem Design (MANDATORY) -Place `{subsystem-name}.md` in the **parent** folder; create `{subsystem-name}/` for children. -**Important**: A file at `{system-name}/{name}.md` may be either a subsystem or a unit. Always -determine the correct classification from `docs/design/introduction.md` — folder depth does not -determine classification. -All sections mandatory; write "N/A - {justification}" rather than removing any section: +Place `{subsystem-name}.md` in the **parent** folder; create `{subsystem-name}/` for children: - **Overview**: responsibility, boundaries, contained units - **Interfaces**: what it exposes and consumes @@ -67,37 +66,46 @@ All sections mandatory; write "N/A - {justification}" rather than removing any s # Unit Design (MANDATORY) -Place `{unit-name}.md` in the **parent** folder. -**Important**: A file at `{system-name}/{name}.md` may be either a subsystem or a unit. Always -determine the correct classification from `docs/design/introduction.md` — folder depth does not -determine classification. -All sections mandatory; write "N/A - {justification}" rather than removing any section: +Place `{unit-name}.md` in the **parent** folder: - **Purpose**: single responsibility - **Data Model**: fields, properties, types, invariants (IEC 62304 §5.4.2) - **Key Methods**: name, purpose, algorithm, preconditions, postconditions, parameter types - **Error Handling**: detection and handling; what is propagated vs. handled locally -- **Interactions**: dependencies on other units/subsystems/OTS; who calls this unit +- **Dependencies**: other units, subsystems, OTS items, and shared packages used +- **Callers**: units or subsystems that call or consume this unit # OTS Integration Design (when OTS items exist) Create `docs/design/ots.md` (`#` heading) covering the overall OTS integration strategy. -For each OTS item, create `docs/design/ots/{ots-name}.md` (`##` heading) covering: -why chosen, which features/APIs used, integration patterns, version constraints. +For each OTS item, create `docs/design/ots/{ots-name}.md` (`##` heading) with sections: + +- **Purpose**: why chosen and what it provides to the local system +- **Features Used**: which specific features, APIs, or capabilities are consumed +- **Integration Pattern**: how it is consumed; initialization, configuration, disposal requirements # Shared Package Integration Design (when Shared Packages exist) Create `docs/design/shared.md` (`#` heading) covering the overall consumption strategy. -For each Shared Package, create `docs/design/shared/{package-name}.md` (`##` heading) covering: -which advertised features are consumed, integration pattern, configuration/initialization. +For each Shared Package, create `docs/design/shared/{package-name}.md` (`##` heading) with sections: + +- **Advertised Features Consumed**: which features the local system relies on +- **Integration Pattern**: how the package is referenced, initialized, and consumed +- **Assumptions**: any assumptions the local system makes about the package's behavior # Writing Guidelines - 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 @@ -108,7 +116,7 @@ which advertised features are consumed, integration pattern, configuration/initi - [ ] System design includes all mandatory sections (Architecture, External Interfaces, Dependencies, Risk Control Measures, Data Flow, Design Constraints) - [ ] Subsystem design includes all mandatory sections (Overview, Interfaces, Design) -- [ ] Unit design includes all mandatory sections (Purpose, Data Model, Key Methods, Error Handling, Interactions) +- [ ] Unit design includes all mandatory sections (Purpose, Data Model, Key Methods, Error Handling, Dependencies, Callers) - [ ] Non-applicable mandatory sections contain "N/A - {justification}" - [ ] `docs/design/ots.md` and `docs/design/ots/{ots-name}.md` exist when OTS items are present - [ ] `docs/design/shared.md` and `docs/design/shared/{package-name}.md` exist when Shared Packages are present diff --git a/.github/standards/reqstream-usage.md b/.github/standards/reqstream-usage.md index 0b30dfa..2371164 100644 --- a/.github/standards/reqstream-usage.md +++ b/.github/standards/reqstream-usage.md @@ -25,8 +25,8 @@ docs/reqstream/ │ ├── platform-requirements.yaml # Platform support requirements │ ├── {subsystem-name}.yaml # Subsystem requirements │ ├── {subsystem-name}/ # Subsystem folder (kebab-case); may nest recursively -│ │ ├── {child-subsystem}.yaml # Child subsystem requirements -│ │ ├── {child-subsystem}/ # Child subsystem folder +│ │ ├── {subsystem-name}.yaml # Child subsystem requirements +│ │ ├── {subsystem-name}/ # Child subsystem folder │ │ └── {unit-name}.yaml # Unit requirements │ └── {unit-name}.yaml # System-level unit requirements ├── ots/ # OTS items appear as a distinct section in reports @@ -35,7 +35,11 @@ docs/reqstream/ └── {package-name}.yaml # Requirements for Shared Package dependencies ``` -Local items have matching paths across `docs/reqstream/`, `docs/design/`, and `docs/verification/`. +Local items have matching relative paths across `docs/reqstream/`, `docs/design/`, and `docs/verification/`: + +- Requirements: `{system-name}[/{subsystem-name}...]/{item-name}.yaml` +- Design: `{system-name}[/{subsystem-name}...]/{item-name}.md` +- Verification: `{system-name}[/{subsystem-name}...]/{item-name}.md` # Requirements File Format @@ -48,12 +52,12 @@ folder depth does not determine whether an item is a subsystem or unit. Valid section nestings (names in `{braces}` are placeholders): ```text -{System} Requirements # system-level requirements -├── {Subsystem} Requirements # root subsystem requirements -│ ├── {Subsystem} Requirements # nested subsystem (may recurse) -│ │ └── {Unit} Requirements # unit under a nested subsystem -│ └── {Unit} Requirements # unit under a root subsystem -└── {Unit} Requirements # unit directly under the system +{SystemName} Requirements # system-level requirements +├── {SubsystemName} Requirements # root subsystem requirements +│ ├── {SubsystemName} Requirements # nested subsystem (may recurse) +│ │ └── {UnitName} Requirements # unit under a nested subsystem +│ └── {UnitName} Requirements # unit under a root subsystem +└── {UnitName} Requirements # unit directly under the system OTS Software Requirements # OTS root section (fixed title) └── {OtsName} Requirements # requirements for one OTS item Shared Package Requirements # shared package root section (fixed title) diff --git a/.github/standards/reviewmark-usage.md b/.github/standards/reviewmark-usage.md index 17952ed..bc73da6 100644 --- a/.github/standards/reviewmark-usage.md +++ b/.github/standards/reviewmark-usage.md @@ -21,101 +21,122 @@ 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 -# Review-Set Organization +# Context Files -Organize review-sets using these standard patterns to ensure comprehensive coverage -while keeping each review manageable in scope: +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. -**Naming conventions**: See `software-items.md` - kebab-case placeholders -(e.g., `{system-name}`) are always kebab-case; cased placeholders -(e.g., `{SystemName}`) follow your language's convention. +| 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 | -## `Purpose` Review (only one per repository) +# Review-Set Organization + +**Naming conventions**: Placeholders in documentation, requirements, design, and +verification file paths are kebab-case (e.g., `{system-name}`). Placeholders in +source and test file paths may use the casing conventional for the project's +source language or repository layout (e.g., `{SystemName}`). Review-set name +placeholders are always PascalCase (e.g., `{SystemName}`). -Reviews user-facing capabilities and system promises: +## `Purpose` Review (only one per repository) -- **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` - - Design introduction: `docs/design/introduction.md` - - System design: `docs/design/{system-name}.md` -## `{System}-Architecture` Review (one per system) +## `Decomposition` Review (only one per repository) -Reviews system architecture and operational validation: +- **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` + - SysML2 model: `docs/sysml2/**/*.sysml` +- **Context Files**: `README.md`, `docs/user_guide/**/*.md` + +## `{SystemName}-Architecture` Review (one per system) - **Purpose**: Proves that the system is designed and tested to satisfy its requirements -- **Title**: "Review that {System} Architecture Satisfies Requirements" +- **Title**: "Review that {SystemName} Architecture Satisfies Requirements" - **Scope**: Excludes subsystem and unit files, relying on system-level design to describe what subsystems and units it uses - **File Path Patterns**: @@ -125,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` -## `{System}-Design` Review (one per system) - -Reviews architectural and design consistency: +## `{SystemName}-Design` Review (one per system) - **Purpose**: Proves the system design is consistent and complete -- **Title**: "Review that {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` @@ -142,65 +162,59 @@ Reviews architectural and design consistency: - OTS overview: `docs/design/ots.md` _(only if OTS items exist)_ - Shared Package overview: `docs/design/shared.md` _(only if Shared Package items exist)_ -## `{System}-Verification` Review (one per system) - -Reviews verification completeness and consistency: +## `{SystemName}-Verification` Review (one per system) - **Purpose**: Proves the system verification design is consistent and covers all requirements -- **Title**: "Review that {System} Verification is Consistent and Complete" +- **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` - OTS overview: `docs/verification/ots.md` _(only if OTS items exist)_ - Shared Package overview: `docs/verification/shared.md` _(only if Shared Package items exist)_ -## `{System}-AllRequirements` Review (one per system) - -Reviews requirements quality and traceability: +## `{SystemName}-AllRequirements` Review (one per system) - **Purpose**: Proves the requirements are consistent and complete -- **Title**: "Review that All {System} Requirements are 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` -## `{System}-{Subsystem[-Child...]}` Review (one per subsystem at any depth) - -Reviews subsystem architecture and interfaces: +## `{SystemName}-{SubsystemName}[-{SubsystemName}...]` Review (one per subsystem at any depth) - **Purpose**: Proves that the subsystem is designed and tested to satisfy its requirements -- **Title**: "Review that {System} {Subsystem} Satisfies Subsystem Requirements" +- **Title**: "Review that {SystemName} {SubsystemName} Satisfies Subsystem Requirements" - **Scope**: Excludes units under the subsystem, relying on subsystem design to describe what units it uses - **File Path Patterns**: - - Requirements: `docs/reqstream/{system-name}/.../{subsystem-name}.yaml` - - Design: `docs/design/{system-name}/.../{subsystem-name}.md` - - Verification design: `docs/verification/{system-name}/.../{subsystem-name}.md` - - Tests: `test/{SystemName}.Tests/.../{SubsystemName}/{SubsystemName}Tests.{ext}` + - Requirements: `docs/reqstream/{system-name}[/{subsystem-name}...]/{subsystem-name}.yaml` + - 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` -## `{System}-{Subsystem[-Child...]}-{Unit}` Review (one per unit) - -Reviews individual software unit implementation: +## `{SystemName}-{SubsystemName}[-{SubsystemName}...]-{UnitName}` Review (one per unit) - **Purpose**: Proves the unit is designed, implemented, and tested to satisfy its requirements -- **Title**: "Review that {System} {Subsystem} {Unit} Implementation is Correct" +- **Title**: "Review that {SystemName} {SubsystemName} {UnitName} Implementation is Correct" - **Scope**: Complete unit review including all artifacts - **File Path Patterns**: - - Requirements: `docs/reqstream/{system-name}/.../{unit-name}.yaml` - - Design: `docs/design/{system-name}/.../{unit-name}.md` - - Verification design: `docs/verification/{system-name}/.../{unit-name}.md` - - Source: `src/{SystemName}/.../{UnitName}.{ext}` - - Tests: `test/{SystemName}.Tests/.../{UnitName}Tests.{ext}` + - Requirements: `docs/reqstream/{system-name}[/{subsystem-name}...]/{unit-name}.yaml` + - Design: `docs/design/{system-name}[/{subsystem-name}...]/{unit-name}.md` + - Verification design: `docs/verification/{system-name}[/{subsystem-name}...]/{unit-name}.md` + - Source (C# example): `src/{SystemName}[/{SubsystemName}...]/{UnitName}.cs` + - 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 @@ -213,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 @@ -228,21 +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 -- [ ] Purpose review-set includes README.md, user guide, system requirements, design introduction, and system design files -- [ ] System-level reviews follow hierarchical scope principle (exclude subsystem/unit details) -- [ ] Subsystem reviews follow hierarchical scope principle (exclude unit source code) -- [ ] Only unit reviews include actual source code files -- [ ] Architecture review-sets include system verification design alongside system design -- [ ] Design review-sets include all system design files -- [ ] Verification review-sets include all system verification files -- [ ] Subsystem review-sets include subsystem verification design -- [ ] Unit review-sets include unit verification design -- [ ] OTS review-sets include OTS requirements, integration design, and verification evidence -- [ ] Shared Package review-sets include Shared Package requirements, integration design, and verification evidence - [ ] 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 07c4013..3514228 100644 --- a/.github/standards/software-items.md +++ b/.github/standards/software-items.md @@ -3,12 +3,6 @@ name: Software Items description: Follow these standards when categorizing software components. --- -# Software Items Definition Standards - -This document defines standards for categorizing software items within -Continuous Compliance environments because proper categorization determines -requirements management approach, testing strategy, and review scope. - # Software Item Categories Categorize all software into six primary groups: @@ -40,17 +34,28 @@ Categorize all software into six primary groups: # Naming Conventions in File Path Patterns -Two placeholder styles appear in path patterns across these standards: +Three placeholder forms appear in path patterns across these standards: -- **Kebab-case** (`{system-name}`, `{unit-name}`): always kebab-case - - used in documentation and requirements paths -- **Cased** (`{SystemName}`, `{UnitName}`): follow your language's convention - - `PascalCase` for C#/Java, `snake_case` for C++/Python - - used in source and test file paths +- **Kebab-case** (`{system-name}`, `{unit-name}`): always kebab-case — + documentation and requirements file paths +- **PascalCase IDs** (`{SystemName}`, `{UnitName}`): always PascalCase — + requirements IDs, ReviewMark IDs, and other documentation identifiers +- **Language-cased** (`{SystemName}` or `{system_name}`): follow your language's + convention — `PascalCase` for C#/Java, `snake_case` for C++/Python — + source and test file/folder names -# Categorization Guidelines +## Nesting Depth Notation + +Subsystems nest to any depth. Patterns use bracket-ellipsis to express this without +enumerating levels — `[/{subsystem-name}...]` in paths, `[-{SubsystemName}...]` in +dash-separated IDs. Examples covering all three forms: -Choose the appropriate category based on scope and testability: +- `{SystemName}[-{SubsystemName}...]-{UnitName}-Feature` (PascalCase ID) +- `docs/design/{system-name}[/{subsystem-name}...]/{unit-name}.md` (kebab-case doc path) +- `src/{SystemName}[/{SubsystemName}...]/{UnitName}.cs` (C# source path) +- `src/{system_name}[/{subsystem_name}...]/{unit_name}.cpp` (C++/Python source path) + +# Categorization Guidelines ## Software Package @@ -89,7 +94,7 @@ Choose the appropriate category based on scope and testability: - Examples: System.Text.Json, Entity Framework, third-party APIs - **Artifact locations** (OTS items have no internal design documentation): - Requirements: `docs/reqstream/ots/{ots-name}.yaml` - - Design: `docs/design/ots/{ots-name}.md` (integration/usage design - how the local system uses this item) + - Design: `docs/design/ots/{ots-name}.md` (integration/usage design) - Verification: `docs/verification/ots/{ots-name}.md` - These folders sit parallel to system folders (not inside any system folder) - System design documentation records which OTS items each system depends on @@ -109,10 +114,9 @@ Choose the appropriate category based on scope and testability: downstream integration tests that transitively prove the advertised features are functional - **Artifact locations** (no internal design documentation in the consuming repository): - Requirements: `docs/reqstream/shared/{package-name}.yaml` - - Design: `docs/design/shared/{package-name}.md` (integration/usage design - which features are consumed and how) + - Design: `docs/design/shared/{package-name}.md` (integration/usage design) - Verification: `docs/verification/shared/{package-name}.md` - These folders sit parallel to system and OTS folders -- System design documentation records which Shared Packages each system depends on # Software Item Artifact Model @@ -126,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/standards/technical-documentation.md b/.github/standards/technical-documentation.md index 0dc4455..23893bd 100644 --- a/.github/standards/technical-documentation.md +++ b/.github/standards/technical-documentation.md @@ -6,9 +6,6 @@ globs: ["docs/**/*.md", "README.md", "!docs/**/generated/**"] # Technical Documentation Standards -This document defines standards for technical documentation within Continuous -Compliance environments. - # Core Principles Technical documentation serves as compliance evidence and must be structured @@ -40,8 +37,7 @@ docs/{collection}/ Without `title.txt` and `definition.yaml` the pipeline cannot generate the document. When creating a new document collection, create these three files together and use -the existing collections under `docs/` as templates - they share a consistent -structure across all collections. +the existing collections under `docs/` as templates. The `generated/` folder is **never committed** to the repository - it is created locally and in CI by the build pipeline. Do not flag its absence as a conformance @@ -85,8 +81,7 @@ elsewhere causes duplicate sections in the compiled PDF. ## Document Ordering -List documents in logical reading order in Pandoc configuration because -readers need coherent information flow from general to specific topics. +List documents in logical reading order in `definition.yaml`. ## Heading Depth Rule (MANDATORY) @@ -110,15 +105,10 @@ available - keep internal structure flat to avoid excessive nesting. Write technical documentation for clarity and compliance verification: - **Clear and Concise**: Use direct language and avoid unnecessary complexity. - Regulatory reviewers must understand content quickly. -- **Structured Sections**: Use consistent heading hierarchy and section - organization. Enables automated processing and review. -- **Specific Examples**: Include concrete examples with actual values rather - than placeholders. Supports implementation verification. +- **Structured Sections**: Use consistent heading hierarchy and section organization. +- **Specific Examples**: Include concrete examples with actual values rather than placeholders. - **Current Information**: Keep documentation synchronized with code changes. - Outdated documentation invalidates compliance evidence. -- **Traceable Content**: Link documentation to requirements and implementation - where applicable for audit trails. +- **Traceable Content**: Link documentation to requirements and implementation where applicable. ## References Sections @@ -138,26 +128,16 @@ Instead use **verbal references** - plain prose that identifies the target by na > > Refer to the *System Requirements* document for the full specification. -Verbal references are readable by both AI agents and humans in any rendering environment. - # Markdown Format Requirements -Markdown documentation in this repository must follow the formatting standards -defined in `.markdownlint-cli2.yaml` (subject to any exclusions configured there) -for consistency and professional presentation: - -- **120 Character Line Limit**: Keep lines 120 characters or fewer for readability. - Break long lines naturally at punctuation or logical breaks. -- **No Trailing Whitespace**: Remove all trailing spaces and tabs from line - endings to prevent formatting inconsistencies. -- **Blank Lines Around Headings**: Include a blank line both before and after - each heading to improve document structure and readability. -- **Blank Lines Around Lists**: Include a blank line both before and after - numbered and bullet lists to ensure proper rendering and visual separation. -- **ATX-Style Headers**: Use `#` syntax for headers instead of underline style - for consistency across all documentation. -- **Consistent List Indentation**: Use 2-space indentation for nested list - items to maintain uniform formatting. +Follow `.markdownlint-cli2.yaml` formatting standards: + +- **120 Character Line Limit**: Keep lines 120 characters or fewer; break at punctuation or logical breaks. +- **No Trailing Whitespace**: Remove all trailing spaces and tabs. +- **Blank Lines Around Headings**: Include a blank line before and after each heading. +- **Blank Lines Around Lists**: Include a blank line before and after numbered and bullet lists. +- **ATX-Style Headers**: Use `#` syntax, not underline style. +- **Consistent List Indentation**: Use 2-space indentation for nested list items. # Auto-Generated Content (CRITICAL) @@ -168,8 +148,6 @@ build outputs that are overwritten on every CI run: respective `docs/` sections, or in `docs/generated/` for final release artifacts - **Source Modification**: Update source files (requirements YAML, `.reviewmark.yaml`, tool configuration) instead of generated output -- **Tool Integration**: Generated content integrates with CI/CD pipelines and - manual changes disrupt automation # README.md Best Practices @@ -192,20 +170,12 @@ Structure README.md for both human readers and AI agent processing: - **Code Block Languages**: Specify language for syntax highlighting and tool processing - **Clear Prerequisites**: List exact version requirements and dependencies -## Quality Guidelines - -- **Scannable Structure**: Use bullet points, headings, and short paragraphs -- **Current Examples**: Verify all code examples work with current version -- **Link Validation**: Ensure all external links are accessible and current -- **Consistent Tone**: Professional, helpful tone appropriate for technical audience - # Quality Checks Before submitting technical documentation, verify: - [ ] Documentation organized under `docs/` following standard folder structure - [ ] Pandoc collections include `introduction.md` with Purpose and Scope sections -- [ ] Content follows clear and concise writing guidelines with specific examples - [ ] No modifications made to auto-generated markdown files in compliance folders - [ ] README.md includes all required sections with absolute URLs and concrete examples - [ ] Documentation integrated into ReviewMark review-sets for formal review diff --git a/.github/standards/testing-principles.md b/.github/standards/testing-principles.md index 73974ff..917463e 100644 --- a/.github/standards/testing-principles.md +++ b/.github/standards/testing-principles.md @@ -3,11 +3,6 @@ name: Testing Principles description: Follow these standards when developing any software tests. --- -# Testing Principles Standards - -This document defines universal testing principles and quality standards for test development within -Continuous Compliance environments. - # Test Dependency Boundaries (MANDATORY) Respect software item hierarchy boundaries to ensure review-sets can validate proper architectural scope. diff --git a/.github/standards/verification-documentation.md b/.github/standards/verification-documentation.md index f3d950e..494e40f 100644 --- a/.github/standards/verification-documentation.md +++ b/.github/standards/verification-documentation.md @@ -28,7 +28,8 @@ docs/verification/ └── {package-name}.md # heading depth ## ``` -Subsystems may nest recursively. Each file's heading depth equals its folder depth under `docs/verification/`. +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. # introduction.md (MANDATORY) @@ -41,56 +42,44 @@ Must include: # System Verification Design (MANDATORY) -Create `{system-name}.md` (`#` heading) and `{system-name}/` folder. All sections mandatory; -write "N/A - {justification}" rather than removing any section: +Create `{system-name}.md` (`#` heading) and `{system-name}/` folder: -- **Verification Strategy**: test types (unit, integration, end-to-end), framework, project structure +- **Verification Approach**: test types (unit, integration, end-to-end), framework, project structure - **Test Environment**: OS, runtime, external services, files, or configuration required - **Acceptance Criteria**: what constitutes a passing system test (IEC 62304 §5.7.2) -- **System-Level Test Scenarios**: named scenarios for each system requirement -- **Requirements Coverage**: requirement → scenario(s) → test method(s) mapping +- **Test Scenarios**: named scenarios for each system requirement # Subsystem Verification Design (MANDATORY) -Place `{subsystem-name}.md` in the **parent** folder; create `{subsystem-name}/` for children. -**Important**: A file at `{system-name}/{name}.md` may be either a subsystem or a unit. Always -determine the correct classification from `docs/design/introduction.md` — folder depth does not -determine classification. -All sections mandatory; write "N/A - {justification}" rather than removing any section: +Place `{subsystem-name}.md` in the **parent** folder; create `{subsystem-name}/` for children: -- **Verification Strategy**: integration test approach and mocking at subsystem boundary +- **Verification Approach**: integration test approach and mocking at subsystem boundary - **Test Environment**: any environment setup beyond the standard test runner - **Acceptance Criteria**: what constitutes a passing subsystem test (IEC 62304 §5.5.2) - **Test Scenarios**: named scenarios including boundary conditions, error paths, and normal operation -- **Requirements Coverage**: requirement → scenario(s) → test method(s) mapping # Unit Verification Design (MANDATORY) -Place `{unit-name}.md` in the **parent** folder. -**Important**: A file at `{system-name}/{name}.md` may be either a subsystem or a unit. Always -determine the correct classification from `docs/design/introduction.md` — folder depth does not -determine classification. -All sections mandatory; write "N/A - {justification}" rather than removing any section: +Place `{unit-name}.md` in the **parent** folder: - **Verification Approach**: what is mocked/stubbed and why; injected vs. real dependencies - **Test Environment**: any environment setup beyond the standard test runner - **Acceptance Criteria**: what constitutes passing unit tests (IEC 62304 §5.5.2) - **Test Scenarios**: named scenarios including boundary values, error paths, and normal operation -- **Requirements Coverage**: requirement → scenario(s) → test method(s) mapping # OTS Verification Evidence (when OTS items exist) Create `docs/verification/ots.md` (`#` heading) covering the overall OTS verification strategy. For each OTS item, create `docs/verification/ots/{ots-name}.md` (`##` heading) covering: -verification approach (self-validation, integration tests, vendor evidence) and requirements coverage. +verification approach (self-validation, integration tests, vendor evidence). # Shared Package Verification Evidence (when Shared Packages exist) Create `docs/verification/shared.md` (`#` heading) covering the overall Shared Package verification strategy. For each Shared Package, create `docs/verification/shared/{package-name}.md` (`##` heading) covering: -verification approach and requirements coverage. +verification approach. # Writing Guidelines @@ -103,14 +92,10 @@ verification approach and requirements coverage. - [ ] `introduction.md` includes Companion Artifact Structure - [ ] Each file's heading depth matches its folder depth - [ ] All folders use kebab-case mirroring source structure -- [ ] System verification includes all mandatory sections (Verification Strategy, Test Environment, - Acceptance Criteria, System-Level Test Scenarios, Requirements Coverage) -- [ ] Subsystem verification includes all mandatory sections (Verification Strategy, Test Environment, - Acceptance Criteria, Test Scenarios, Requirements Coverage) -- [ ] Unit verification includes all mandatory sections (Verification Approach, Test Environment, - Acceptance Criteria, Test Scenarios, Requirements Coverage) +- [ ] Each system/subsystem/unit file includes all mandatory sections (Verification Approach, + Test Environment, Acceptance Criteria, Test Scenarios) - [ ] Non-applicable mandatory sections contain "N/A - {justification}" -- [ ] Every requirement is mapped to at least one named test scenario +- [ ] Requirements-to-test coverage is tracked via the ReqStream trace matrix, not in these documents - [ ] `docs/verification/ots.md` and `docs/verification/ots/{ots-name}.md` exist when OTS items are present - [ ] `docs/verification/shared.md` and `docs/verification/shared/{package-name}.md` exist when Shared Packages are present - [ ] Documents are integrated into ReviewMark review-sets diff --git a/AGENTS.md b/AGENTS.md index 94e04a4..a69ca64 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,7 @@ # Project Overview -- **name**: ReqStream +- **project-name**: ReqStream +- **organization**: DEMA Consulting - **description**: A .NET command-line tool for managing software requirements in YAML format, providing validation, linting, traceability, and test-mapping capabilities - **languages**: C# @@ -18,6 +19,7 @@ │ ├── requirements_doc/ │ ├── requirements_report/ │ ├── reqstream/ +│ ├── sysml2/ │ ├── user_guide/ │ └── verification/ ├── src/ @@ -35,16 +37,18 @@ commit messages, and reports). This repository follows a reference template for structure and file conventions. -- **Template URL**: `https://github.com/demaconsulting/Agents/raw/refs/heads/template` +- **template-url**: `https://github.com/demaconsulting/Agents/raw/refs/heads/template` - **Repository map**: `{template-url}/repository-map.md` - **Template files**: `{template-url}/{file-path}` for files described in the map # 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 @@ -59,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. @@ -75,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. @@ -85,12 +91,15 @@ The default agent should handle simple, straightforward tasks directly. Delegate to specialized agents only for specific scenarios: - **Pre-PR lint cleanup** (fix all lint issues before pull request) → Call the lint-fix agent -- **Light development work** (small fixes, simple features) → Call the developer agent +- **Scoped fixes with no new user-visible behavior** (PR review comments, doc + corrections, known bug fixes with defined root cause) → Call the developer agent - **Light quality checking** (basic validation) → Call the quality agent -- **Formal feature implementation** (complex, multi-step) → Call the implementation agent -- **Formal bug resolution** (complex debugging, systematic fixes) → Call the implementation agent +- **Any change introducing new user-visible behavior** (features, enhancements, + new commands or options) → Call the implementation agent +- **Formal bug resolution** (complex debugging, unknown root cause) → Call the implementation agent - **Formal reviews** (compliance verification, detailed analysis) → Call the formal-review agent - **Structural audit**: (repository layout vs. template) → Call the template-sync agent +- **Implementation planning only** (review a plan before committing to implementation) → Call the planning agent # Agent Reporting (Specialized Agents Must Follow) @@ -99,16 +108,16 @@ Specialized agents MUST generate a completion report: 1. Save to `.agent-logs/{agent-name}-{subject}-{unique-id}.md` where `{subject}` is a kebab-case task summary (max 5 words) and `{unique-id}` is a short unique suffix (e.g., 8-char hex or timestamp) -2. Start with `**Result**: (SUCCEEDED|FAILED)` as the first metadata field +2. Start with `**Result**: (SUCCEEDED|FAILED|INCOMPLETE)` as the first metadata field 3. Include the agent-specific report sections defined in each agent's prompt 4. Return the summary to the caller Result semantics for orchestrator decision-making: -- **SUCCEEDED**: Work completed and all applicable quality gates met +- **SUCCEEDED**: Work completed and all quality gates applicable to that agent's scope met - **FAILED**: Work could not be completed or quality gates not met - **INCOMPLETE**: Work cannot proceed without information only the user can - provide (implementation agent only) + provide (implementation, planning, and template-sync agents) # Formatting (After Making Changes) @@ -126,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) From 32e1e3439a2e30f0277605a4583212164a503528 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Thu, 9 Jul 2026 13:32:36 -0400 Subject: [PATCH 2/5] Add SysML2 architecture model support and update documentation - Scaffold docs/sysml2/model and docs/sysml2/views for the ReqStream system, its 5 subsystems (Cli, Modeling, Tracing, SelfTest, Utilities), 15 units, and the 3 library OTS dependencies (YamlDotNet, FileSystemGlobbing, TestResults) modeled as SysML2 part defs. - Wire demaconsulting.sysml2tools.tool into .config/dotnet-tools.json, .versionmark.yaml, lint.ps1, and .github/workflows/build.yaml (self- validation and SVG render steps, tool version capture). - Rework docs/design/introduction.md to replace the hand-maintained ASCII software structure tree with the generated SoftwareStructureView diagram, and embed per-subsystem/unit diagrams across docs/design/reqstream.md and docs/design/reqstream/**. - Rework .reviewmark.yaml per the updated reviewmark-usage.md standard: split Purpose/Decomposition review-sets, add context blocks to all ReqStream-* review-sets, and add docs/sysml2/**/*.sysml to needs-review. --- .config/dotnet-tools.json | 6 + .github/workflows/build.yaml | 16 ++- .reviewmark.yaml | 114 +++++++++++++++++- .versionmark.yaml | 5 + docs/design/introduction.md | 33 ++--- docs/design/reqstream.md | 2 + docs/design/reqstream/cli.md | 2 + docs/design/reqstream/cli/context.md | 2 + docs/design/reqstream/modeling.md | 2 + docs/design/reqstream/modeling/lint-issue.md | 2 + docs/design/reqstream/modeling/load-result.md | 2 + docs/design/reqstream/modeling/requirement.md | 2 + .../reqstream/modeling/requirements-loader.md | 2 + .../design/reqstream/modeling/requirements.md | 2 + docs/design/reqstream/modeling/section.md | 2 + docs/design/reqstream/program.md | 2 + docs/design/reqstream/self-test.md | 2 + docs/design/reqstream/self-test/validation.md | 2 + docs/design/reqstream/tracing.md | 2 + docs/design/reqstream/tracing/trace-matrix.md | 2 + docs/design/reqstream/utilities.md | 2 + .../reqstream/utilities/glob-matcher.md | 2 + .../reqstream/utilities/path-helpers.md | 2 + .../utilities/temporary-directory.md | 2 + docs/sysml2/model/ots.sysml | 27 +++++ docs/sysml2/model/reqstream.sysml | 29 +++++ docs/sysml2/model/reqstream/cli.sysml | 12 ++ docs/sysml2/model/reqstream/cli/context.sysml | 11 ++ docs/sysml2/model/reqstream/modeling.sysml | 17 +++ .../model/reqstream/modeling/lint-issue.sysml | 11 ++ .../reqstream/modeling/load-result.sysml | 11 ++ .../reqstream/modeling/requirement.sysml | 11 ++ .../modeling/requirements-loader.sysml | 11 ++ .../reqstream/modeling/requirements.sysml | 11 ++ .../model/reqstream/modeling/section.sysml | 11 ++ docs/sysml2/model/reqstream/program.sysml | 11 ++ docs/sysml2/model/reqstream/self-test.sysml | 12 ++ .../reqstream/self-test/validation.sysml | 11 ++ docs/sysml2/model/reqstream/tracing.sysml | 12 ++ .../reqstream/tracing/trace-matrix.sysml | 11 ++ docs/sysml2/model/reqstream/utilities.sysml | 13 ++ .../reqstream/utilities/glob-matcher.sysml | 11 ++ .../reqstream/utilities/path-helpers.sysml | 11 ++ .../utilities/temporary-directory.sysml | 11 ++ docs/sysml2/views/design-views.sysml | 34 ++++++ docs/verification/introduction.md | 1 + lint.ps1 | 7 +- 47 files changed, 488 insertions(+), 31 deletions(-) create mode 100644 docs/sysml2/model/ots.sysml create mode 100644 docs/sysml2/model/reqstream.sysml create mode 100644 docs/sysml2/model/reqstream/cli.sysml create mode 100644 docs/sysml2/model/reqstream/cli/context.sysml create mode 100644 docs/sysml2/model/reqstream/modeling.sysml create mode 100644 docs/sysml2/model/reqstream/modeling/lint-issue.sysml create mode 100644 docs/sysml2/model/reqstream/modeling/load-result.sysml create mode 100644 docs/sysml2/model/reqstream/modeling/requirement.sysml create mode 100644 docs/sysml2/model/reqstream/modeling/requirements-loader.sysml create mode 100644 docs/sysml2/model/reqstream/modeling/requirements.sysml create mode 100644 docs/sysml2/model/reqstream/modeling/section.sysml create mode 100644 docs/sysml2/model/reqstream/program.sysml create mode 100644 docs/sysml2/model/reqstream/self-test.sysml create mode 100644 docs/sysml2/model/reqstream/self-test/validation.sysml create mode 100644 docs/sysml2/model/reqstream/tracing.sysml create mode 100644 docs/sysml2/model/reqstream/tracing/trace-matrix.sysml create mode 100644 docs/sysml2/model/reqstream/utilities.sysml create mode 100644 docs/sysml2/model/reqstream/utilities/glob-matcher.sysml create mode 100644 docs/sysml2/model/reqstream/utilities/path-helpers.sysml create mode 100644 docs/sysml2/model/reqstream/utilities/temporary-directory.sysml create mode 100644 docs/sysml2/views/design-views.sysml 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/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7122ee9..1ce03bd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -478,7 +478,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 === @@ -737,6 +737,20 @@ jobs: shell: bash run: mkdir -p docs/design/generated + - name: Run SysML2Tools self-validation + run: > + dotnet sysml2tools + --validate + --results artifacts/sysml2tools-self-validation.trx + + - name: Render Software Structure diagrams with SysML2Tools + shell: pwsh + run: > + dotnet sysml2tools render + --output docs/design/generated --format svg + 'docs/sysml2/model/**/*.sysml' + 'docs/sysml2/views/design-views.sysml' + - name: Generate Design HTML with Pandoc shell: bash run: > diff --git a/.reviewmark.yaml b/.reviewmark.yaml index 3af49e1..a07261c 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -13,6 +13,7 @@ needs-review: - "docs/design/**/*.md" # Design documentation files - "docs/verification/**/*.md" # Verification documentation files - "docs/user_guide/**/*.md" # User guide documentation + - "docs/sysml2/**/*.sysml" # SysML2 architecture model - "!**/obj/**" # Exclude build output - "!**/bin/**" # Exclude build output - "!node_modules/**" # Exclude npm dependencies @@ -26,21 +27,38 @@ evidence-source: type: url location: https://raw.githubusercontent.com/demaconsulting/ReqStream/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: Purpose - title: Review that Advertised Features Match System Design + title: Review that README and User Guide are Coherent and Complete + context: + - "!docs/design/introduction.md" # exclude design intro from user-facing review paths: - "README.md" # user-facing documentation - "docs/user_guide/**/*.md" # user guide - - "docs/reqstream/reqstream.yaml" # system requirements + + # Decomposition Review (only one per repository) + - id: Decomposition + title: Review that ReqStream 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/reqstream.md" # system design + - "docs/sysml2/**/*.sysml" # SysML2 model (authoritative structure) # ReqStream - Specials - id: ReqStream-Architecture title: Review that ReqStream Architecture Satisfies Requirements + context: + - "README.md" + - "docs/user_guide/**/*.md" paths: - "docs/reqstream/reqstream.yaml" # system requirements - "docs/design/introduction.md" # design introduction @@ -53,6 +71,8 @@ reviews: - id: ReqStream-Design title: Review that ReqStream Design is Consistent and Complete + context: + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream.yaml" # system requirements - "docs/reqstream/reqstream/platform-requirements.yaml" # platform requirements @@ -68,6 +88,9 @@ reviews: - id: ReqStream-AllRequirements title: Review that All ReqStream Requirements are Complete + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "requirements.yaml" # root requirements file - "docs/reqstream/reqstream.yaml" # system requirements file @@ -77,6 +100,9 @@ reviews: # ReqStream - Program - id: ReqStream-Program title: Review that ReqStream Program Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream/program.yaml" # unit requirements - "docs/design/reqstream/program.md" # unit design @@ -87,6 +113,9 @@ reviews: # ReqStream - Cli - id: ReqStream-Cli title: Review that ReqStream Cli Satisfies Subsystem Requirements + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream/cli.yaml" # subsystem requirements - "docs/design/reqstream/cli.md" # subsystem design @@ -95,6 +124,11 @@ reviews: - id: ReqStream-Cli-Context title: Review that ReqStream Cli Context Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/cli.md" + - "docs/reqstream/reqstream/cli.yaml" paths: - "docs/reqstream/reqstream/cli/context.yaml" # unit requirements - "docs/design/reqstream/cli/context.md" # unit design @@ -105,6 +139,9 @@ reviews: # ReqStream - Modeling - id: ReqStream-Modeling title: Review that ReqStream Modeling Satisfies Subsystem Requirements + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream/modeling.yaml" # subsystem requirements - "docs/design/reqstream/modeling.md" # subsystem design @@ -113,6 +150,11 @@ reviews: - id: ReqStream-Modeling-LintIssue title: Review that ReqStream Modeling LintIssue Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/modeling.md" + - "docs/reqstream/reqstream/modeling.yaml" paths: - "docs/reqstream/reqstream/modeling/lint-issue.yaml" # unit requirements - "docs/design/reqstream/modeling/lint-issue.md" # unit design @@ -122,6 +164,11 @@ reviews: - id: ReqStream-Modeling-LoadResult title: Review that ReqStream Modeling LoadResult Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/modeling.md" + - "docs/reqstream/reqstream/modeling.yaml" paths: - "docs/reqstream/reqstream/modeling/load-result.yaml" # unit requirements - "docs/design/reqstream/modeling/load-result.md" # unit design @@ -132,6 +179,11 @@ reviews: - id: ReqStream-Modeling-Requirement title: Review that ReqStream Modeling Requirement Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/modeling.md" + - "docs/reqstream/reqstream/modeling.yaml" paths: - "docs/reqstream/reqstream/modeling/requirement.yaml" # unit requirements - "docs/design/reqstream/modeling/requirement.md" # unit design @@ -141,6 +193,11 @@ reviews: - id: ReqStream-Modeling-Requirements title: Review that ReqStream Modeling Requirements Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/modeling.md" + - "docs/reqstream/reqstream/modeling.yaml" paths: - "docs/reqstream/reqstream/modeling/requirements.yaml" # unit requirements - "docs/design/reqstream/modeling/requirements.md" # unit design @@ -152,6 +209,11 @@ reviews: - id: ReqStream-Modeling-RequirementsLoader title: Review that ReqStream Modeling RequirementsLoader Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/modeling.md" + - "docs/reqstream/reqstream/modeling.yaml" paths: - "docs/reqstream/reqstream/modeling/requirements-loader.yaml" # unit requirements - "docs/design/reqstream/modeling/requirements-loader.md" # unit design @@ -161,6 +223,11 @@ reviews: - id: ReqStream-Modeling-Section title: Review that ReqStream Modeling Section Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/modeling.md" + - "docs/reqstream/reqstream/modeling.yaml" paths: - "docs/reqstream/reqstream/modeling/section.yaml" # unit requirements - "docs/design/reqstream/modeling/section.md" # unit design @@ -173,6 +240,9 @@ reviews: # ReqStream - Tracing - id: ReqStream-Tracing title: Review that ReqStream Tracing Satisfies Subsystem Requirements + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream/tracing.yaml" # subsystem requirements - "docs/design/reqstream/tracing.md" # subsystem design @@ -181,6 +251,11 @@ reviews: - id: ReqStream-Tracing-TraceMatrix title: Review that ReqStream Tracing TraceMatrix Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/tracing.md" + - "docs/reqstream/reqstream/tracing.yaml" paths: - "docs/reqstream/reqstream/tracing/trace-matrix.yaml" # unit requirements - "docs/design/reqstream/tracing/trace-matrix.md" # unit design @@ -193,6 +268,9 @@ reviews: # ReqStream - SelfTest - id: ReqStream-SelfTest title: Review that ReqStream SelfTest Satisfies Subsystem Requirements + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream/self-test.yaml" # subsystem requirements - "docs/design/reqstream/self-test.md" # subsystem design @@ -201,6 +279,11 @@ reviews: - id: ReqStream-SelfTest-Validation title: Review that ReqStream SelfTest Validation Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/self-test.md" + - "docs/reqstream/reqstream/self-test.yaml" paths: - "docs/reqstream/reqstream/self-test/validation.yaml" # unit requirements - "docs/design/reqstream/self-test/validation.md" # unit design @@ -211,6 +294,9 @@ reviews: # ReqStream - Utilities - id: ReqStream-Utilities title: Review that ReqStream Utilities Satisfies Subsystem Requirements + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" paths: - "docs/reqstream/reqstream/utilities.yaml" # subsystem requirements - "docs/design/reqstream/utilities.md" # subsystem design @@ -218,6 +304,11 @@ reviews: - id: ReqStream-Utilities-GlobMatcher title: Review that ReqStream Utilities GlobMatcher Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/utilities.md" + - "docs/reqstream/reqstream/utilities.yaml" paths: - "docs/reqstream/reqstream/utilities/glob-matcher.yaml" # unit requirements - "docs/design/reqstream/utilities/glob-matcher.md" # unit design @@ -227,6 +318,11 @@ reviews: - id: ReqStream-Utilities-PathHelpers title: Review that ReqStream Utilities PathHelpers Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/utilities.md" + - "docs/reqstream/reqstream/utilities.yaml" paths: - "docs/reqstream/reqstream/utilities/path-helpers.yaml" # unit requirements - "docs/design/reqstream/utilities/path-helpers.md" # unit design @@ -236,6 +332,11 @@ reviews: - id: ReqStream-Utilities-TemporaryDirectory title: Review that ReqStream Utilities TemporaryDirectory Implementation is Correct + context: + - "docs/design/reqstream.md" + - "docs/reqstream/reqstream.yaml" + - "docs/design/reqstream/utilities.md" + - "docs/reqstream/reqstream/utilities.yaml" paths: - "docs/reqstream/reqstream/utilities/temporary-directory.yaml" # unit requirements - "docs/design/reqstream/utilities/temporary-directory.md" # unit design @@ -298,6 +399,13 @@ reviews: - "docs/reqstream/ots/sonarmark.yaml" # OTS requirements - "docs/verification/ots/sonarmark.md" # OTS verification + - 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 + - id: OTS-VersionMark title: Review that VersionMark Provides Required Functionality paths: diff --git a/.versionmark.yaml b/.versionmark.yaml index 28387dc..c8768a4 100644 --- a/.versionmark.yaml +++ b/.versionmark.yaml @@ -73,3 +73,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/docs/design/introduction.md b/docs/design/introduction.md index 640f08c..673a354 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -25,6 +25,7 @@ OTS items: - **YamlDotNet**: integration and usage design. - **Microsoft.Extensions.FileSystemGlobbing**: integration and usage design. - **DemaConsulting.TestResults**: integration and usage design. +- **SysML2Tools**: integration and usage design. The following topics are out of scope: @@ -36,32 +37,12 @@ The following topics are out of scope: ## Software Structure -```text -ReqStream (System) -├── Program (Unit) -├── Cli (Subsystem) -│ └── Context (Unit) -├── Utilities (Subsystem) -│ ├── GlobMatcher (Unit) -│ ├── PathHelpers (Unit) -│ └── TemporaryDirectory (Unit) -├── Modeling (Subsystem) -│ ├── LintIssue (Unit) -│ ├── LoadResult (Unit) -│ ├── Requirement (Unit) -│ ├── Requirements (Unit) -│ ├── RequirementsLoader (Unit) -│ └── Section (Unit) -├── Tracing (Subsystem) -│ └── TraceMatrix (Unit) -└── SelfTest (Subsystem) - └── Validation (Unit) - -OTS Dependencies: -├── YamlDotNet (OTS) -├── Microsoft.Extensions.FileSystemGlobbing (OTS) -└── DemaConsulting.TestResults (OTS) -``` +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 diff --git a/docs/design/reqstream.md b/docs/design/reqstream.md index f40b602..6496021 100644 --- a/docs/design/reqstream.md +++ b/docs/design/reqstream.md @@ -1,5 +1,7 @@ # ReqStream +![ReqStream System Structure](ReqStreamView.svg) + ## Architecture The ReqStream system is a single executable (.NET tool package) organized into the following diff --git a/docs/design/reqstream/cli.md b/docs/design/reqstream/cli.md index 7cd39dc..7d1d7b8 100644 --- a/docs/design/reqstream/cli.md +++ b/docs/design/reqstream/cli.md @@ -1,5 +1,7 @@ ## Cli +![Cli Structure](CliView.svg) + ### Overview The `Cli` subsystem provides the command-line interface for ReqStream. It acts as the primary diff --git a/docs/design/reqstream/cli/context.md b/docs/design/reqstream/cli/context.md index 25649bf..030aa7a 100644 --- a/docs/design/reqstream/cli/context.md +++ b/docs/design/reqstream/cli/context.md @@ -1,5 +1,7 @@ ### Context +![Cli Structure](CliView.svg) + #### Purpose `Context` is the command-line argument parser and I/O owner for ReqStream. It is the single diff --git a/docs/design/reqstream/modeling.md b/docs/design/reqstream/modeling.md index 049b324..c7ebe96 100644 --- a/docs/design/reqstream/modeling.md +++ b/docs/design/reqstream/modeling.md @@ -1,5 +1,7 @@ ## Modeling +![Modeling Structure](ModelingView.svg) + ### Overview The `Modeling` subsystem provides the data model and YAML parsing for ReqStream requirements diff --git a/docs/design/reqstream/modeling/lint-issue.md b/docs/design/reqstream/modeling/lint-issue.md index 2940cc2..4152e64 100644 --- a/docs/design/reqstream/modeling/lint-issue.md +++ b/docs/design/reqstream/modeling/lint-issue.md @@ -1,5 +1,7 @@ ### LintIssue +![Modeling Structure](ModelingView.svg) + #### Purpose `LintIssue` and its companion enum `LintSeverity` represent a single structural issue discovered diff --git a/docs/design/reqstream/modeling/load-result.md b/docs/design/reqstream/modeling/load-result.md index 1467943..75096c6 100644 --- a/docs/design/reqstream/modeling/load-result.md +++ b/docs/design/reqstream/modeling/load-result.md @@ -1,5 +1,7 @@ ### LoadResult +![Modeling Structure](ModelingView.svg) + #### Purpose `LoadResult` encapsulates the combined outcome of a `Requirements.Load` call. It holds the diff --git a/docs/design/reqstream/modeling/requirement.md b/docs/design/reqstream/modeling/requirement.md index 9f377df..da765ca 100644 --- a/docs/design/reqstream/modeling/requirement.md +++ b/docs/design/reqstream/modeling/requirement.md @@ -1,5 +1,7 @@ ### Requirement +![Modeling Structure](ModelingView.svg) + #### Purpose `Requirement` is the domain model for a single requirement entry. It is a simple mutable diff --git a/docs/design/reqstream/modeling/requirements-loader.md b/docs/design/reqstream/modeling/requirements-loader.md index a73e080..4286fdc 100644 --- a/docs/design/reqstream/modeling/requirements-loader.md +++ b/docs/design/reqstream/modeling/requirements-loader.md @@ -1,5 +1,7 @@ ### RequirementsLoader +![Modeling Structure](ModelingView.svg) + #### Purpose `RequirementsLoader` is the YAML deserializer and structural lint validator for requirements diff --git a/docs/design/reqstream/modeling/requirements.md b/docs/design/reqstream/modeling/requirements.md index 48f817f..f1dffe8 100644 --- a/docs/design/reqstream/modeling/requirements.md +++ b/docs/design/reqstream/modeling/requirements.md @@ -1,5 +1,7 @@ ### Requirements +![Modeling Structure](ModelingView.svg) + #### Purpose `Requirements` is the root of the requirements section tree and the public API entry point for diff --git a/docs/design/reqstream/modeling/section.md b/docs/design/reqstream/modeling/section.md index af4407a..4f5ab64 100644 --- a/docs/design/reqstream/modeling/section.md +++ b/docs/design/reqstream/modeling/section.md @@ -1,5 +1,7 @@ ### Section +![Modeling Structure](ModelingView.svg) + #### Purpose `Section` is the container node in the requirements tree. It groups a set of `Requirement` diff --git a/docs/design/reqstream/program.md b/docs/design/reqstream/program.md index 72c2aa3..c5b909e 100644 --- a/docs/design/reqstream/program.md +++ b/docs/design/reqstream/program.md @@ -1,5 +1,7 @@ ## Program +![ReqStream System Structure](ReqStreamView.svg) + ### Purpose `Program` is the entry point of the ReqStream executable. It owns the top-level execution flow, diff --git a/docs/design/reqstream/self-test.md b/docs/design/reqstream/self-test.md index 5005c70..2083fc3 100644 --- a/docs/design/reqstream/self-test.md +++ b/docs/design/reqstream/self-test.md @@ -1,5 +1,7 @@ ## SelfTest +![SelfTest Structure](SelfTestView.svg) + ### Overview The `SelfTest` subsystem provides the self-validation framework for ReqStream. It is invoked diff --git a/docs/design/reqstream/self-test/validation.md b/docs/design/reqstream/self-test/validation.md index b75fa42..60d78d3 100644 --- a/docs/design/reqstream/self-test/validation.md +++ b/docs/design/reqstream/self-test/validation.md @@ -1,5 +1,7 @@ ### Validation +![SelfTest Structure](SelfTestView.svg) + #### Purpose `Validation` is the self-validation test runner for ReqStream. It executes a suite of end-to-end diff --git a/docs/design/reqstream/tracing.md b/docs/design/reqstream/tracing.md index 58029d7..904740b 100644 --- a/docs/design/reqstream/tracing.md +++ b/docs/design/reqstream/tracing.md @@ -1,5 +1,7 @@ ## Tracing +![Tracing Structure](TracingView.svg) + ### Overview The `Tracing` subsystem provides test result loading and requirement-to-test traceability diff --git a/docs/design/reqstream/tracing/trace-matrix.md b/docs/design/reqstream/tracing/trace-matrix.md index 3516769..a82533c 100644 --- a/docs/design/reqstream/tracing/trace-matrix.md +++ b/docs/design/reqstream/tracing/trace-matrix.md @@ -1,5 +1,7 @@ ### TraceMatrix +![Tracing Structure](TracingView.svg) + #### Purpose `TraceMatrix` maps test execution results to requirements and calculates requirement-coverage diff --git a/docs/design/reqstream/utilities.md b/docs/design/reqstream/utilities.md index d1c79d0..ee47ea7 100644 --- a/docs/design/reqstream/utilities.md +++ b/docs/design/reqstream/utilities.md @@ -1,5 +1,7 @@ ## Utilities +![Utilities Structure](UtilitiesView.svg) + ### Overview The `Utilities` subsystem provides shared, general-purpose helper utilities for ReqStream. It diff --git a/docs/design/reqstream/utilities/glob-matcher.md b/docs/design/reqstream/utilities/glob-matcher.md index bf0caab..36efaef 100644 --- a/docs/design/reqstream/utilities/glob-matcher.md +++ b/docs/design/reqstream/utilities/glob-matcher.md @@ -1,5 +1,7 @@ ### GlobMatcher +![Utilities Structure](UtilitiesView.svg) + #### Purpose `GlobMatcher` is a static utility class that resolves glob patterns to lists of absolute diff --git a/docs/design/reqstream/utilities/path-helpers.md b/docs/design/reqstream/utilities/path-helpers.md index 54dc7a8..ac39bc9 100644 --- a/docs/design/reqstream/utilities/path-helpers.md +++ b/docs/design/reqstream/utilities/path-helpers.md @@ -1,5 +1,7 @@ ### PathHelpers +![Utilities Structure](UtilitiesView.svg) + #### Purpose `PathHelpers` is a static utility class that provides safe path combination guarded against diff --git a/docs/design/reqstream/utilities/temporary-directory.md b/docs/design/reqstream/utilities/temporary-directory.md index 5f14623..56d384b 100644 --- a/docs/design/reqstream/utilities/temporary-directory.md +++ b/docs/design/reqstream/utilities/temporary-directory.md @@ -1,5 +1,7 @@ ### TemporaryDirectory +![Utilities Structure](UtilitiesView.svg) + #### Purpose `TemporaryDirectory` is a disposable utility class that creates a uniquely named scratch diff --git a/docs/sysml2/model/ots.sysml b/docs/sysml2/model/ots.sysml new file mode 100644 index 0000000..9e8d8a2 --- /dev/null +++ b/docs/sysml2/model/ots.sysml @@ -0,0 +1,27 @@ +package OtsDependencies { + doc /* Off-the-shelf (OTS) dependencies used by ReqStream. */ + + 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 FileSystemGlobbing { + doc /* OTS: Microsoft.Extensions.FileSystemGlobbing. */ + + comment designRef /* Design: docs/design/ots/microsoft-extensions-file-system-globbing.md */ + comment verificationRef /* Verification: docs/verification/ots/microsoft-extensions-file-system-globbing.md */ + comment reqRef /* Requirements: docs/reqstream/ots/microsoft-extensions-file-system-globbing.yaml */ + } + + part def TestResults { + doc /* OTS: DemaConsulting.TestResults. */ + + comment designRef /* Design: docs/design/ots/dema-consulting-test-results.md */ + comment verificationRef /* Verification: docs/verification/ots/dema-consulting-test-results.md */ + comment reqRef /* Requirements: docs/reqstream/ots/dema-consulting-test-results.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream.sysml b/docs/sysml2/model/reqstream.sysml new file mode 100644 index 0000000..b7664ee --- /dev/null +++ b/docs/sysml2/model/reqstream.sysml @@ -0,0 +1,29 @@ +package ReqStream { + import OtsDependencies::*; + + doc + /* + * ReqStream is a .NET command-line tool for managing software requirements in YAML + * format, tracing test results to requirements, and enforcing coverage in CI/CD pipelines. + */ + + part def ReqStreamSystem { + doc /* The ReqStream system as a whole. */ + + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/IntegrationTests.cs */ + comment designRef /* Design: docs/design/reqstream.md */ + comment verificationRef /* Verification: docs/verification/reqstream.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream.yaml */ + + part program : Program; + part cli : CliSubsystem; + part modeling : ModelingSubsystem; + part tracing : TracingSubsystem; + part selfTest : SelfTestSubsystem; + part utilities : UtilitiesSubsystem; + + part yamlDotNet : YamlDotNet; + part fileSystemGlobbing : FileSystemGlobbing; + part testResults : TestResults; + } +} diff --git a/docs/sysml2/model/reqstream/cli.sysml b/docs/sysml2/model/reqstream/cli.sysml new file mode 100644 index 0000000..a1fc853 --- /dev/null +++ b/docs/sysml2/model/reqstream/cli.sysml @@ -0,0 +1,12 @@ +package ReqStream { + part def CliSubsystem { + doc /* Command-line argument parsing and I/O ownership. */ + + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Cli/CliTests.cs */ + comment designRef /* Design: docs/design/reqstream/cli.md */ + comment verificationRef /* Verification: docs/verification/reqstream/cli.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/cli.yaml */ + + part context : Context; + } +} diff --git a/docs/sysml2/model/reqstream/cli/context.sysml b/docs/sysml2/model/reqstream/cli/context.sysml new file mode 100644 index 0000000..545219a --- /dev/null +++ b/docs/sysml2/model/reqstream/cli/context.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def Context { + doc /* Command-line argument parser and I/O owner. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Cli/Context.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Cli/ContextTests.cs */ + comment designRef /* Design: docs/design/reqstream/cli/context.md */ + comment verificationRef /* Verification: docs/verification/reqstream/cli/context.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/cli/context.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/modeling.sysml b/docs/sysml2/model/reqstream/modeling.sysml new file mode 100644 index 0000000..4d58c50 --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling.sysml @@ -0,0 +1,17 @@ +package ReqStream { + part def ModelingSubsystem { + doc /* Requirements data model, section tree, and YAML load/lint pipeline. */ + + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/ModelingTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling.yaml */ + + part lintIssue : LintIssue; + part loadResult : LoadResult; + part requirementItem : Requirement; + part requirementsItem : Requirements; + part requirementsLoader : RequirementsLoader; + part section : Section; + } +} diff --git a/docs/sysml2/model/reqstream/modeling/lint-issue.sysml b/docs/sysml2/model/reqstream/modeling/lint-issue.sysml new file mode 100644 index 0000000..aef9c1d --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling/lint-issue.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def LintIssue { + doc /* Lint issue severity and data model. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Modeling/LintIssue.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/LintIssueTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling/lint-issue.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling/lint-issue.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling/lint-issue.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/modeling/load-result.sysml b/docs/sysml2/model/reqstream/modeling/load-result.sysml new file mode 100644 index 0000000..4c99606 --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling/load-result.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def LoadResult { + doc /* Combined result of loading requirements and associated lint issues. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Modeling/LoadResult.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/LoadResultTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling/load-result.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling/load-result.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling/load-result.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/modeling/requirement.sysml b/docs/sysml2/model/reqstream/modeling/requirement.sysml new file mode 100644 index 0000000..ae8454e --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling/requirement.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def Requirement { + doc /* Single requirement with ID, title, and test links. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Modeling/Requirement.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/RequirementTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling/requirement.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling/requirement.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling/requirement.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/modeling/requirements-loader.sysml b/docs/sysml2/model/reqstream/modeling/requirements-loader.sysml new file mode 100644 index 0000000..1d2d65c --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling/requirements-loader.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def RequirementsLoader { + doc /* YAML deserializer and lint validator for requirements files. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Modeling/RequirementsLoader.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/RequirementsLoaderTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling/requirements-loader.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling/requirements-loader.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling/requirements-loader.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/modeling/requirements.sysml b/docs/sysml2/model/reqstream/modeling/requirements.sysml new file mode 100644 index 0000000..d05e63d --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling/requirements.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def Requirements { + doc /* Parsed requirements document with section tree. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Modeling/Requirements.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/RequirementsLoadTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling/requirements.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling/requirements.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling/requirements.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/modeling/section.sysml b/docs/sysml2/model/reqstream/modeling/section.sysml new file mode 100644 index 0000000..45e826e --- /dev/null +++ b/docs/sysml2/model/reqstream/modeling/section.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def Section { + doc /* Named group of requirements within a document. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Modeling/Section.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Modeling/SectionTests.cs */ + comment designRef /* Design: docs/design/reqstream/modeling/section.md */ + comment verificationRef /* Verification: docs/verification/reqstream/modeling/section.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/modeling/section.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/program.sysml b/docs/sysml2/model/reqstream/program.sysml new file mode 100644 index 0000000..4879065 --- /dev/null +++ b/docs/sysml2/model/reqstream/program.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def Program { + doc /* Entry point and execution orchestrator. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Program.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/ProgramTests.cs */ + comment designRef /* Design: docs/design/reqstream/program.md */ + comment verificationRef /* Verification: docs/verification/reqstream/program.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/program.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/self-test.sysml b/docs/sysml2/model/reqstream/self-test.sysml new file mode 100644 index 0000000..9a0b817 --- /dev/null +++ b/docs/sysml2/model/reqstream/self-test.sysml @@ -0,0 +1,12 @@ +package ReqStream { + part def SelfTestSubsystem { + doc /* Self-validation test runner exercised at startup for OTS/BuildMark self-check evidence. */ + + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/SelfTest/SelfTestTests.cs */ + comment designRef /* Design: docs/design/reqstream/self-test.md */ + comment verificationRef /* Verification: docs/verification/reqstream/self-test.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/self-test.yaml */ + + part validation : Validation; + } +} diff --git a/docs/sysml2/model/reqstream/self-test/validation.sysml b/docs/sysml2/model/reqstream/self-test/validation.sysml new file mode 100644 index 0000000..2f540b8 --- /dev/null +++ b/docs/sysml2/model/reqstream/self-test/validation.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def Validation { + doc /* Self-validation test runner. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/SelfTest/Validation.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/SelfTest/ValidationTests.cs */ + comment designRef /* Design: docs/design/reqstream/self-test/validation.md */ + comment verificationRef /* Verification: docs/verification/reqstream/self-test/validation.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/self-test/validation.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/tracing.sysml b/docs/sysml2/model/reqstream/tracing.sysml new file mode 100644 index 0000000..ace95a1 --- /dev/null +++ b/docs/sysml2/model/reqstream/tracing.sysml @@ -0,0 +1,12 @@ +package ReqStream { + part def TracingSubsystem { + doc /* Test result loading and requirement-coverage trace matrix generation. */ + + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Tracing/TracingTests.cs */ + comment designRef /* Design: docs/design/reqstream/tracing.md */ + comment verificationRef /* Verification: docs/verification/reqstream/tracing.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/tracing.yaml */ + + part traceMatrix : TraceMatrix; + } +} diff --git a/docs/sysml2/model/reqstream/tracing/trace-matrix.sysml b/docs/sysml2/model/reqstream/tracing/trace-matrix.sysml new file mode 100644 index 0000000..9b6218c --- /dev/null +++ b/docs/sysml2/model/reqstream/tracing/trace-matrix.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def TraceMatrix { + doc /* Test result loader and requirement-coverage analyzer. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Tracing/TraceMatrix.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Tracing/TraceMatrixTests.cs */ + comment designRef /* Design: docs/design/reqstream/tracing/trace-matrix.md */ + comment verificationRef /* Verification: docs/verification/reqstream/tracing/trace-matrix.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/tracing/trace-matrix.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/utilities.sysml b/docs/sysml2/model/reqstream/utilities.sysml new file mode 100644 index 0000000..0c34e29 --- /dev/null +++ b/docs/sysml2/model/reqstream/utilities.sysml @@ -0,0 +1,13 @@ +package ReqStream { + part def UtilitiesSubsystem { + doc /* Glob-pattern matching, safe path handling, and temporary workspace helpers. */ + + comment designRef /* Design: docs/design/reqstream/utilities.md */ + comment verificationRef /* Verification: docs/verification/reqstream/utilities.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/utilities.yaml */ + + part globMatcher : GlobMatcher; + part pathHelpers : PathHelpers; + part temporaryDirectory : TemporaryDirectory; + } +} diff --git a/docs/sysml2/model/reqstream/utilities/glob-matcher.sysml b/docs/sysml2/model/reqstream/utilities/glob-matcher.sysml new file mode 100644 index 0000000..cdf0726 --- /dev/null +++ b/docs/sysml2/model/reqstream/utilities/glob-matcher.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def GlobMatcher { + doc /* Glob-pattern file matching utility. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Utilities/GlobMatcher.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Utilities/GlobMatcherTests.cs */ + comment designRef /* Design: docs/design/reqstream/utilities/glob-matcher.md */ + comment verificationRef /* Verification: docs/verification/reqstream/utilities/glob-matcher.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/utilities/glob-matcher.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/utilities/path-helpers.sysml b/docs/sysml2/model/reqstream/utilities/path-helpers.sysml new file mode 100644 index 0000000..2befafa --- /dev/null +++ b/docs/sysml2/model/reqstream/utilities/path-helpers.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def PathHelpers { + doc /* Safe path-combination utility with traversal protection. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Utilities/PathHelpers.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Utilities/PathHelpersTests.cs */ + comment designRef /* Design: docs/design/reqstream/utilities/path-helpers.md */ + comment verificationRef /* Verification: docs/verification/reqstream/utilities/path-helpers.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/utilities/path-helpers.yaml */ + } +} diff --git a/docs/sysml2/model/reqstream/utilities/temporary-directory.sysml b/docs/sysml2/model/reqstream/utilities/temporary-directory.sysml new file mode 100644 index 0000000..2e3d3f9 --- /dev/null +++ b/docs/sysml2/model/reqstream/utilities/temporary-directory.sysml @@ -0,0 +1,11 @@ +package ReqStream { + part def TemporaryDirectory { + doc /* Disposable temporary directory for isolated file-system workspaces. */ + + comment sourceRef /* Source: src/DemaConsulting.ReqStream/Utilities/TemporaryDirectory.cs */ + comment testRef /* Test: test/DemaConsulting.ReqStream.Tests/Utilities/TemporaryDirectoryTests.cs */ + comment designRef /* Design: docs/design/reqstream/utilities/temporary-directory.md */ + comment verificationRef /* Verification: docs/verification/reqstream/utilities/temporary-directory.md */ + comment reqRef /* Requirements: docs/reqstream/reqstream/utilities/temporary-directory.yaml */ + } +} diff --git a/docs/sysml2/views/design-views.sysml b/docs/sysml2/views/design-views.sysml new file mode 100644 index 0000000..8bc235d --- /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 ReqStream 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 ReqStream { + view SoftwareStructureView { + expose ReqStream; + } + + view ReqStreamView { + expose ReqStreamSystem; + } + + view CliView { + expose CliSubsystem; + } + + view ModelingView { + expose ModelingSubsystem; + } + + view TracingView { + expose TracingSubsystem; + } + + view SelfTestView { + expose SelfTestSubsystem; + } + + view UtilitiesView { + expose UtilitiesSubsystem; + } +} diff --git a/docs/verification/introduction.md b/docs/verification/introduction.md index 17647e3..1e6af9b 100644 --- a/docs/verification/introduction.md +++ b/docs/verification/introduction.md @@ -49,6 +49,7 @@ The following OTS items are also verified: - **WeasyPrint** — HTML to PDF converter - **YamlDotNet** — YAML parsing library - **Microsoft.Extensions.FileSystemGlobbing** — glob pattern matching library +- **SysML2Tools** — architecture model validation and diagram rendering tool The following topics are out of scope: 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. From 5863fada6e321de1123980d4fb9989b541c60093 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Thu, 9 Jul 2026 13:32:48 -0400 Subject: [PATCH 3/5] Add SysML2Tools OTS companion documentation - Add docs/reqstream/ots/sysml2tools.yaml, docs/design/ots/sysml2tools.md, and docs/verification/ots/sysml2tools.md as full OTS companion artifacts for the sysml2tools dotnet tool itself. - Wire the new files into requirements.yaml, docs/design/definition.yaml, docs/verification/definition.yaml, docs/design/ots.md, and docs/verification/ots.md, plus a new OTS-SysML2Tools review-set in .reviewmark.yaml (added in the previous commit). - Add sysml, sysml2tools, and demaconsulting to .cspell.yaml. --- .cspell.yaml | 3 ++ docs/design/definition.yaml | 1 + docs/design/ots.md | 5 ++- docs/design/ots/sysml2tools.md | 52 +++++++++++++++++++++++++++ docs/reqstream/ots/sysml2tools.yaml | 38 ++++++++++++++++++++ docs/verification/definition.yaml | 1 + docs/verification/ots.md | 1 + docs/verification/ots/sysml2tools.md | 53 ++++++++++++++++++++++++++++ requirements.yaml | 1 + 9 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 docs/design/ots/sysml2tools.md create mode 100644 docs/reqstream/ots/sysml2tools.yaml create mode 100644 docs/verification/ots/sysml2tools.md diff --git a/.cspell.yaml b/.cspell.yaml index 5dc6cd7..57e9156 100644 --- a/.cspell.yaml +++ b/.cspell.yaml @@ -18,6 +18,7 @@ words: - buildmark - DEMA - Dema + - demaconsulting - fileassert - hotspot - hotspots @@ -30,6 +31,8 @@ words: - Sarif - sarifmark - sonarmark + - sysml + - sysml2tools - testname - testresults - tracematrix diff --git a/docs/design/definition.yaml b/docs/design/definition.yaml index 245a355..38580c3 100644 --- a/docs/design/definition.yaml +++ b/docs/design/definition.yaml @@ -35,6 +35,7 @@ input-files: - docs/design/ots/yamldotnet.md - docs/design/ots/microsoft-extensions-file-system-globbing.md - docs/design/ots/dema-consulting-test-results.md + - docs/design/ots/sysml2tools.md template: template.html table-of-contents: true diff --git a/docs/design/ots.md b/docs/design/ots.md index a160ecd..71d2dba 100644 --- a/docs/design/ots.md +++ b/docs/design/ots.md @@ -5,7 +5,10 @@ ReqStream. Each OTS item is accessed through a single dedicated wrapper or utili the system, ensuring minimal coupling and straightforward replacement. CI pipeline tools (BuildMark, FileAssert, xUnit, Pandoc, ReviewMark, SarifMark, SonarMark, VersionMark, WeasyPrint) are excluded from integration design documentation because they are not accessed -through source code APIs; their integration is through the CI configuration files. +through source code APIs; their integration is through the CI configuration files. SysML2Tools is +a pipeline tool but is documented here as an intentional exception because it validates and +renders the SysML2 architecture model that this chapter and `docs/design/introduction.md` +describe; see _SysML2Tools OTS Design_ for its integration pattern. ## Selection Criteria diff --git a/docs/design/ots/sysml2tools.md b/docs/design/ots/sysml2tools.md new file mode 100644 index 0000000..364704a --- /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 ReqStream'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..3c2887f --- /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: ReqStream-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: ReqStream-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: ReqStream-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: + - ReqStream-OTS-SysML2Tools-Lint + - ReqStream-OTS-SysML2Tools-Render diff --git a/docs/verification/definition.yaml b/docs/verification/definition.yaml index ba244e0..5c7fb60 100644 --- a/docs/verification/definition.yaml +++ b/docs/verification/definition.yaml @@ -25,6 +25,7 @@ input-files: - docs/verification/ots/yamldotnet.md - docs/verification/ots/microsoft-extensions-file-system-globbing.md - docs/verification/ots/dema-consulting-test-results.md + - docs/verification/ots/sysml2tools.md - docs/verification/ots/xunit.md - docs/verification/ots/weasyprint.md - docs/verification/ots/versionmark.md diff --git a/docs/verification/ots.md b/docs/verification/ots.md index c083812..3d7cbd0 100644 --- a/docs/verification/ots.md +++ b/docs/verification/ots.md @@ -41,6 +41,7 @@ The following table lists all OTS items and their primary evidence type. | YamlDotNet | Integration test evidence | | Microsoft.Extensions.FileSystemGlobbing | Integration test evidence | | DemaConsulting.TestResults | Integration test evidence | +| SysML2Tools | Self-validation report and CI pipeline step evidence | ## Regression Approach diff --git a/docs/verification/ots/sysml2tools.md b/docs/verification/ots/sysml2tools.md new file mode 100644 index 0000000..cdf369a --- /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 ReqStream 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/requirements.yaml b/requirements.yaml index ce5e751..08efc5c 100644 --- a/requirements.yaml +++ b/requirements.yaml @@ -16,3 +16,4 @@ includes: - docs/reqstream/ots/yamldotnet.yaml - docs/reqstream/ots/microsoft-extensions-file-system-globbing.yaml - docs/reqstream/ots/dema-consulting-test-results.yaml + - docs/reqstream/ots/sysml2tools.yaml From 63ff1a286575d6f89e42808001b2f0300c030236 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Thu, 9 Jul 2026 17:09:08 -0400 Subject: [PATCH 4/5] Fix formal review findings: SysML2Tools OTS scope, coverage tables, CLI/design doc drift - docs/design/ots/sysml2tools.md: fix self-contradiction (global vs local tool), correct CI job/step references (build-docs job, self-validation + render steps). - docs/design/introduction.md: remove SysML2Tools from the in-scope OTS design items list to match the SysML2 model boundary; document it (and other pipeline OTS tools) as out-of-scope build-pipeline tooling with companion artifacts and a dedicated ReviewMark review-set instead. - docs/reqstream/reqstream/modeling.yaml: remove the misplaced ReqStream-Utilities-SafePath child reference from ReqStream-Modeling-MultiFileLoading (belongs to the Utilities subsystem). - docs/design/reqstream/tracing.md: correct TraceMatrix.Export depth documentation - only a lower bound of 1 is enforced, no upper bound of 6. - docs/design/reqstream.md: document --version/-v, --help/-h/-?, and --results/--result aliases to match Context.cs and cli/context.md. - docs/design/reqstream/utilities.md: document GlobMatcher null-input behavior (ArgumentNullException for null patterns collection, silent skip of null elements). - docs/verification/reqstream/{modeling,tracing,utilities,utilities/path-helpers}.md: remove hand-maintained Requirements Coverage tables per verification-documentation.md standard (coverage lives in the ReqStream trace matrix, not verification docs); reworded acceptance-criteria text that referenced the removed tables. --- docs/design/introduction.md | 8 +++- docs/design/ots/sysml2tools.md | 26 +++++++------ docs/design/reqstream.md | 8 ++-- docs/design/reqstream/tracing.md | 11 ++++-- docs/design/reqstream/utilities.md | 4 +- docs/reqstream/reqstream/modeling.yaml | 1 - docs/verification/reqstream/modeling.md | 14 +------ docs/verification/reqstream/tracing.md | 14 +------ docs/verification/reqstream/utilities.md | 37 +------------------ .../reqstream/utilities/path-helpers.md | 11 +----- 10 files changed, 43 insertions(+), 91 deletions(-) diff --git a/docs/design/introduction.md b/docs/design/introduction.md index 673a354..5940321 100644 --- a/docs/design/introduction.md +++ b/docs/design/introduction.md @@ -25,13 +25,17 @@ OTS items: - **YamlDotNet**: integration and usage design. - **Microsoft.Extensions.FileSystemGlobbing**: integration and usage design. - **DemaConsulting.TestResults**: integration and usage design. -- **SysML2Tools**: integration and usage design. The following topics are out of scope: - Internal design of OTS items (YamlDotNet, Microsoft.Extensions.FileSystemGlobbing, DemaConsulting.TestResults) -- Build pipeline configuration +- Build pipeline configuration and the build/pipeline OTS tools that support it (for example + SysML2Tools, Pandoc, WeasyPrint, BuildMark, VersionMark, ReviewMark, SarifMark, SonarMark, + XUnit, and FileAssert). These pipeline tools are not modeled as SysML2 structural parts; each + still has its own requirements, design, and verification companion artifacts under + `docs/design/ots/`, `docs/reqstream/ots/`, and `docs/verification/ots/`, and is covered by its + own ReviewMark OTS review-set. - Deployment and packaging - Test projects, test classes, and test infrastructure diff --git a/docs/design/ots/sysml2tools.md b/docs/design/ots/sysml2tools.md index 364704a..b181252 100644 --- a/docs/design/ots/sysml2tools.md +++ b/docs/design/ots/sysml2tools.md @@ -1,6 +1,6 @@ ## SysML2Tools OTS Design -DemaConsulting.SysML2Tools is a .NET dotnet global tool that lints a SysML2 architecture model +DemaConsulting.SysML2Tools is a .NET dotnet local tool that lints a SysML2 architecture model and renders its declared views to SVG diagrams consumed by the design documentation. ### Purpose @@ -36,16 +36,20 @@ package name `demaconsulting.sysml2tools.tool` and restored with `dotnet tool re 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. +It is used in three places in the pipeline: + +- **Lint** (`lint.ps1`, run from the `build.yaml` `quality-checks` job and available for local + pre-PR checks): `dotnet sysml2tools lint 'docs/sysml2/**/*.sysml'` fails the build if the model + contains syntax errors or unresolved references. +- **Self-validation** (`build.yaml` `build-docs` job, "Run SysML2Tools self-validation" step): + `dotnet sysml2tools --validate` runs the tool's own self-test suite and captures the results to + `artifacts/sysml2tools-self-validation.trx`, satisfying the OTS self-validation requirement. +- **Render** (`build.yaml` `build-docs` job, "Render Software Structure diagrams with SysML2Tools" + step): `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 diff --git a/docs/design/reqstream.md b/docs/design/reqstream.md index 6496021..f13da33 100644 --- a/docs/design/reqstream.md +++ b/docs/design/reqstream.md @@ -73,10 +73,10 @@ to produce output. - *Type*: CLI. - *Role*: Consumer (the user provides arguments to the system). -- *Contract*: Defined flag set (`--version`, `--help`, `--silent`, `--validate`, `--lint`, - `--enforce`, `--requirements`, `--tests`, `--report`, `--matrix`, `--justifications`, +- *Contract*: Defined flag set (`--version`/`-v`, `--help`/`-h`/`-?`, `--silent`, `--validate`, + `--lint`, `--enforce`, `--requirements`, `--tests`, `--report`, `--matrix`, `--justifications`, `--filter`, `--depth`, `--report-depth`, `--matrix-depth`, `--justifications-depth`, - `--results`, `--log`); unknown flags cause `ArgumentException`. + `--results`/`--result`, `--log`); unknown flags cause `ArgumentException`. - *Constraints*: No interactive prompts; all information must be on the command line. **Standard output (stdout)**: Plain text lines via `Context.WriteLine`. @@ -128,7 +128,7 @@ to produce output. - *Type*: File (XML). - *Role*: Provider. -- *Contract*: Path from `--results`; written by `Validation.WriteResultsFile`. +- *Contract*: Path from `--results`/`--result`; written by `Validation.WriteResultsFile`. - *Constraints*: Extension must be `.trx` or `.xml`. **Process exit code**: Integer signal to the calling process. diff --git a/docs/design/reqstream/tracing.md b/docs/design/reqstream/tracing.md index 904740b..44e6579 100644 --- a/docs/design/reqstream/tracing.md +++ b/docs/design/reqstream/tracing.md @@ -32,10 +32,13 @@ The `Tracing` subsystem contains the following software unit: - *Type*: In-process .NET public API. - *Role*: Provider. - *Contract*: Accepts `filePath`, `depth`, and optional `filterTags`; writes a Markdown report - with Summary, Requirements, and Testing sections. The `depth` parameter controls the Markdown - heading level (valid range 1–6, matching ATX heading levels `#` through `######`); when omitted - the default is 1 (top-level `#` headings). -- *Constraints*: Throws `ArgumentException` for null/empty path. + with Summary, Requirements, and Testing sections. The `depth` parameter sets the starting + Markdown heading level (ATX `#` count) for the report; when omitted the default is 1 + (top-level `#` headings). Only a lower bound of 1 is enforced — nested requirement sections + increase the heading level further for each level of nesting and are not capped at the + Markdown `######` (level 6) maximum. +- *Constraints*: Throws `ArgumentException` for null/empty path; throws + `ArgumentOutOfRangeException` when `depth` is less than 1. **TraceMatrix.CalculateSatisfiedRequirements**: Returns satisfied and total requirement counts. diff --git a/docs/design/reqstream/utilities.md b/docs/design/reqstream/utilities.md index ee47ea7..5952a78 100644 --- a/docs/design/reqstream/utilities.md +++ b/docs/design/reqstream/utilities.md @@ -26,7 +26,9 @@ matching any of the supplied glob patterns. - *Role*: Provider (Cli subsystem consumes this). - *Contract*: Accepts a collection of glob pattern strings; returns `List` of absolute paths. Supports both relative patterns (resolved against the current working directory) and - absolute patterns (resolved from the rooted prefix of the pattern). + absolute patterns (resolved from the rooted prefix of the pattern). Throws + `ArgumentNullException` if `patterns` itself is null; individual null elements within + `patterns` are skipped silently so callers do not need to filter their collections. - *Constraints*: Never throws for non-matching patterns or non-existent directories. **PathHelpers.SafePathCombine**: Combines two paths and validates the result stays within the diff --git a/docs/reqstream/reqstream/modeling.yaml b/docs/reqstream/reqstream/modeling.yaml index 5a4da3b..4600ff9 100644 --- a/docs/reqstream/reqstream/modeling.yaml +++ b/docs/reqstream/reqstream/modeling.yaml @@ -73,7 +73,6 @@ sections: children: - ReqStream-Requirements-Includes - ReqStream-Requirements-SectionMerging - - ReqStream-Utilities-SafePath - id: ReqStream-Modeling-Linting title: The Modeling subsystem shall perform requirements file linting. diff --git a/docs/verification/reqstream/modeling.md b/docs/verification/reqstream/modeling.md index 2e991c5..0d5231f 100644 --- a/docs/verification/reqstream/modeling.md +++ b/docs/verification/reqstream/modeling.md @@ -17,7 +17,8 @@ completion. The Modeling subsystem verification is complete when all xUnit tests in `ModelingTests.cs` pass without uncaught exceptions and all assertions succeed. The subsystem is considered verified when -every requirement in the Requirements Coverage is mapped to at least one passing test method. +every Modeling requirement is mapped to at least one passing test method in the ReqStream trace +matrix. ### Test Scenarios @@ -41,14 +42,3 @@ malformed YAML produces an error with null requirements; `Modeling_Linting_ValidFile_ReturnsNoIssues`, which verifies a valid file returns no issues; and `Modeling_LintingReporting_MultipleConditions_ReportsAllIssues`, which verifies all issues are reported at once. - -### Requirements Coverage - -| Requirement ID | Scenario(s) | Test Method(s) | -| --- | --- | --- | -| `ReqStream-Modeling-YamlParsing` | YAML Parsing Scenario | `Modeling_YamlParsing_ValidFile_LoadsRequirements`, `Modeling_YamlParsing_ValidFile_ReturnsNoLintIssues`, `Modeling_YamlParsing_DuplicateIds_DetectsLintError`, `Modeling_YamlParsing_NoPaths_ThrowsArgumentException` | -| `ReqStream-Modeling-Export` | Export Scenario | `Modeling_Export_Requirements_GeneratesMarkdownFile`, `Modeling_Export_Justifications_GeneratesMarkdownFile` | -| `ReqStream-Modeling-MultiFileLoading` | YAML Parsing Scenario | `Modeling_YamlParsing_ValidFile_LoadsRequirements`, `Modeling_MultiFileLoading_WithIncludes_LoadsRequirementsFromAllFiles` | -| `ReqStream-Modeling-Linting` | Linting Scenario | `Modeling_YamlParsing_DuplicateIds_DetectsLintError`, `Modeling_Linting_MalformedYaml_DetectsError`, `Modeling_Linting_ValidFile_ReturnsNoIssues` | -| `ReqStream-Modeling-LintingValidation` | Linting Scenario | `Modeling_Linting_MalformedYaml_DetectsError`, `Modeling_Linting_ValidFile_ReturnsNoIssues` | -| `ReqStream-Modeling-LintingReporting` | Linting Scenario | `Modeling_YamlParsing_DuplicateIds_DetectsLintError`, `Modeling_LintingReporting_MultipleConditions_ReportsAllIssues` | diff --git a/docs/verification/reqstream/tracing.md b/docs/verification/reqstream/tracing.md index 087a3f6..42c01fd 100644 --- a/docs/verification/reqstream/tracing.md +++ b/docs/verification/reqstream/tracing.md @@ -19,7 +19,8 @@ files in a per-test temporary directory that is deleted on disposal. The Tracing subsystem verification is complete when all xUnit tests in `TracingTests.cs` pass without uncaught exceptions and all assertions succeed. The subsystem is considered verified when -every requirement in the Requirements Coverage table is mapped to at least one passing test method. +every Tracing requirement is mapped to at least one passing test method in the ReqStream trace +matrix. ### Test Scenarios @@ -43,14 +44,3 @@ file produces `InvalidOperationException`. **Reporting**: Tests verify that a Markdown trace matrix report is generated. This scenario is tested by `Tracing_Reporting_SimpleMatrix_CreatesMarkdownFile`, which verifies a Markdown report is generated. - -### Requirements Coverage - -| Requirement ID | Scenario(s) | Test Method(s) | -| --- | --- | --- | -| `ReqStream-Tracing-TestResults` | Test Results Loading Scenario | `Tracing_TestResults_TrxFile_LoadsTestResults`, `Tracing_TestResults_JUnitFile_LoadsTestResults` | -| `ReqStream-Tracing-Mapping` | Coverage Scenario | `Tracing_Coverage_WithPassingTests_AllRequirementsSatisfied` | -| `ReqStream-Tracing-Coverage` | Coverage Scenario | `Tracing_Coverage_WithPassingTests_AllRequirementsSatisfied`, `Tracing_Coverage_WithMissingTests_RequirementIsUnsatisfied` | -| `ReqStream-Tracing-MissingFile` | Error Handling Scenario | `Tracing_FileLoading_NonExistentFile_ThrowsFileNotFoundException` | -| `ReqStream-Tracing-MalformedFile` | Error Handling Scenario | `Tracing_FileLoading_MalformedFile_ThrowsInvalidOperationException` | -| `ReqStream-Tracing-Reporting` | Reporting Scenario | `Tracing_Reporting_SimpleMatrix_CreatesMarkdownFile` | diff --git a/docs/verification/reqstream/utilities.md b/docs/verification/reqstream/utilities.md index 2f0ef51..294fe1b 100644 --- a/docs/verification/reqstream/utilities.md +++ b/docs/verification/reqstream/utilities.md @@ -23,8 +23,8 @@ which are deleted on test completion. The Utilities subsystem verification is complete when all xUnit unit tests for `GlobMatcher`, `PathHelpers`, and `TemporaryDirectory` pass without uncaught exceptions and all assertions -succeed. The subsystem is considered verified when every requirement in the Requirements -Coverage is mapped to at least one passing test method. +succeed. The subsystem is considered verified when every Utilities requirement is mapped to at +least one passing test method in the ReqStream trace matrix. ### Test Scenarios @@ -81,36 +81,3 @@ scenario is tested by `TemporaryDirectory_Constructor_Default_CreatesDirectory`, `TemporaryDirectory_GetFilePath_TraversalAttempt_ThrowsArgumentException`, `TemporaryDirectory_Dispose_PopulatedDirectory_DeletesDirectory`, and `TemporaryDirectory_Dispose_AlreadyDeleted_DoesNotThrow`. - -### Requirements Coverage - -| Requirement ID | Test Method(s) | -| --- | --- | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_RelativePattern_MatchesFiles` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_AbsolutePatternWithWildcard_MatchesFiles` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_AbsolutePatternWithDoubleWildcard_MatchesFilesInSubdirectories` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_AbsoluteLiteralPath_MatchesSingleFile` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_SplitAbsolutePattern_WildcardAtTopLevel_SplitsAtRoot` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_SplitAbsolutePattern_LiteralPath_SplitsAtLastSeparator` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_SplitAbsolutePattern_DoubleStarWildcard_SplitsBeforeWildcard` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_MultiplePatterns_DeduplicatesResults` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_MultiplePatterns_CombinesFromDifferentSources` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_ReturnsAbsolutePaths` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_AbsolutePatternNonExistentDirectory_ReturnsEmpty` | -| `ReqStream-Utilities-GlobMatching` | `GlobMatcher_FindMatchingFiles_MultipleMatches_ReturnsSortedResults` | -| `ReqStream-GlobMatcher-NullPatterns` | `GlobMatcher_FindMatchingFiles_NullPatterns_ThrowsArgumentNullException` | -| `ReqStream-GlobMatcher-NullElement` | `GlobMatcher_FindMatchingFiles_NullElementInPatterns_SkipsElement` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_ValidRelativePath_ReturnsCombinedPath` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_ValidSubdirectory_ReturnsCombinedPath` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_DotDotPath_ThrowsArgumentException` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_DeepDotDotPath_ThrowsArgumentException` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_AbsoluteOverridePath_ThrowsArgumentException` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_NullBasePath_ThrowsArgumentNullException` | -| `ReqStream-Utilities-SafePath` | `PathHelpers_SafePathCombine_NullRelativePath_ThrowsArgumentNullException` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_Constructor_Default_CreatesDirectory` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_Constructor_TwoInstances_CreateUniqueDirectories` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_GetFilePath_SimpleFile_ReturnsPathUnderDirectory` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_GetFilePath_NestedPath_CreatesIntermediateDirectories` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_GetFilePath_TraversalAttempt_ThrowsArgumentException` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_Dispose_PopulatedDirectory_DeletesDirectory` | -| `ReqStream-Utilities-TemporaryDirectory` | `TemporaryDirectory_Dispose_AlreadyDeleted_DoesNotThrow` | diff --git a/docs/verification/reqstream/utilities/path-helpers.md b/docs/verification/reqstream/utilities/path-helpers.md index 5bbe8ce..3d06e83 100644 --- a/docs/verification/reqstream/utilities/path-helpers.md +++ b/docs/verification/reqstream/utilities/path-helpers.md @@ -15,7 +15,8 @@ No file system access or external dependencies are used. The PathHelpers unit verification is complete when all xUnit tests in `PathHelpersTests.cs` pass without uncaught exceptions and all assertions succeed. The unit is considered verified when every -requirement in the Requirements Coverage table is mapped to at least one passing test method. +PathHelpers requirement is mapped to at least one passing test method in the ReqStream trace +matrix. #### Test Scenarios @@ -34,11 +35,3 @@ absolute path overrides are rejected. This scenario is tested by `ArgumentNullException`. This scenario is tested by `PathHelpers_SafePathCombine_NullBasePath_ThrowsArgumentNullException` and `PathHelpers_SafePathCombine_NullRelativePath_ThrowsArgumentNullException`. - -#### Requirements Coverage - -| Requirement ID | Test Method(s) | -| --- | --- | -| `ReqStream-Utilities-PathHelpers-SafeCombine` | `PathHelpers_SafePathCombine_ValidRelativePath_ReturnsCombinedPath`, `PathHelpers_SafePathCombine_ValidSubdirectory_ReturnsCombinedPath` | -| `ReqStream-Utilities-PathHelpers-PathTraversalRejection` | `PathHelpers_SafePathCombine_DotDotPath_ThrowsArgumentException`, `PathHelpers_SafePathCombine_DeepDotDotPath_ThrowsArgumentException`, `PathHelpers_SafePathCombine_AbsoluteOverridePath_ThrowsArgumentException` | -| `ReqStream-Utilities-PathHelpers-NullGuard` | `PathHelpers_SafePathCombine_NullBasePath_ThrowsArgumentNullException`, `PathHelpers_SafePathCombine_NullRelativePath_ThrowsArgumentNullException` | From aaef45097e9bf67c9667ea3287e466c92139b6da Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Thu, 9 Jul 2026 17:16:29 -0400 Subject: [PATCH 5/5] fix(modeling): resolve mappings after full include tree is loaded Restructure RequirementsLoader into a two-pass load: pass 1 recursively builds the full requirements tree across all includes without resolving mappings; pass 2 resolves all deferred mappings against the complete requirements dictionary. Unresolved mapping IDs now emit a lint Error instead of being silently dropped. Adds tests covering mapping resolution across includes and the new unresolved-mapping-id lint error. --- .../Modeling/RequirementsLoader.cs | 86 ++++++++++++++----- .../Modeling/RequirementsLoaderTests.cs | 76 ++++++++++++++++ 2 files changed, 141 insertions(+), 21 deletions(-) diff --git a/src/DemaConsulting.ReqStream/Modeling/RequirementsLoader.cs b/src/DemaConsulting.ReqStream/Modeling/RequirementsLoader.cs index b45651d..58645e5 100644 --- a/src/DemaConsulting.ReqStream/Modeling/RequirementsLoader.cs +++ b/src/DemaConsulting.ReqStream/Modeling/RequirementsLoader.cs @@ -25,13 +25,15 @@ namespace DemaConsulting.ReqStream.Modeling; /// -/// Loads requirements from YAML files using a single DOM tree walk that simultaneously -/// builds the requirements model and collects lint issues. +/// Loads requirements from YAML files using a single DOM parse per file (each file's YAML is +/// parsed exactly once), followed by two logical passes over the resulting DOM trees: a tree +/// build pass that builds the requirements model, and a mapping resolution pass that applies +/// test mappings once the full requirements tree (across all included files) is known. /// /// /// Internal static class that is the sole reader of YAML from disk for requirements data. /// Isolated behind . Not thread-safe; designed for -/// single-threaded, single-pass loading. +/// single-threaded loading. /// internal static class RequirementsLoader { @@ -72,8 +74,14 @@ internal static class RequirementsLoader /// Thrown when no paths are provided. /// /// Initializes all shared state for one load session (requirements tree, seenIds, - /// allRequirements, visitedFiles, activeFiles). Delegates file loading to - /// and cycle detection to . + /// allRequirements, visitedFiles, activeFiles, pendingMappings). Runs two passes: + /// Pass 1 builds the full merged requirements tree across all files reachable via + /// includes:, by delegating to , while mappings: + /// blocks are deferred (not yet resolved) into pendingMappings. Pass 2, run only + /// after the entire tree (across all included files) has been built, resolves every + /// deferred mapping via so that mappings may reference + /// requirements defined in any file, regardless of include order. Cycle detection via + /// runs last, once mappings are resolved. /// Returns null when any error-level issue is found, /// allowing callers to detect failure without exception handling. /// @@ -99,10 +107,20 @@ internal static LoadResult Load(string[] paths) // activeFiles tracks the current include call stack to detect circular includes var activeFiles = new HashSet(StringComparer.Ordinal); - // Walk each file, building the model and collecting issues + // pendingMappings collects each file's 'mappings:' root, deferred until the full + // requirements tree (across all included files) has been built + var pendingMappings = new List<(string Path, YamlMappingNode Root)>(); + + // Pass 1: walk each file, building the model (deferring mapping resolution) and collecting issues foreach (var path in paths) { - LoadFile(requirements, issues, path, seenIds, allRequirements, visitedFiles, activeFiles); + LoadFile(requirements, issues, path, seenIds, allRequirements, visitedFiles, activeFiles, pendingMappings); + } + + // Pass 2: now that the full requirements tree is built, resolve deferred test mappings + foreach (var (mappingPath, mappingRoot) in pendingMappings) + { + LoadDocumentMappings(issues, mappingPath, mappingRoot, allRequirements); } // Validate cycle-free requirement references on a best-effort basis, even if other errors exist @@ -117,8 +135,10 @@ internal static LoadResult Load(string[] paths) } /// - /// Reads and processes a single YAML file, walking its DOM tree to build model objects - /// and collect lint issues. Follows include directives recursively. + /// Reads and processes a single YAML file (one DOM parse per file), walking its DOM tree + /// to build model objects and collect lint issues, deferring mapping resolution. Follows + /// include directives recursively so the tree-build pass covers the full include graph + /// before any mapping is resolved. /// /// The requirements tree being built. /// The list to add lint issues to. @@ -127,11 +147,17 @@ internal static LoadResult Load(string[] paths) /// Dictionary of all built requirement objects, keyed by ID. /// Set of fully-resolved file paths already processed. /// Set of fully-resolved file paths in the current include call stack. + /// + /// Collects each file's mappings: document root, deferred for resolution in the + /// second pass (see ) after the full requirements tree has been built. + /// /// /// Handles file-not-found and I/O errors by recording them as objects /// and returning — never throws for domain errors. Uses activeFiles to detect circular /// file includes before following include directives. Uses visitedFiles to skip files - /// already processed (handles diamond-include patterns without re-processing). + /// already processed (handles diamond-include patterns without re-processing). Mapping + /// resolution is intentionally deferred (see pendingMappings) so that mappings may + /// reference requirements defined in files not yet visited at this point in the recursion. /// private static void LoadFile( Requirements requirements, @@ -140,7 +166,8 @@ private static void LoadFile( Dictionary seenIds, Dictionary allRequirements, HashSet visitedFiles, - HashSet activeFiles) + HashSet activeFiles, + List<(string Path, YamlMappingNode Root)> pendingMappings) { // Resolve to full path to detect duplicate includes string fullPath; @@ -224,8 +251,8 @@ private static void LoadFile( return; } - // Walk the document, building model objects and collecting issues - LoadDocument(requirements, issues, path, root, seenIds, allRequirements); + // Walk the document, building model objects and collecting issues (mapping resolution deferred) + LoadDocument(requirements, issues, path, root, seenIds, allRequirements, pendingMappings); // Track this file as active during recursive include processing activeFiles.Add(fullPath); @@ -250,7 +277,7 @@ private static void LoadFile( continue; } - LoadFile(requirements, issues, includePath, seenIds, allRequirements, visitedFiles, activeFiles); + LoadFile(requirements, issues, includePath, seenIds, allRequirements, visitedFiles, activeFiles, pendingMappings); } // Remove from active set after this file's includes are fully processed @@ -259,7 +286,7 @@ private static void LoadFile( /// /// Walks a document root mapping node, checking for unknown fields and loading - /// sections and test mappings. + /// sections; defers mapping resolution to the second pass (see ). /// /// The requirements tree being built. /// The list to add lint issues to. @@ -267,13 +294,18 @@ private static void LoadFile( /// The document root mapping node. /// Dictionary of requirement IDs already seen. /// Dictionary of all built requirement objects. + /// + /// Collects this document's mappings: root for deferred resolution once the full + /// requirements tree (across all included files) has been built. + /// private static void LoadDocument( Requirements requirements, List issues, string path, YamlMappingNode root, Dictionary seenIds, - Dictionary allRequirements) + Dictionary allRequirements, + List<(string Path, YamlMappingNode Root)> pendingMappings) { // Report unknown fields at document root foreach (var key in root.Children.Keys.OfType()) @@ -291,8 +323,9 @@ private static void LoadDocument( // Load top-level sections into the requirements tree LoadDocumentSections(requirements, issues, path, root, seenIds, allRequirements); - // Apply test mappings to already-loaded requirements - LoadDocumentMappings(issues, path, root, allRequirements); + // Defer test mapping resolution to the second pass, once the full requirements tree + // (across all included files) has been built + pendingMappings.Add((path, root)); } /// @@ -614,12 +647,17 @@ private static void LoadRequirement( } /// - /// Loads test mappings from the document root and applies them to already-built requirements. + /// Loads test mappings from a document root and applies them to already-built requirements. /// /// The list to add lint issues to. /// The file path for error locations. /// The document root mapping node. /// Dictionary of all built requirement objects. + /// + /// Called during the second pass (see ), once the full requirements tree + /// across all included files has been built, so mappings may reference requirements defined + /// in any file regardless of include order. + /// private static void LoadDocumentMappings( List issues, string path, @@ -695,8 +733,14 @@ private static void LoadMapping( return; } - // Resolve the referenced requirement (silently skip mappings to unknown IDs) - allRequirements.TryGetValue(idNode.Value, out var requirement); + // Resolve the referenced requirement, reporting an error for unknown mapping IDs + if (!allRequirements.TryGetValue(idNode.Value, out var requirement)) + { + issues.Add(new LintIssue( + $"{path}({idNode.Start.Line},{idNode.Start.Column})", + LintSeverity.Error, + $"Mapping references unknown requirement id '{idNode.Value}'")); + } // Extract and validate 'tests', then apply to the requirement var tests = GetValidatedStringList( diff --git a/test/DemaConsulting.ReqStream.Tests/Modeling/RequirementsLoaderTests.cs b/test/DemaConsulting.ReqStream.Tests/Modeling/RequirementsLoaderTests.cs index 8fb36bd..9576530 100644 --- a/test/DemaConsulting.ReqStream.Tests/Modeling/RequirementsLoaderTests.cs +++ b/test/DemaConsulting.ReqStream.Tests/Modeling/RequirementsLoaderTests.cs @@ -490,6 +490,82 @@ public void RequirementsLoader_Load_WithIncludes_LintsIncludedFiles() Assert.Contains("Unknown field 'unknown_field' in requirement", errors); } + /// + /// Test that a mapping declared in a parent file targeting a requirement defined in a + /// file reached via that parent's includes resolves correctly, regardless of the order + /// the files are processed in. + /// + [Fact] + public void RequirementsLoader_Load_WithMappingToIncludedFile_ResolvesMapping() + { + // Arrange: create an included file defining the target requirement, and a root file + // that includes it and declares a mapping targeting that requirement + var includedFile = _testDirectory.GetFilePath("included.yaml"); + File.WriteAllText(includedFile, @"sections: + - title: Included Section + requirements: + - id: INC-001 + title: Included requirement +"); + + var rootFile = _testDirectory.GetFilePath("root.yaml"); + File.WriteAllText(rootFile, @"includes: + - included.yaml +sections: + - title: Root Section + requirements: + - id: ROOT-001 + title: Root requirement +mappings: + - id: INC-001 + tests: + - Included_Test +"); + + // Act: load the root requirements file (which includes the other) + var result = Requirements.Load(rootFile); + + // Assert: no errors, and the mapping's test resolved against the included requirement + Assert.False(result.HasErrors); + var requirements = result.Requirements; + Assert.NotNull(requirements); + + var includedSection = requirements.Sections.Single(s => s.Title == "Included Section"); + var includedReq = includedSection.Requirements.Single(r => r.Id == "INC-001"); + Assert.Contains("Included_Test", includedReq.Tests); + } + + /// + /// Test that a mapping referencing an id that does not exist anywhere in the full + /// requirements tree reports an error instead of being silently dropped. + /// + [Fact] + public void RequirementsLoader_Load_WithUnresolvableMappingId_ReportsError() + { + // Arrange: create a YAML file with a mapping block that targets a nonexistent id + var reqFile = _testDirectory.GetFilePath("unresolvable-mapping-id.yaml"); + File.WriteAllText(reqFile, @"sections: + - title: Test Section + requirements: + - id: REQ-001 + title: Test requirement +mappings: + - id: DOES-NOT-EXIST + tests: + - SomeTest +"); + + // Act: load the requirements file + var result = Requirements.Load(reqFile); + + // Assert: exit code is 1 and error names the unresolved mapping id + Assert.True(result.HasErrors); + Assert.Null(result.Requirements); + Assert.Contains(result.Issues, i => i.Severity == LintSeverity.Error); + Assert.Contains(result.Issues, + i => i.Description.Contains("Mapping references unknown requirement id 'DOES-NOT-EXIST'")); + } + /// /// Test that a mapping with an unknown field reports an error. ///