The DQS Mathematical Model: Flat-Cost Suppressions and Deterministic Gates
The Documentation Quality Score (DQS) is an integer from 0 to 100. Given the same repository state, it always produces the same number. v0.8.0 changed two things: it closed a gate paradox where CI-blocking codes had zero DQS weight, and it replaced the allowance-based suppression model with a flat-cost model.
The Gate Paradox
Before v0.8.0, the scoring engine had two separate tables: CODE_SARIF_LEVELS (used by the CI gate) and a penalty table (used by the DQS calculator). These tables were maintained independently. The invariant — that a CI-blocking code must also deduct from the score — was not enforced.
Three codes broke that invariant:
| Code | Name | SARIF Level | DQS Penalty (before v0.8.0) |
|---|---|---|---|
| Z103 | ORPHAN_LINK | error | 0 pts |
| Z111 | VIRTUAL_ROUTE_BROKEN | error | 0 pts |
| Z113 | AUTHOR_KEY_COLLISION | error | 0 pts |
The observable consequence: a repository with 50 ORPHAN_LINK findings would fail the CI gate (exit code 1) but report a DQS of 100. The gate and the score were contradicting each other.
v0.8.0 established a single source of truth: CodeDefinition, a NamedTuple that stores severity, penalty, and category for each code in one place. CODE_SARIF_LEVELS is now derived from it. Structural registration is impossible without a penalty — the paradox cannot recur.
The three paradox codes received their penalties in the migration:
| Code | Name | Penalty | Category |
|---|---|---|---|
| Z103 | ORPHAN_LINK | 2.0 pts | Structural |
| Z111 | VIRTUAL_ROUTE_BROKEN | 8.0 pts | Structural |
| Z113 | AUTHOR_KEY_COLLISION | 2.0 pts | Structural |
From Allowance to Flat-Cost
The v0.7.x suppression model was allowance-based:
Suppressions up to suppression_cap were free. Only excess suppressions generated debt. The cap served two roles simultaneously: it was a governance allowance boundary and a hard-fail threshold.
That dual role was the problem. A project with suppression_cap = 30 and 30 active suppressions had: score impact = 0, exit code = 0. Suppressions were invisible in the DQS.
The v0.8.0 model decouples the two roles:
Every suppression deducts 1 point. The cap is exclusively a hard-fail threshold:
- When : score is reduced by points. Exit code is determined by the score gate.
- When :
zenzic scoreexits with code 1 immediately, before score gate evaluation.
The Complete DQS Formula
Assembling all five stages:
where , is the total active suppression count, and:
Or, expanding the full pipeline into a single expression:
where is the total suppression count and .
Numerical Properties
Maximum achievable score is now , where is the active suppression count. A project with 10 suppressions cannot exceed 90, regardless of finding counts.
Monotonicity: is non-increasing in . Adding a suppression never improves the score.
Score/gate coupling: the CI gate threshold (configured via --fail-under) and the hard-fail suppression threshold (suppression_cap) are now independent. A project with a score of 80 and 29 suppressions (cap = 30) passes both. A project with a score of 95 and 31 suppressions (cap = 30) fails the cap gate regardless of the score.
Closing the Mapping Gap
The CodeDefinition single source of truth was established to prevent gate/score divergence. But the initial migration targeted only the three paradox codes (Z103, Z111, Z113). A subsequent audit identified four additional codes that the engine could emit (causing Exit 1) while carrying a penalty of 0.0 in the penalty table. The same paradox, at a smaller scale.
Three of the four received penalties in the migration:
| Code | Name | Penalty | Category | Notes |
|---|---|---|---|---|
| Z401 | MISSING_DIRECTORY_INDEX | 2.0 pts | Navigation | Directory reachable but no index page present |
| Z403 | MISSING_ALT | 1.0 pt | Content | Image with missing alt attribute (is_warning=True) |
| Z404 | CONFIG_ASSET_MISSING | 3.0 pts | Brand | Favicon or OG image declared in config but absent on disk |
The fourth — Z602 (I18N_PARITY) — remains frozen at 0.0 by architectural decision.
I18N_PARITY acts as a governance gate: it enforces language parity between documentation
trees and triggers Exit 1 when parity fails. Assigning it a DQS penalty would conflate
two independent quality dimensions (translation completeness vs. link health / content
quality) into a single number, making the score harder to interpret. A separate ADR is
required to add Z602 to the DQS formula. For now, it is excluded from the penalty table and identified as FROZEN_CODE in CODE_DEFINITIONS.
Migration Impact (v0.7.x → v0.8.0)
Projects with active suppressions will see their DQS decrease. The magnitude is exactly the active suppression count:
For a project with 10 suppressions previously scoring 75 (under allowance model with ), the new score is .
The suppression audit output in the CLI is unchanged. The label semantics for [MANAGED DEBT] and [EXTENDED DEBT] describe governance posture, not score exemption.
See Also
- Scoring Algorithm Reference — Full formula derivation and penalty table
- Suppression Policy — Three suppression levels and the
--auditoverride - Finding Codes — Full Zxxx code encyclopedia with remediation steps
