Skip to content

Commit 3bb05d0

Browse files
committed
feat(#194): add code quality matrix for src and tests
- Introduce a best-effort code quality matrix for source and test files. - Define warning and alert thresholds to guide maintainability. - Provide authoring guidance to help shape code quality from the start.
1 parent 0c72cc2 commit 3bb05d0

36 files changed

Lines changed: 303 additions & 95 deletions

.github/agents/powershell-developer.agent.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Implement PowerShell command and helper changes in the NovaModuleTools style.
1616
- Preserve Nova's `project.json`-driven build model; do not add hand-written source `.psm1` or module `.psd1` files.
1717
- Read `project.json` `Manifest.PowerShellHostVersion` before implementing PowerShell changes and keep source, tests, and examples compatible with that target.
1818
- Keep one externally called function per file and match the file name to that function. In `src/private/`, additional functions may stay only as same-file support helpers called by that file's entry function.
19+
- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort source-code matrix while shaping `src/**/*.ps1`.
1920
- Add or update source-mirrored tests and PlatyPS-compatible help docs for the changed behavior.
2021
- Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the bottom.
2122

@@ -40,6 +41,7 @@ Implement PowerShell command and helper changes in the NovaModuleTools style.
4041
- Keep `ShouldProcess` behavior where the command already supports it.
4142
- Keep raw infrastructure calls behind approved adapters.
4243
- Preserve existing command names, warning semantics, and output shape.
44+
- Keep new or heavily changed source functions inside the warning thresholds from `.github/instructions/code-quality-matrix.instructions.md` unless the scope explicitly justifies otherwise.
4345

4446
## Definition of done
4547

.github/agents/reviewer.agent.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Review changes for correctness, maintainability, test coverage, workflow safety,
2020
- Check that Nova projects still use generated `dist/` module files instead of hand-written source `.psm1` or module `.psd1` files.
2121
- Check changed PowerShell code, tests, and examples against `project.json` `Manifest.PowerShellHostVersion`; flag PowerShell 7.x-only constructs in projects that target `5.1` unless the change explicitly adds guarded compatibility handling.
2222
- Check that public commands/classes have matching PlatyPS-compatible help and that new source files have source-mirrored tests.
23+
- Review changed `src/**/*.ps1` and `tests/**/*.ps1` against `.github/instructions/code-quality-matrix.instructions.md`; flag new or heavily changed code that exceeds the warning thresholds without a clear, explicit reason.
2324
- Flag public files that do not keep exactly one top-level function, and flag private files that group multiple externally called functions instead of limiting extra functions to same-file support helpers. Also flag file/function name mismatches for public commands or externally called private helpers.
2425
- Flag broad catch-all test files when focused source-mirrored tests would make ownership clearer.
2526
- Flag any PSScriptAnalyzer rule excludes or suppressions; the code should be fixed instead.

.github/agents/test-engineer.agent.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Improve or maintain the repository's Pester coverage, coverage-gate behavior, an
1515
- Refactor brittle or duplicated tests into reusable support patterns.
1616
- Enforce a source-mirrored test layout for new projects and newly added or changed source files.
1717
- Keep test files and helpers compatible with the project's `project.json` `Manifest.PowerShellHostVersion` target.
18+
- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort test-code matrix while shaping `tests/**/*.ps1`.
1819
- Keep CI coverage output compatible with the CodeScene workflow.
1920

2021
## Inputs to inspect
@@ -41,6 +42,7 @@ Improve or maintain the repository's Pester coverage, coverage-gate behavior, an
4142
- Do not group unrelated source files into one broad test file when mirrored `tests/public`, `tests/private`, or `tests/classes` ownership is possible.
4243
- Do not introduce PowerShell 7.x-only test syntax or APIs into a project that targets `5.1` unless compatibility coverage is explicitly part of the scope.
4344
- If CodeScene flags a regression, refactor the tests or helpers instead of suppressing the finding.
45+
- Keep new or heavily changed tests inside the warning thresholds from `.github/instructions/code-quality-matrix.instructions.md` unless the scope explicitly justifies otherwise.
4446

4547
## Definition of done
4648

.github/copilot-instructions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Read these files before making non-trivial changes:
1515
3. `.github/pull_request_template.md`
1616
4. The relevant file in `.github/instructions/`
1717
5. The relevant skill under `.github/skills/<skill-name>/SKILL.md`
18+
6. `.github/instructions/code-quality-matrix.instructions.md` when shaping or reviewing `src/**/*.ps1` or `tests/**/*.ps1`
1819

1920
Prompt templates under `.github/prompts/*.prompt.md` are not auto-loaded. Reference them explicitly in chat when you want to use one of the repository's reusable task prompts.
2021

@@ -45,6 +46,7 @@ For new or not-yet-scoped work, start with `.github/agents/architect.agent.md` a
4546
- Keep `run.ps1` as the local quality loop: run ScriptAnalyzer first, then `Invoke-NovaBuild`, then `Test-NovaBuild`.
4647
- If `run.ps1` or `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` reports ScriptAnalyzer findings, fix them before review, handoff, or commit. Do not treat a failing local quality loop as an acceptable stopping point.
4748
- Keep file/function ownership explicit: `src/public/` files should own exactly one top-level function each, and `src/private/` files should expose at most one externally called function per file. Additional private functions may stay only as support helpers used from the same file, and the file name should match the function that owns the file.
49+
- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort quality matrix for `src/**/*.ps1` and `tests/**/*.ps1`; generated projects should follow that guidance through Agentic Copilot files, not by depending on a required `.codescene/code-health-rules.json`.
4850
- Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, and `RELEASE_NOTE.md` after every meaningful change.
4951
- Update tests when behavior changes.
5052
- Prefer existing helpers and support files over ad hoc duplication.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
applyTo: "src/**/*.ps1,tests/**/*.ps1"
3+
---
4+
5+
# Agentic code quality matrix
6+
7+
## Purpose
8+
9+
Use this file as the best-effort code quality matrix for generated and reviewed code in this repository.
10+
11+
The matrix translates the repository's preferred `src/**` and `tests/**` maintainability thresholds into agent guidance, so agents can shape code toward the expected quality from the start. This guidance does **not** require a `.codescene/code-health-rules.json` file in generated projects.
12+
13+
## How to use the matrix
14+
15+
- Treat warning thresholds as the default design ceiling for new or heavily changed code.
16+
- Treat alert thresholds as refactor-now signals for new or heavily changed code.
17+
- When a threshold has no alert value, stay below the warning threshold by default.
18+
- When a threshold is marked `not used`, do not optimize around it; focus on the other limits instead.
19+
- If a change must exceed a threshold, call it out in the handoff and explain the trade-off clearly.
20+
21+
## Source code matrix (`**/src/**`)
22+
23+
| Threshold | Warning | Alert | Best-effort authoring guidance |
24+
|----------------------------------------------------|------------------|-------|--------------------------------------------------------------------------------------------------------------|
25+
| `constructor_max_arguments` | `4` || Extract parameter objects or workflow-context objects before constructors exceed four inputs. |
26+
| `file_mean_cyclomatic_complexity_warning` | `26` || Split growing files or extract helpers before the file's average complexity drifts past this point. |
27+
| `function_complex_conditional_branches_warning` | `6` | `11` | Break up long boolean expressions before complex branch conditions become hard to read. |
28+
| `function_cyclomatic_complexity_warning` | `6` | `11` | Extract helpers and flatten control flow before a function becomes a local hotspot. |
29+
| `function_duplication_min_lines_of_code_for_check` | `6 lines` || Treat six or more repeated lines as an extraction candidate. |
30+
| `function_duplication_min_similarity_percentage` | `89% similarity` || Consolidate near-copy/paste logic even when names or literals differ slightly. |
31+
| `function_lines_of_code_warning` | `16` | `31` | Keep new or heavily changed functions short; extract helpers before they drift beyond the warning threshold. |
32+
| `function_max_arguments` | `4` || Introduce context objects, parameter objects, or helper abstractions before functions exceed four inputs. |
33+
| `function_nesting_depth_warning` | `6` || Flatten nested control flow early; do not let new logic grow into deep indentation towers. |
34+
35+
## Test code matrix (`**/tests/**`)
36+
37+
| Threshold | Warning | Alert | Best-effort authoring guidance |
38+
|----------------------------------------------------|------------|------------------------------|--------------------------------------------------------------------------------------------------------------------------|
39+
| `constructor_max_arguments` | `5` || Keep test helper constructors simple; prefer factory helpers or setup objects before they sprawl. |
40+
| `file_lines_of_code_for_warning` | `1000` | `5000` (`critical`: `10000`) | Split oversized test files by source ownership or behavior before they become hard to review. |
41+
| `file_mean_cyclomatic_complexity_warning` | `4` || Refactor test helpers or `BeforeAll` setup when a file becomes too branch-heavy overall. |
42+
| `file_primitive_obsession_percentage_for_warning` | `0.3` || Extract builders, fixtures, or named data objects when tests lean too heavily on raw strings, ints, and hashtables. |
43+
| `function_bumpy_road_bumps_for_warning` | `2` || Keep each test focused on one logical path; extract setup helpers when the flow breaks into many chunks. |
44+
| `function_bumpy_road_nesting_level_depth` | `2` || Keep test logic shallow and linear; avoid nested setup trees in individual test functions. |
45+
| `function_complex_conditional_branches_warning` | `2` | `10` | Prefer separate tests or helper functions over highly conditional test logic. |
46+
| `function_cyclomatic_complexity_warning` | `9` | `100` | Split test helpers or parameterized cases before one test function turns into control-flow-heavy code. |
47+
| `function_embedded_content_lines_of_code_warning` | `not used` | `not used` | Do not optimize for this metric; focus on the other thresholds instead. |
48+
| `function_lines_of_code_warning` | `70` | `500` | Keep new or heavily changed test functions compact; extract setup and assertion helpers when they grow too large. |
49+
| `function_max_arguments` | `4` || Keep helper/test function signatures tight; prefer fixtures or context objects over long parameter lists. |
50+
| `function_nesting_depth_warning` | `4` || Flatten nested assertions and setup paths before they become difficult to follow. |
51+
| `unit_test_consecutive_asserts_for_large_block` | `4` || Split assertion helpers or use richer comparison helpers before an assertion block grows past four consecutive asserts. |
52+
| `unit_test_suite_number_of_large_assertion_blocks` | `4` || If a suite accumulates multiple large assertion blocks, extract reusable assertion helpers instead of copy/paste growth. |
53+
54+
## Review expectations
55+
56+
- PowerShell implementation agents should use the source code matrix while shaping `src/**/*.ps1`.
57+
- Test-focused agents should use the test code matrix while shaping `tests/**/*.ps1`.
58+
- Review agents should flag new or heavily changed code that ignores the warning thresholds without a clear, justified reason.

.github/instructions/powershell-coding-standards.instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r
7575

7676
## Maintainability rules
7777

78+
- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort source-code matrix for `src/**/*.ps1`; warning thresholds are the default ceiling for new or heavily changed code.
7879
- Favor short functions and extracted helpers over large nested logic.
7980
- Avoid copy/paste across source or test files.
8081
- Add comments only when the code would otherwise be hard to follow.

.github/instructions/testing-policy.instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Use this file when changing production code, tests, coverage behavior, or CI tes
1616
- Reuse `*.TestSupport.ps1` helpers where possible.
1717
- For every new or changed `src/**/*.ps1` file, add or update the matching source-mirrored `.Tests.ps1` file.
1818
- Keep test files and helpers compatible with `project.json` `Manifest.PowerShellHostVersion`; if a project targets `5.1`, do not rely on PowerShell 7.x-only syntax, cmdlets, parameters, or APIs in the tests.
19+
- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort test-code matrix for `tests/**/*.ps1`; warning thresholds are the default ceiling for new or heavily changed tests.
1920
- Use broad guardrail, architecture, command-model, or integration tests only for behavior that genuinely spans multiple source files; do not use them as the default place for unit coverage of unrelated source files.
2021

2122
## Repository test structure

.github/prompts/implement-issue.prompt.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@ Implement the issue in the NovaModuleTools repository using the repository-local
1717
5. Preserve the Nova build model: use `project.json` and Nova commands for build/test/package/release behavior, and do not create hand-written source `.psm1` or module `.psd1` files.
1818
6. Inspect `project.json` `Manifest.PowerShellHostVersion` before changing PowerShell code, tests, or examples, and keep the implementation compatible with that target.
1919
7. Implement the smallest maintainable fix.
20-
8. Do not add PSScriptAnalyzer excluded rules or suppressions; fix analyzer findings in the code.
21-
9. If `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1` reports ScriptAnalyzer findings, fix them before handoff instead of only reporting the failure.
22-
10. Keep file/function ownership explicit: one externally called function per file, with private-file extras limited to same-file support helpers, and keep the file name aligned to the entry function.
23-
11. Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the bottom.
24-
12. Add or update the matching source-mirrored Pester file for every changed `src/**/*.ps1` file; if the behavior is genuinely cross-cutting, document which integration/guardrail test owns it and why a mirrored unit test is not practical.
25-
13. Add or update PlatyPS-compatible help under `docs/<ProjectName>/en-US/` when public commands or public classes change.
26-
14. Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, `RELEASE_NOTE.md`, help docs, and `docs/*.html` as applicable.
27-
15. If a commit message is requested, derive it from `$GIT_BRANCH_NAME` and the implemented change using the repository's Conventional Commit rules.
28-
16. Run the relevant validation, then summarize what changed, why, and how it was verified.
29-
17. If that summary is returned as Markdown or copy-ready UI output, format it according to the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`).
20+
8. Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort quality matrix for changed `src/**/*.ps1` and `tests/**/*.ps1`; keep new or heavily changed code within the relevant warning thresholds unless the scope explicitly justifies otherwise.
21+
9. Do not add PSScriptAnalyzer excluded rules or suppressions; fix analyzer findings in the code.
22+
10. If `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1` reports ScriptAnalyzer findings, fix them before handoff instead of only reporting the failure.
23+
11. Keep file/function ownership explicit: one externally called function per file, with private-file extras limited to same-file support helpers, and keep the file name aligned to the entry function.
24+
12. Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the bottom.
25+
13. Add or update the matching source-mirrored Pester file for every changed `src/**/*.ps1` file; if the behavior is genuinely cross-cutting, document which integration/guardrail test owns it and why a mirrored unit test is not practical.
26+
14. Add or update PlatyPS-compatible help under `docs/<ProjectName>/en-US/` when public commands or public classes change.
27+
15. Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, `RELEASE_NOTE.md`, help docs, and `docs/*.html` as applicable.
28+
16. If a commit message is requested, derive it from `$GIT_BRANCH_NAME` and the implemented change using the repository's Conventional Commit rules.
29+
17. Run the relevant validation, then summarize what changed, why, and how it was verified.
30+
18. If that summary is returned as Markdown or copy-ready UI output, format it according to the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`).
3031

3132
## Repository-specific reminders
3233

.github/prompts/improve-test-coverage.prompt.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ Improve changed-code coverage in NovaModuleTools without lowering maintainabilit
88
2. Read the nearby production code and the most relevant existing test/support files.
99
3. Place new tests in the source-mirrored path under `tests/` by default: one focused `.Tests.ps1` file per covered `src/**/*.ps1` file.
1010
4. Use an existing guardrail or integration test only when it intentionally owns genuinely cross-cutting behavior, and document that ownership in the handoff.
11-
5. Add the smallest test that proves the missing behavior.
12-
6. If setup is duplicated, refactor the tests before adding more assertions.
13-
7. Re-run the focused tests, then the repository quality loop if code changed.
14-
8. Recheck CodeScene coverage or Code Health if that was the original failure.
11+
5. Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort test-code matrix; keep new or heavily changed tests within the warning thresholds unless the scope explicitly justifies otherwise.
12+
6. Add the smallest test that proves the missing behavior.
13+
7. If setup is duplicated, refactor the tests before adding more assertions.
14+
8. Re-run the focused tests, then the repository quality loop if code changed.
15+
9. Recheck CodeScene coverage or Code Health if that was the original failure.
1516

1617
## Repository-specific reminders
1718

0 commit comments

Comments
 (0)