Skip to content

Add architecture tests or architectural guardrails for NovaModuleTools. #100

Description

@stiwicourage

Task

Implement a maintainability improvement: add architecture tests or architectural guardrails for NovaModuleTools.

The goal is to protect the intended structure of the codebase so good layering and shared patterns do not drift over time.

Why this follow-up is needed

The repository is already moving toward clearer command, CLI, package, release, update, and shared layers.

As maintainability improvements are introduced, it becomes valuable to enforce some of the intended architecture with tests or lightweight repository rules so the structure remains intentional instead of depending only on convention.

Goal

After this change:

  • important architectural rules should be explicit
  • at least some of those rules should be test-enforced
  • future contributors should have clearer guardrails
  • maintainability improvements should be harder to regress accidentally

Likely files to inspect first

Repository structure / target areas

  • src/public/
  • src/private/shared/
  • src/private/cli/
  • src/private/release/
  • src/private/package/
  • src/private/update/
  • src/private/build/

Existing tests that could host architectural checks

  • tests/ArchitectureGuardrails.Tests.ps1
  • tests/CoverageGaps.Tests.ps1
  • tests/RemainingHelperCoverage.Tests.ps1
  • tests/NovaCommandModel.Tests.ps1
  • any test helpers useful for scanning repo files

Contribution guidance

  • README.md
  • CONTRIBUTING.md

What to do

  1. Define a small, high-value set of architectural rules for the repo.
  2. Choose lightweight enforcement mechanisms, preferably tests in tests/.
  3. Implement only the most valuable rules first.
  4. Keep the rules understandable and maintainable.
  5. Add or update contributor-facing guidance only if needed.

Example rule candidates

Choose only the ones that make sense after inspecting the codebase:

  • src/public/ commands should stay thin and should not perform direct JSON serialization.
  • Additional adapter seams such as self-update execution should stay behind dedicated helpers like Invoke-NovaModuleUpdateCommand.
  • Public commands should continue delegating to workflow/context helpers such as Get-Nova*WorkflowContext, Get-Nova*Context, and Invoke-Nova*Workflow instead of growing orchestration logic inline.
  • CLI-specific host interaction should remain under src/private/cli/.
  • Shared helpers should be used instead of reintroducing duplicate project.json write logic.
  • If stricter protection becomes valuable, project.json persistence should stay centralized behind Write-ProjectJsonData.
  • Deep internal helpers should avoid Write-Host unless they are explicitly UI-oriented.
  • Certain layers should avoid direct environment-variable access if a shared config helper exists.
  • Certain layers should avoid direct git/HTTP access if adapter helpers exist.

Next steps after the initial guardrails

The first architecture guardrails are now in place in tests/ArchitectureGuardrails.Tests.ps1.

The next high-value slices to add are:

  1. Add a guardrail for other adapter seams such as self-update execution so direct Update-Module usage stays behind Invoke-NovaModuleUpdateCommand.
  2. Add a guardrail that public commands keep delegating to workflow/context helpers rather than accumulating orchestration logic inline.
  3. Add a guardrail around shared project.json persistence paths if stricter protection is desired, so writes continue to flow through Write-ProjectJsonData.

Keep those additions incremental: introduce one new guardrail category at a time, validate it against the current repo shape, and prefer rules that reflect existing design rather than aspirational structure.

Design constraints

  • Keep the architecture rules small and high-value.
  • Avoid brittle tests that break on harmless refactors.
  • Prefer meaningful guardrails over noisy restrictions.
  • Do not create architecture rules that the current design clearly does not support.
  • Keep the enforcement mechanism easy for maintainers to understand.

Expected implementation shape

A good solution will likely:

  • define a handful of architectural invariants
  • implement them as tests or lightweight repository checks
  • document the intent if needed
  • avoid over-engineering or introducing a complex rule engine

Testing requirements

Add or update tests to cover at least these scenarios:

  1. The chosen architectural rules are enforced by automated checks.
  2. The tests fail clearly when a rule is violated.
  3. The tests are not excessively brittle.
  4. Existing test suites still pass.

Validation steps

Start with focused validation:

pwsh -NoLogo -NoProfile -Command 'Invoke-NovaBuild'
pwsh -NoLogo -NoProfile -Command 'Invoke-Pester ./tests/CoverageGaps.Tests.ps1 -Output Detailed'
pwsh -NoLogo -NoProfile -Command 'Invoke-Pester ./tests/RemainingHelperCoverage.Tests.ps1 -Output Detailed'
pwsh -NoLogo -NoProfile -Command 'Invoke-Pester ./tests/NovaCommandModel.Tests.ps1 -Output Detailed'

Also run:

git --no-pager diff --check

Documentation review requirements

After code changes, review and update if needed:

  • README.md
  • CONTRIBUTING.md
  • CHANGELOG.md

If no doc updates are needed, state that they were reviewed and why no change was necessary.

Definition of done

The task is only done when all of the following are true:

  1. A small set of meaningful architectural rules is defined.
  2. Those rules are enforced automatically.
  3. The enforcement is understandable and maintainable.
  4. Targeted tests pass.
  5. Invoke-NovaBuild passes.
  6. git diff --check passes.

Final report format

When done, report back with:

  1. Architectural risks addressed
  2. Files changed
  3. Rules introduced
  4. Enforcement approach
  5. Tests added/updated
  6. Validation commands run and results
  7. Documentation reviewed/updated
  8. Remaining follow-up ideas

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions