diff --git a/.cspell.json b/.cspell.json
new file mode 100644
index 0000000..8ff6bc1
--- /dev/null
+++ b/.cspell.json
@@ -0,0 +1,43 @@
+{
+ "version": "0.2",
+ "language": "en",
+ "words": [
+ "buildmark",
+ "BuildMark",
+ "copilot",
+ "cspell",
+ "csproj",
+ "Dema",
+ "demaconsulting",
+ "DEMACONSULTINGNUGETKEY",
+ "Dependabot",
+ "dependabot",
+ "dotnet",
+ "editorconfig",
+ "ibiqlik",
+ "markdownlint",
+ "mstest",
+ "ncipollo",
+ "nuget",
+ "nupkg",
+ "opencover",
+ "reqstream",
+ "snupkg",
+ "trx",
+ "yamllint"
+ ],
+ "ignorePaths": [
+ "node_modules",
+ ".git",
+ "bin",
+ "obj",
+ "*.nupkg",
+ "*.snupkg",
+ "*.dll",
+ "*.exe",
+ "*.trx",
+ "*.spdx.json",
+ "package-lock.json",
+ "yarn.lock"
+ ]
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..de4966e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,94 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# All files
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# Markdown files
+[*.md]
+trim_trailing_whitespace = false
+
+# YAML files
+[*.{yml,yaml}]
+indent_size = 2
+
+# JSON files
+[*.json]
+indent_size = 2
+
+# XML files
+[*.{xml,csproj,props,targets}]
+indent_size = 2
+
+# C# files
+[*.cs]
+indent_size = 4
+
+# Code style rules
+csharp_prefer_braces = true:warning
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+
+# Naming conventions
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = warning
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+# Organize usings
+dotnet_sort_system_directives_first = true
+dotnet_separate_import_directive_groups = false
+
+# Code quality - set to suggestion to not break existing code
+dotnet_code_quality_unused_parameters = all:suggestion
+
+# Nullable reference types
+csharp_nullable_reference_types = enable
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..70ba481
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,115 @@
+---
+name: 🐛 Bug Report
+description: Report a bug or issue with the BuildMark tool
+title: "[Bug]: "
+labels: ["bug"]
+assignees: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to report a bug! Please fill out the sections below to help us understand and
+ fix the issue.
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: A clear and concise description of what the bug is.
+ placeholder: Describe the bug...
+ validations:
+ required: true
+
+ - type: textarea
+ id: steps-to-reproduce
+ attributes:
+ label: Steps to Reproduce
+ description: Detailed steps to reproduce the behavior
+ placeholder: |
+ 1. Run BuildMark with command '...'
+ 2. Provide input file '...'
+ 3. Observe error...
+ value: |
+ 1.
+ 2.
+ 3.
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected-behavior
+ attributes:
+ label: Expected Behavior
+ description: A clear and concise description of what you expected to happen
+ placeholder: Describe what should happen...
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual-behavior
+ attributes:
+ label: Actual Behavior
+ description: A clear and concise description of what actually happened
+ placeholder: Describe what actually happens...
+ validations:
+ required: true
+
+ - type: textarea
+ id: code-sample
+ attributes:
+ label: Code Sample
+ description: If applicable, provide a minimal code sample that reproduces the issue
+ placeholder: |
+ ```csharp
+ // Your code here
+ ```
+ render: csharp
+
+ - type: input
+ id: version
+ attributes:
+ label: Tool Version
+ description: What version of the BuildMark tool are you using?
+ placeholder: e.g., 1.0.0
+ validations:
+ required: true
+
+ - type: dropdown
+ id: dotnet-version
+ attributes:
+ label: .NET Version
+ description: What version of .NET are you using?
+ options:
+ - ".NET 8"
+ - ".NET 9"
+ - ".NET 10"
+ - Other (please specify in additional context)
+ validations:
+ required: true
+
+ - type: input
+ id: os
+ attributes:
+ label: Operating System
+ description: What operating system are you using?
+ placeholder: e.g., Windows 11, Ubuntu 22.04, macOS 14.0
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional Context
+ description: Add any other context about the problem here, such as error messages, stack traces, or screenshots
+ placeholder: Any additional information...
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ description: Please confirm the following
+ options:
+ - label: I have searched existing issues to ensure this is not a duplicate
+ required: true
+ - label: I have provided a clear description of the problem
+ required: true
+ - label: I have included steps to reproduce the issue
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..820af86
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,9 @@
+---
+blank_issues_enabled: false
+contact_links:
+ - name: 📚 Documentation
+ url: https://github.com/demaconsulting/BuildMark
+ about: Read the documentation for BuildMark
+ - name: 💬 Discussions
+ url: https://github.com/demaconsulting/BuildMark/discussions
+ about: Ask questions and discuss with the community
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..fd52f52
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,102 @@
+---
+name: ✨ Feature Request
+description: Suggest a new feature or enhancement for the BuildMark tool
+title: "[Feature]: "
+labels: ["enhancement"]
+assignees: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for suggesting a feature! Please fill out the sections below to help us understand your request.
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem Statement
+ description: Is your feature request related to a problem? Please describe.
+ placeholder: I'm frustrated when... / I need to be able to...
+ validations:
+ required: true
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: Proposed Solution
+ description: Describe the solution you'd like to see
+ placeholder: A clear and concise description of what you want to happen
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives Considered
+ description: Describe any alternative solutions or features you've considered
+ placeholder: A clear and concise description of any alternative solutions or features
+
+ - type: textarea
+ id: examples
+ attributes:
+ label: Usage Examples
+ description: If applicable, provide examples of how this feature would be used
+ placeholder: |
+ ```csharp
+ // Example usage
+ buildmark --input report.json --output report.md --feature-flag
+ ```
+ render: csharp
+
+ - type: textarea
+ id: benefits
+ attributes:
+ label: Benefits
+ description: Explain why this enhancement would be useful to BuildMark users
+ placeholder: This would be useful because...
+ validations:
+ required: true
+
+ - type: dropdown
+ id: priority
+ attributes:
+ label: Priority
+ description: How important is this feature to you?
+ options:
+ - Low - Nice to have
+ - Medium - Would improve my workflow
+ - High - Blocking my use case
+ validations:
+ required: true
+
+ - type: dropdown
+ id: willingness
+ attributes:
+ label: Willingness to Contribute
+ description: Would you be willing to contribute this feature?
+ options:
+ - "Yes, I can submit a pull request"
+ - "Yes, with guidance from maintainers"
+ - "No, but I can help test it"
+ - "No, I'm just suggesting"
+ validations:
+ required: true
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional Context
+ description: Add any other context, screenshots, or links about the feature request here
+ placeholder: Any additional information...
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ description: Please confirm the following
+ options:
+ - label: I have searched existing issues to ensure this is not a duplicate
+ required: true
+ - label: I have provided a clear description of the feature
+ required: true
+ - label: I have explained why this feature would be useful
+ required: true
diff --git a/.github/agents/documentation-writer.md b/.github/agents/documentation-writer.md
new file mode 100644
index 0000000..41d5dba
--- /dev/null
+++ b/.github/agents/documentation-writer.md
@@ -0,0 +1,47 @@
+---
+name: Documentation Writer
+description: Expert agent for BuildMark documentation, requirements.yaml maintenance, and markdown/spell/YAML linting
+---
+
+# Documentation Writer - BuildMark
+
+Create and maintain clear, accurate documentation for the BuildMark .NET CLI tool.
+
+## When to Invoke This Agent
+
+Invoke the documentation-writer agent for:
+
+- Documentation updates and reviews (README.md, guides, CONTRIBUTING.md, etc.)
+- Requirements updates in `requirements.yaml` (adding, modifying, or reviewing requirements)
+- Ensuring requirements are properly linked to tests
+- Markdown, spell checking, and YAML linting issues
+- Documentation structure and organization improvements
+
+For requirements quality: After this agent updates requirements, invoke the software-quality-enforcer
+agent to ensure requirements have proper test coverage and quality.
+
+## BuildMark-Specific Rules
+
+### Markdown
+
+- **README.md ONLY**: Absolute URLs (shipped in NuGet) - `https://github.com/demaconsulting/BuildMark/blob/main/FILE.md`
+- **All other .md**: Reference-style links - `[text][ref]` with `[ref]: url` at file end
+- Max 120 chars/line, lists need blank lines (MD032)
+
+### Requirements (requirements.yaml)
+
+- All requirements MUST link to tests (prefer `BuildMark_*` self-validation over unit tests)
+- When adding features: add requirement + test linkage
+- Test CLI commands before documenting
+- After updating requirements, recommend invoking software-quality-enforcer to verify test quality
+
+### Linting Before Commit
+
+- markdownlint (see CI workflow)
+- cspell (add terms to `.cspell.json`)
+- yamllint
+
+## Don't
+
+- Change code to match docs
+- Add docs for non-existent features
diff --git a/.github/agents/project-maintainer.md b/.github/agents/project-maintainer.md
new file mode 100644
index 0000000..508d314
--- /dev/null
+++ b/.github/agents/project-maintainer.md
@@ -0,0 +1,50 @@
+---
+name: Project Maintainer
+description: Expert agent for BuildMark project management, dependencies, CI/CD, releases, and requirements traceability
+---
+
+# Project Maintainer - BuildMark
+
+Maintain BuildMark .NET CLI tool infrastructure, dependencies, releases, and requirements traceability.
+
+## BuildMark-Specific
+
+### Build
+
+- Targets: .NET 8.0, 9.0, 10.0
+- Zero warnings required (TreatWarningsAsErrors=true)
+
+### Workflows (.github/workflows)
+
+- **build.yaml**: Reusable (checkout, setup .NET, restore, build Release, test, pack, upload)
+- **build_on_push.yaml**: Main CI/CD (quality checks, Windows+Linux builds)
+
+### Requirements Traceability (Critical)
+
+- `requirements.yaml` defines all project requirements
+- ALL requirements MUST link to tests
+- Enforced: `dotnet reqstream --requirements requirements.yaml --tests "test-results/**/*.trx" --enforce`
+- Published as PDFs: "BuildMark Requirements.pdf", "BuildMark Trace Matrix.pdf"
+
+### Quality Gates (Must Pass)
+
+1. Build (zero warnings)
+2. All tests pass
+3. Markdown/spell/YAML linting
+4. Requirements enforcement
+5. CodeQL security
+
+### Commands
+
+```bash
+dotnet tool restore && dotnet restore
+dotnet build --no-restore --configuration Release
+dotnet test --no-build --configuration Release
+dotnet pack --no-build --configuration Release
+```
+
+## Don't
+
+- Merge without CI passing
+- Ignore failing tests/builds
+- Disable quality checks
diff --git a/.github/agents/software-quality-enforcer.md b/.github/agents/software-quality-enforcer.md
new file mode 100644
index 0000000..47e57a3
--- /dev/null
+++ b/.github/agents/software-quality-enforcer.md
@@ -0,0 +1,34 @@
+---
+name: Software Quality Enforcer
+description: Code quality specialist for BuildMark - enforce testing, coverage >80%, static analysis, and zero warnings
+---
+
+# Software Quality Enforcer - BuildMark
+
+Enforce quality standards for BuildMark .NET CLI tool.
+
+## Quality Gates (ALL Must Pass)
+
+- Zero build warnings (TreatWarningsAsErrors=true)
+- All tests passing
+- Code coverage >80%
+- Static analysis (Microsoft.CodeAnalysis.NetAnalyzers, SonarAnalyzer.CSharp)
+- Code formatting (.editorconfig compliance)
+- Markdown/spell/YAML linting
+- Requirements traceability (all linked to tests)
+
+## BuildMark-Specific
+
+- **Test Naming**: `ClassName_MethodUnderTest_Scenario_ExpectedBehavior` (for requirements traceability)
+- **Test Linkage**: All requirements MUST link to tests (prefer `BuildMark_*` self-validation)
+- **XML Docs**: On ALL members (public/internal/private) with spaces after `///`
+- **No external runtime deps**: Only essential dependencies allowed
+
+## Commands
+
+```bash
+dotnet build --configuration Release # Zero warnings required
+dotnet test --configuration Release --collect "XPlat Code Coverage"
+dotnet format --verify-no-changes
+dotnet reqstream --requirements requirements.yaml --tests "test-results/**/*.trx" --enforce
+```
diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml
new file mode 100644
index 0000000..a291005
--- /dev/null
+++ b/.github/codeql-config.yml
@@ -0,0 +1,10 @@
+---
+name: "CodeQL Configuration for BuildMark"
+
+# Paths to exclude from analysis
+paths-ignore:
+ - '**/bin/**'
+ - '**/obj/**'
+ - '**/TestResults/**'
+ - '**/*.Designer.cs'
+ - '**/*.generated.cs'
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..72aa9c9
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,20 @@
+---
+version: 2
+updates:
+ # GitHub Actions
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ labels:
+ - "dependencies"
+ - "github-actions"
+
+ # NuGet dependencies
+ - package-ecosystem: "nuget"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ labels:
+ - "dependencies"
+ - "nuget"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..ad3c25c
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,63 @@
+# Pull Request
+
+## Description
+
+
+
+## Type of Change
+
+
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] Documentation update
+- [ ] Code quality improvement
+
+## Related Issues
+
+
+
+Closes #
+
+## Pre-Submission Checklist
+
+Before submitting this pull request, ensure you have completed the following:
+
+### Build and Test
+
+- [ ] Code builds successfully: `dotnet build --configuration Release`
+- [ ] All tests pass: `dotnet test --configuration Release`
+- [ ] Code produces zero warnings
+
+### Code Quality
+
+- [ ] Code formatting is correct: `dotnet format --verify-no-changes`
+- [ ] New code has appropriate XML documentation comments
+- [ ] Static analyzer warnings have been addressed
+
+### Quality Checks
+
+Please run the following checks before submitting:
+
+- [ ] **Spell checker passes**: `cspell "**/*.{md,cs}"`
+- [ ] **Markdown linter passes**: `markdownlint "**/*.md"`
+- [ ] **YAML linter passes**: `yamllint '**/*.{yml,yaml}'`
+
+### Testing
+
+- [ ] Added unit tests for new functionality
+- [ ] Updated existing tests if behavior changed
+- [ ] All tests follow the AAA (Arrange, Act, Assert) pattern
+- [ ] Test coverage is maintained or improved
+
+### Documentation
+
+- [ ] Updated README.md (if applicable)
+- [ ] Updated ARCHITECTURE.md (if applicable)
+- [ ] Added code examples for new features (if applicable)
+- [ ] Updated requirements.yaml (if applicable)
+
+## Additional Notes
+
+
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
new file mode 100644
index 0000000..fc5f08a
--- /dev/null
+++ b/.github/workflows/build.yaml
@@ -0,0 +1,206 @@
+---
+on:
+ workflow_call:
+ inputs:
+ version:
+ required: true
+ type: string
+ secrets:
+ SONAR_TOKEN:
+ required: true
+
+jobs:
+ quality-checks:
+ name: Quality Checks
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+
+ - name: Run markdown linter
+ uses: DavidAnson/markdownlint-cli2-action@v22
+ with:
+ globs: '**/*.md'
+
+ - name: Run spell checker
+ uses: streetsidesoftware/cspell-action@v8
+ with:
+ files: '**/*.{md,cs}'
+
+ - name: Run YAML linter
+ uses: ibiqlik/action-yamllint@v3
+ with:
+ config_file: .yamllint.yaml
+
+ build:
+ name: Build ${{ matrix.os }}
+ needs: quality-checks
+ permissions:
+ contents: read
+ pull-requests: write
+
+ strategy:
+ matrix:
+ os: [windows-latest, ubuntu-latest]
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+
+ - name: Setup dotnet
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: |
+ 8.x
+ 9.x
+ 10.x
+
+ - name: Restore Dependencies
+ run: >
+ dotnet restore
+
+ - name: Build
+ run: >
+ dotnet build
+ --no-restore
+ --configuration Release
+ --property:Version=${{ inputs.version }}
+
+ - name: Test
+ run: >
+ dotnet test
+ --no-build
+ --configuration Release
+ --property:Version=${{ inputs.version }}
+ --collect "XPlat Code Coverage;Format=opencover"
+ --logger "trx;LogFilePrefix=${{ matrix.os }}"
+ --results-directory test-results
+
+ - name: Create Dotnet Tool
+ run: >
+ dotnet pack
+ --no-build
+ --no-restore
+ --property:PackageVersion=${{ inputs.version }}
+
+ - name: Upload Test Results
+ uses: actions/upload-artifact@v6
+ with:
+ name: test-results-${{ matrix.os }}
+ path: test-results/*.trx
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v6
+ with:
+ name: artifacts-${{ matrix.os }}
+ path: |
+ src/DemaConsulting.BuildMark/bin/Release/*.nupkg
+ src/DemaConsulting.BuildMark/bin/Release/*.snupkg
+
+ codeql:
+ name: CodeQL Analysis
+ runs-on: ubuntu-latest
+ needs: quality-checks
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v4
+ with:
+ languages: csharp
+ queries: security-and-quality
+ config-file: ./.github/codeql-config.yml
+
+ - name: Setup dotnet
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: |
+ 8.x
+ 9.x
+ 10.x
+
+ - name: Restore Dependencies
+ run: >
+ dotnet restore
+
+ - name: Build
+ run: >
+ dotnet build
+ --no-restore
+ --configuration Release
+ --property:Version=${{ inputs.version }}
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v4
+ with:
+ category: "/language:csharp"
+ output: sarif-results
+ upload: false
+
+ - name: Upload CodeQL SARIF
+ uses: actions/upload-artifact@v6
+ with:
+ name: codeql-sarif
+ path: sarif-results/csharp.sarif
+
+ integration-test:
+ name: Integration Test ${{ matrix.os }} .NET ${{ matrix.dotnet-version }}
+ runs-on: ${{ matrix.os }}
+ needs: build
+ permissions:
+ contents: read
+
+ strategy:
+ matrix:
+ os: [windows-latest, ubuntu-latest]
+ dotnet-version: ['8.x', '9.x', '10.x']
+
+ steps:
+ - name: Download package
+ uses: actions/download-artifact@v7
+ with:
+ name: artifacts-${{ matrix.os }}
+ path: packages
+
+ - name: Setup dotnet
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: ${{ matrix.dotnet-version }}
+
+ - name: Install tool from package
+ shell: bash
+ run: |
+ echo "Installing package version ${{ inputs.version }} from: packages/"
+ dotnet tool install --global \
+ --add-source packages \
+ --version ${{ inputs.version }} \
+ DemaConsulting.BuildMark
+
+ - name: Test version display
+ shell: bash
+ run: |
+ echo "Testing buildmark --version..."
+ buildmark --version || { echo "✗ Version command failed"; exit 1; }
+ echo "✓ Version command succeeded"
+
+ - name: Test help display
+ shell: bash
+ run: |
+ echo "Testing buildmark --help..."
+ buildmark --help || { echo "✗ Help command failed"; exit 1; }
+ echo "✓ Help command succeeded"
diff --git a/.github/workflows/build_on_push.yaml b/.github/workflows/build_on_push.yaml
new file mode 100644
index 0000000..d536b8e
--- /dev/null
+++ b/.github/workflows/build_on_push.yaml
@@ -0,0 +1,22 @@
+---
+name: Build on Push
+
+on:
+ push: # On push to any branch
+ workflow_dispatch: # Allow manual trigger
+ schedule: # 5PM UTC every Monday
+ - cron: '0 17 * * 1'
+
+jobs:
+ build:
+ name: Build
+ permissions:
+ actions: read
+ contents: read
+ pull-requests: write
+ security-events: write
+ uses: ./.github/workflows/build.yaml
+ with:
+ version: 0.0.0-run.${{ github.run_number }}
+ secrets:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..7b1331c
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,71 @@
+---
+name: Release
+
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Release version (1.0.0)'
+ required: true
+ type: string
+ publish:
+ description: 'Publish type'
+ required: true
+ type: choice
+ options:
+ - none
+ - release
+ - publish
+
+jobs:
+ build:
+ name: Build
+ permissions:
+ actions: read
+ contents: read
+ pull-requests: write
+ security-events: write
+ uses: ./.github/workflows/build.yaml
+ with:
+ version: ${{ inputs.version }}
+ secrets:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ needs: build
+ permissions:
+ contents: write
+
+ steps:
+ - name: Setup dotnet
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: |
+ 8.x
+ 9.x
+ 10.x
+
+ - name: Download package artifacts
+ uses: actions/download-artifact@v7
+ with:
+ name: artifacts-ubuntu-latest
+ path: artifacts
+
+ - name: Create GitHub Release
+ if: inputs.publish == 'release' || inputs.publish == 'publish'
+ uses: ncipollo/release-action@v1
+ with:
+ tag: ${{ inputs.version }}
+ artifacts: artifacts/*
+ generateReleaseNotes: true
+
+ - name: Publish to NuGet.org
+ if: inputs.publish == 'publish'
+ run: |
+ set -e
+ dotnet nuget push artifacts/*.nupkg \
+ --api-key ${{ secrets.DEMACONSULTINGNUGETKEY }} \
+ --source https://api.nuget.org/v3/index.json \
+ --skip-duplicate
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea48538
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,37 @@
+.vs
+*.bak
+*.user
+
+bin/
+obj/
+TestResults/
+
+# Code coverage reports
+coverage/
+*.coverage
+*.coveragexml
+*.opencover.xml
+
+# Test results
+*.trx
+test-results/
+*.log
+
+# Temporary files
+*.tmp
+.DS_Store
+
+# Node.js dependencies
+node_modules/
+package-lock.json
+
+# Generated documentation
+docs/*.pdf
+docs/guide/*.html
+docs/requirements/requirements.md
+docs/requirements/*.html
+docs/tracematrix/tracematrix.md
+docs/tracematrix/*.html
+docs/quality/sonar-quality.md
+docs/quality/codeql-quality.md
+docs/quality/*.html
diff --git a/.markdownlint.json b/.markdownlint.json
new file mode 100644
index 0000000..e3884ab
--- /dev/null
+++ b/.markdownlint.json
@@ -0,0 +1,8 @@
+{
+ "default": true,
+ "MD003": { "style": "atx" },
+ "MD007": { "indent": 2 },
+ "MD013": { "line_length": 120 },
+ "MD033": false,
+ "MD041": false
+}
diff --git a/.yamllint.yaml b/.yamllint.yaml
new file mode 100644
index 0000000..9cb6241
--- /dev/null
+++ b/.yamllint.yaml
@@ -0,0 +1,25 @@
+---
+# yamllint configuration for BuildMark
+# This configuration defines the rules for YAML file linting
+
+extends: default
+
+rules:
+ # Allow 'on:' in GitHub Actions workflows (not a boolean value)
+ truthy:
+ allowed-values: ['true', 'false', 'on', 'off']
+ check-keys: true
+
+ # Allow longer lines for URLs and complex expressions
+ line-length:
+ max: 120
+ level: error
+
+ # Ensure proper indentation
+ indentation:
+ spaces: 2
+ indent-sequences: true
+
+ # Ensure proper comment formatting
+ comments:
+ min-spaces-from-content: 2
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..e613609
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,62 @@
+# Agent Quick Reference
+
+Project-specific guidance for agents working on BuildMark - a .NET CLI tool for generating markdown build notes.
+
+## Tech Stack
+
+- C# 12, .NET 8.0/9.0/10.0, MSTest, dotnet CLI, NuGet
+
+## Key Files
+
+- **`requirements.yaml`** - All requirements with test linkage (enforced via `dotnet reqstream --enforce`)
+- **`.editorconfig`** - Code style (file-scoped namespaces, 4-space indent, UTF-8+BOM, LF endings)
+- **`.cspell.json`, `.markdownlint.json`, `.yamllint.yaml`** - Linting configs
+
+## Requirements (BuildMark-Specific)
+
+- Link ALL requirements to tests (prefer `BuildMark_*` self-validation over unit tests)
+- Enforced in CI: `dotnet reqstream --requirements requirements.yaml --tests "test-results/**/*.trx" --enforce`
+- When adding features: add requirement + link to test
+
+## Testing (BuildMark-Specific)
+
+- **Test Naming**: `ClassName_MethodUnderTest_Scenario_ExpectedBehavior` (for requirements traceability)
+- **MSTest v4**: Use `Assert.HasCount()`, `Assert.IsEmpty()`, `Assert.DoesNotContain()` (not old APIs)
+- **Console Tests**: Always save/restore `Console.Out` in try/finally
+
+## Code Style (BuildMark-Specific)
+
+- **XML Docs**: On ALL members (public/internal/private) with spaces after `///` in summaries
+- **Errors**: `ArgumentException` for parsing, `InvalidOperationException` for runtime, Write* only after success
+- **No code duplication**: Extract to properties/methods
+
+## Linting (BuildMark-Specific)
+
+- **README.md**: Absolute URLs only (shipped in NuGet package)
+- **Other .md**: Reference-style links `[text][ref]` with `[ref]: url` at end
+- **All linters must pass locally**: markdownlint, cspell, yamllint (see CI workflows for commands)
+
+## Build & Quality (Quick Reference)
+
+```bash
+# Standard build/test
+dotnet build --configuration Release && dotnet test --configuration Release
+
+# Pre-finalization checklist (in order):
+# 1. Build/test (zero warnings required)
+# 2. code_review tool
+# 3. codeql_checker tool
+# 4. All linters (markdownlint, cspell, yamllint)
+# 5. Requirements: dotnet reqstream --requirements requirements.yaml --tests "test-results/**/*.trx" --enforce
+```
+
+## Custom Agents
+
+Delegate tasks to specialized agents for better results:
+
+- **documentation-writer** - Invoke for: documentation updates/reviews, requirements.yaml changes,
+ markdown/spell/YAML linting
+- **project-maintainer** - Invoke for: dependency updates, CI/CD maintenance, releases, requirements
+ traceability enforcement
+- **software-quality-enforcer** - Invoke for: code quality reviews, test coverage verification (>80%),
+ static analysis, zero-warning builds, requirements test quality
diff --git a/DemaConsulting.BuildMark.slnx b/DemaConsulting.BuildMark.slnx
new file mode 100644
index 0000000..8b257ba
--- /dev/null
+++ b/DemaConsulting.BuildMark.slnx
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Icon.png b/Icon.png
new file mode 100644
index 0000000..fe8a0ae
Binary files /dev/null and b/Icon.png differ
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a665927
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 DEMA Consulting
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index e60336e..28dae75 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
# BuildMark
+
Tool to generate Markdown Build Notes
diff --git a/src/DemaConsulting.BuildMark/DemaConsulting.BuildMark.csproj b/src/DemaConsulting.BuildMark/DemaConsulting.BuildMark.csproj
new file mode 100644
index 0000000..0a93b8b
--- /dev/null
+++ b/src/DemaConsulting.BuildMark/DemaConsulting.BuildMark.csproj
@@ -0,0 +1,71 @@
+
+
+
+ Exe
+ net8.0;net9.0;net10.0
+ 12
+ enable
+ enable
+
+
+ true
+ buildmark
+ DemaConsulting.BuildMark
+ 0.0.0
+ DEMA Consulting
+ DEMA Consulting
+ Tool to generate Markdown Build Notes
+ MIT
+ https://github.com/demaconsulting/BuildMark
+ https://github.com/demaconsulting/BuildMark
+ README.md
+ Icon.png
+ build;markdown;documentation
+ Copyright DEMA Consulting
+ BuildMark Tool
+ DemaConsulting.BuildMark
+
+
+ true
+ snupkg
+ true
+ true
+ true
+
+
+ true
+ True
+ true
+ true
+ latest
+
+
+ true
+ $(PackageId)
+ $(Version)
+ Organization: $(Company)
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DemaConsulting.BuildMark/Program.cs b/src/DemaConsulting.BuildMark/Program.cs
new file mode 100644
index 0000000..ae5c8f5
--- /dev/null
+++ b/src/DemaConsulting.BuildMark/Program.cs
@@ -0,0 +1,74 @@
+// Copyright (c) DEMA Consulting
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System.Reflection;
+
+namespace DemaConsulting.BuildMark;
+
+///
+/// Main program entry point for the BuildMark tool.
+///
+internal static class Program
+{
+ ///
+ /// Gets the application version string.
+ ///
+ public static string Version
+ {
+ get
+ {
+ var assembly = typeof(Program).Assembly;
+ return assembly.GetCustomAttribute()?.InformationalVersion
+ ?? assembly.GetName().Version?.ToString()
+ ?? "0.0.0";
+ }
+ }
+
+ ///
+ /// Main entry point for the BuildMark tool.
+ ///
+ /// Command-line arguments.
+ /// Exit code: 0 for success, non-zero for failure.
+ private static int Main(string[] args)
+ {
+ // Print version if --version is specified
+ if (args.Length > 0 && args[0] == "--version")
+ {
+ Console.WriteLine($"BuildMark version {Version}");
+ return 0;
+ }
+
+ // Print help if --help is specified or no arguments
+ if (args.Length == 0 || args[0] == "--help")
+ {
+ Console.WriteLine("BuildMark - Tool to generate Markdown Build Notes");
+ Console.WriteLine();
+ Console.WriteLine("Usage: buildmark [options]");
+ Console.WriteLine();
+ Console.WriteLine("Options:");
+ Console.WriteLine(" --version Display version information");
+ Console.WriteLine(" --help Display this help message");
+ return 0;
+ }
+
+ Console.WriteLine("Hello from BuildMark!");
+ return 0;
+ }
+}
diff --git a/test/DemaConsulting.BuildMark.Tests/AssemblyInfo.cs b/test/DemaConsulting.BuildMark.Tests/AssemblyInfo.cs
new file mode 100644
index 0000000..495b4f8
--- /dev/null
+++ b/test/DemaConsulting.BuildMark.Tests/AssemblyInfo.cs
@@ -0,0 +1,21 @@
+// Copyright (c) DEMA Consulting
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+[assembly: DoNotParallelize]
diff --git a/test/DemaConsulting.BuildMark.Tests/DemaConsulting.BuildMark.Tests.csproj b/test/DemaConsulting.BuildMark.Tests/DemaConsulting.BuildMark.Tests.csproj
new file mode 100644
index 0000000..540e396
--- /dev/null
+++ b/test/DemaConsulting.BuildMark.Tests/DemaConsulting.BuildMark.Tests.csproj
@@ -0,0 +1,39 @@
+
+
+ net8.0;net9.0;net10.0
+ 12
+ enable
+ enable
+ true
+ true
+ true
+ latest
+
+ false
+ true
+ True
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/test/DemaConsulting.BuildMark.Tests/ProgramTests.cs b/test/DemaConsulting.BuildMark.Tests/ProgramTests.cs
new file mode 100644
index 0000000..44937ad
--- /dev/null
+++ b/test/DemaConsulting.BuildMark.Tests/ProgramTests.cs
@@ -0,0 +1,42 @@
+// Copyright (c) DEMA Consulting
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+namespace DemaConsulting.BuildMark.Tests;
+
+///
+/// Tests for the Program class.
+///
+[TestClass]
+public class ProgramTests
+{
+ ///
+ /// Test that the version property returns a valid version string.
+ ///
+ [TestMethod]
+ public void Program_Version_ReturnsValidVersion()
+ {
+ // Act
+ var version = Program.Version;
+
+ // Assert
+ Assert.IsNotNull(version);
+ Assert.IsFalse(string.IsNullOrWhiteSpace(version));
+ }
+}