Scoring Algorithm
"Zenzic doesn't grade on a curve. Security and Governance are not optional."
The Zenzic Documentation Quality Score (DQS) is a deterministic, 0–100 integer computed from the findings of every active check. Given the same repository state, the algorithm always produces the same score. There is no weighting heuristic, no interpolation, and no rounding until the final integer cast.
Architecture Overview
The scoring pipeline has five sequential stages:
1. Security Gate → Z2xx finding? score = 0, early return.
2. Penalty Table → per-code deductions, per-tier caps.
3. Governance Esc. → exponential amplification if Z6xx > 10.
4. Gravity Cap → brand score = 0 ⟹ total ≤ 70.
5. Suppression Debt → subtract ω_debt from capped total.
Each stage is described below with its full formula.
Stage 1 — Security Override
Before any score computation, the engine checks for Z2xx findings:
where .
This is an unconditional early return — no flags, no config options, and no suppressions can bypass it. The four codes in represent binary failure conditions:
| Code | Name | Condition |
|---|---|---|
| Z201 | CREDENTIAL | Credential pattern detected in document |
| Z202 | PATH_TRAVERSAL | System-path escape attempt in a link |
| Z203 | PATTERN_MATCH | Custom forbidden-pattern match |
| Z204 | FORBIDDEN_TERM | Privacy Gate — confidential term exposure |
When the Security Override fires, ScoreReport returns security_override=True and security_findings=N (total Z2xx count). The --strict flag and fail-on-error configuration are irrelevant — the gate operates before all of them.
:::danger Security Codes Are Non-Suppressible
No inline <!-- zenzic:ignore -->, no per_file_ignores, and no excluded_dirs can suppress a Z2xx finding. The finding still fires. The score is still 0.
:::
Stage 2 — Penalty Table and Tier Caps
If no Z2xx finding is present, the engine computes a per-tier score.
Zenzic Weight Matrix (5-Tier)
| Tier | Category | Codes | Weight | Cap |
|---|---|---|---|---|
| Security Gate | — | Z2xx | — | score = 0 |
| Structural | structural | Z1xx | 30% | 30 pts |
| Navigation | navigation | Z3xx, Z4xx | 25% | 25 pts |
| Content | content | Z5xx | 20% | 20 pts |
| Governance | brand | Z404, Z405, Z406, Z6xx | 25% | 25 pts |
Per-Category Formula
For each tier :
The Category Cap Invariant guarantees that a single tier cannot drag the score below its floor. For example, 1 000 occurrences of Z505 (1 pt each) exhaust the content bucket at −20 pts. The remaining 80 pts from other tiers are unaffected.
Base Score
Penalty Reference Table
| Code | Name | Penalty / occurrence | Tier |
|---|---|---|---|
| Z101 | LINK_BROKEN | 8.0 pts | Structural |
| Z102 | ANCHOR_MISSING | 5.0 pts | Structural |
| Z103 | ORPHAN_LINK | 2.0 pts | Structural |
| Z104 | FILE_NOT_FOUND | 8.0 pts | Structural |
| Z105 | ABSOLUTE_PATH | 2.0 pts | Structural |
| Z107 | CIRCULAR_ANCHOR | 1.0 pts | Structural |
| Z106 | CIRCULAR_LINK | 0.0 pts | Informational (no DQS impact) |
| Z108 | EMPTY_LINK_TEXT | 1.0 pts | Structural |
| Z111 | VIRTUAL_ROUTE_BROKEN | 8.0 pts | Structural |
| Z113 | AUTHOR_KEY_COLLISION | 2.0 pts | Structural |
| Z301 | DANGLING_REF | 4.0 pts | Navigation |
| Z302 | DEAD_DEF | 1.0 pts | Navigation |
| Z303 | DUPLICATE_DEF | 3.0 pts | Navigation |
| Z402 | ORPHAN_PAGE | 4.0 pts | Navigation |
| Z401 | MISSING_DIRECTORY_INDEX | 2.0 pts | Navigation |
| Z501 | PLACEHOLDER | 2.0 pts | Content |
| Z502 | SHORT_CONTENT | 1.0 pts | Content |
| Z503 | SNIPPET_ERROR | 10.0 pts | Content |
| Z505 | UNTAGGED_CODE_BLOCK | 1.0 pts | Content |
| Z403 | MISSING_ALT | 1.0 pts | Content |
| Z405 | UNUSED_ASSET | 3.0 pts | Governance |
| Z404 | CONFIG_ASSET_MISSING | 3.0 pts | Governance |
| Z406 | NAV_CONTRACT | 2.0 pts | Governance |
| Z601 | BRAND_OBSOLESCENCE | 2.0 pts | Governance |
::: note Z106 — Knowledge Graph telemetry, not a defect
Z106 is excluded from the penalty table by design. Elevating it to a scored finding would deduct Quality Score points, pressuring engineers to remove cross-links to satisfy the linter — a perverse incentive that degrades real documentation quality. Circular links in a Knowledge Graph are structural data, not defects. Z106 is emitted as topological telemetry; inspect it with --show-info.
:::
:::note Z602 is not scored Z602 (I18N_PARITY) is a Governance gate that fires as a standalone finding. It does not contribute to any DQS bucket and therefore has no penalty value in the table above. :::
Stage 3 — Governance Escalation
Z6xx violations represent brand and governance decay — the kind that accumulates silently. Beyond 10 occurrences, the engine applies an exponential amplifier to the Governance bucket deductions:
where .
The deduction is capped at the Governance tier maximum (25 pts) to prevent overflow. The practical effect: a repository with 20 Z601 violations (10 excess → multiplier = ) takes four times the normal governance hit.
Stage 4 — Gravity Cap
If the Governance bucket is fully zeroed by its deductions:
Rationale (ADR-031): a documentation set with uncontrolled governance violations — brand decay, stale assets, broken navigation contracts — cannot be considered a high-quality product, regardless of its link graph. The Gravity Cap enforces this constraint structurally.
Stage 5 — Suppression Debt
Every active suppression is an acknowledged assumption of responsibility. The flat-cost model deducts exactly 1 point per suppression, regardless of how many suppressions are present. There is no free allowance.
suppression_cap (default: 30) is a hard-fail threshold, not an allowance boundary. When suppression_count > suppression_cap, zenzic score exits with code 1 immediately, before the score gate is evaluated. The penalty formula is independent of the cap:
where:
- = total active suppressions (inline
zenzic:ignore+per_file_ignoresentries)
The final score is:
Suppression Cost Reference
| Suppression count | Cost per suppression | Notes |
|---|---|---|
| 1 pt each | Managed posture — every suppression costs | |
| 1 pt each | Hard-fail: zenzic score exits with code 1 |
:::info Boundary Condition — Configuration Invariant Because every suppression deducts 1 point, the maximum achievable score for a repository is:
where is the total active suppression count. Configuring fail_under > 100 - suppression_cap creates a mathematical contradiction: the score gate fires due to suppression debt before the governance cap is reached. Safe configuration rule:
:::
fail_under and suppression_cap operate as orthogonal constraints evaluated independently by the CI pipeline. A pipeline run fails if either condition is triggered:
- Score gate:
score < fail_under→zenzic scoreexits with code 1 - Governance cap:
|F_s| > suppression_cap→zenzic scoreexits with code 1
This dual-gate architecture enables asymmetric bounding of technical debt. A hybrid policy such as fail_under = 90, suppression_cap = 30 enforces: "Overall quality must never drop below 90/100, and regardless of score, no more than 30 suppressed defects are ever tolerated."
:::tip Suppression Debt in the CLI
Run zenzic score to inspect the current suppression posture:
Suppression Audit: 8/30 (inline: 5, per-file: 3)
Run zenzic check all --audit to see findings without applying suppressions.
:::
Interpretazione dei Risultati
1) Finding Informativi
Informational findings are non-blocking diagnostics for visibility and observability.
- They do not reduce DQS.
- They never trigger the Security Override.
- In SARIF they are emitted at
notelevel.
Typical examples include Z106 (CIRCULAR_LINK) and informational surfaces such as Z114 or Z906.
2) Audit delle Soppressioni
The Suppression Audit is governance telemetry, not a raw failure counter.
- It reports the total active suppressions (inline directives +
per_file_ignores). - It expresses explicitly authorized technical debt envelope.
- Score impact is applied to every active suppression (flat-cost: 1 pt each).
3) Label Semantics: [MANAGED DEBT] and [EXTENDED DEBT]
[MANAGED DEBT]: active suppressions are present and the project remains on sovereign cap profile (suppression_cap <= 30).[EXTENDED DEBT]: active suppressions are present while using an expanded cap profile (suppression_cap > 30).
These labels describe governance posture. They are complementary to score math and help reviewers track suppression growth over time.
:::warning Breaking Change
Suppressions are not allowance-based. Every suppression deducts 1 point (flat-cost model), while suppression_cap remains an independent hard-fail exit threshold. Projects with active suppressions always see their maximum achievable score reduced by the suppression count.
:::
Complete Formula
Assembling all five stages:
where is the total active suppression count and:
Worked Example
Scenario: A repository has 2 broken links (Z101), 3 orphan pages (Z402), 5 untagged code blocks (Z505), and 15 Z601 brand violations, with 8 active suppressions (cap = 30).
Stage 1 — Security Gate: No Z2xx findings → continue.
Stage 2 — Penalty Table:
| Tier | Cap | Deduction | cat_pts |
|---|---|---|---|
| Structural | 30 | 2 × 8.0 = 16.0 | 14.0 |
| Navigation | 25 | 3 × 4.0 = 12.0 | 13.0 |
| Content | 20 | 5 × 1.0 = 5.0 | 15.0 |
| Governance | 25 | 15 × 2.0 = 30.0 → cap to 25 | 0.0 |
Stage 3 — Governance Escalation: 15 Z601 violations → → multiplier → deduction . Brand bucket = 0.
Stage 4 — Gravity Cap: → .
Stage 5 — Suppression Debt: suppressions → flat-cost: .
Reading the CLI Output
Running zenzic score displays a Quality Breakdown Ledger that exposes
every arithmetic step — from raw per-tier penalties to the applied cap, the
Gravity Cap adjustment, suppression debt, and the final score.
✨ Quality Score: 65/100
╭─ Quality Breakdown ──────────────────────────────────────╮
│ Category Issues Weight Raw Pts Applied Pts │
├──────────────────────────────────────────────────────────┤
│ ✓ structural 0 30% 0 0 │
│ ✓ navigation 0 25% 0 0 │
│ ✗ content 2 20% -4 -4 │
│ ✗ brand 15 25% -30 -25 (CAPPED) │
├──────────────────────────────────────────────────────────┤
│ Σ Subtotal 71 │
╰──────────────────────────────────────────────────────────╯
! Technical Debt (6 suppressions) -6 pts
= Final Quality Score 65 / 100
Column guide:
| Column | Meaning |
|---|---|
| Raw Pts | Post-escalation deduction before the category cap, shown as a negative value (or 0). |
| Applied Pts | Deduction actually subtracted, capped at the tier maximum. |
| (CAPPED) | The raw deduction exceeded the tier cap and was truncated. |
| Σ Subtotal | Sum of all retained cat_pts values before Gravity Cap and Suppression Debt. |
When the Gravity Cap fires (Brand bucket = 0), an extra line appears between Σ Subtotal and Technical Debt:
│ Σ Subtotal 75 │
╰──────────────────────────────────────────────────────────╯
! Gravity Cap Enforcement (Brand = 0) -5 pts
! Technical Debt (0 suppressions) 0 pts
= Final Quality Score 70 / 100
The arithmetic is always explicit: Σ Subtotal − Gravity Cap − Suppression Debt = Final Score.
See Also
- Suppression Policy — Three suppression levels, debt formula, and the
--auditoverride - Finding Codes — Full encyclopedia of Zxxx codes with remediation steps
- Handle Technical Debt — Step-by-step remediation workflow
- Configure Privacy Gate — Z204 FORBIDDEN_TERM architecture