What module health is
Module health is a small record, kept per module of your codebase, that says how stable that module has been: its test coverage, how often things have gone wrong in it, and how much it changes. paqad uses it to raise the risk of a change that touches a shaky module, which can move the change to a heavier lane.
Each module gets one JSON file at .paqad/module-health/<module>.json. The folder is git-ignored, so the records are local to each machine. Profiles are created on demand as modules collect evidence; onboarding does not create them, and a project with no profiles yet is normal. Module names come from your module map, docs/instructions/rules/module-map.yml.
Everything on this page is computed by scripts. No AI judgement is involved.
What a profile contains
| Field | Meaning |
|---|---|
module | The module name. |
tier | stable, moderate, fragile or unknown, derived from the metrics. |
metrics.coverage_pct | Test coverage, 0 to 100. |
metrics.defect_frequency | A running count of problems seen in the module, such as failed tests and failed gates. |
metrics.contract_stability | A score from 0 to 1 for how steady the module's behaviour has been. |
metrics.change_velocity | How often the module changes. |
metrics.tests_passing, tests_failing, tests_total | Test counts, when a test report is available. |
metrics.mutation_score | The share of deliberately introduced bugs the tests caught, when mutation testing has run. |
blocked_metrics | Metrics that could not be measured, each with a reason, for example contract_stability:no_public_api_extractor. A missing metric is left empty, never guessed or set to zero. |
updated_at | When the profile was last written. |
How the tier is worked out
The tier is a fixed rule over three metrics: coverage, defect frequency and contract stability.
| Tier | Rule |
|---|---|
unknown | All three are empty. |
stable | Coverage at least 80, defect frequency at most 2, and contract stability at least 0.85. All three must be present. |
moderate | Not stable, but coverage at least 50 and defect frequency at most 5. Both must be present. |
fragile | Everything else. |
Because "everything else" is fragile, a module with some measurements but not the ones stable or moderate need reads fragile. For example, a profile with high coverage but no defect count yet is fragile. This matters because a fragile module raises the risk of any change that touches it.
Where the numbers come from
- After each end-of-change verification. When the completion check runs, paqad records evidence for the modules the change touched and folds it into their profiles. Coverage is taken from test results or from how many obligations are covered. Each failed or errored test, failed gate, uncovered critical obligation, recorded defect or scope violation adds to the defect count, and a clean verified run sets an empty count to 0. Contract stability drops by 0.1 on a failure (from 0.8 if it was empty) and rises to at least 0.9 on a clean run, or drops by 0.05 if expected documentation is missing. Each recorded event adds 1 to change velocity.
- The rollup command.
paqad-ai module-health rollupreads the coverage and test reports that your stack pack describes, maps each file to a module using the module map, counts commits in the last 14 days as change velocity, and rewrites each profile. It records contract stability, defect frequency and mutation score as blocked, because it has no source for them. Use--from-report <path>or--from-test-report <path>to point it at reports your CI already produced. - Manual evidence.
paqad-ai module-health recordrecords evidence by hand (--module,--file,--coverage,--failed-tests,--verification-status), andpaqad-ai module-health syncfolds pending evidence into the profiles.
Before classifying each request, paqad also runs a quick sync so the profiles it reads are current.
How planning uses it
- If any module the request affects is
fragile, the request's risk becomeshigh. For a new feature that means the full lane. See Classification. - If every affected module is
stableand the request is trivial, paqad records that as the reason the fast lane is acceptable. moderateandunknownmodules leave the lane as the other rules set it.
Checking the records
paqad-ai doctor includes a "Module health ledger valid" check. It passes when there are no profiles yet, and fails when a profile is unreadable, is missing required fields, or has a tier that does not match its own metrics. See Doctor.