Skip to content
CodArchthe living map of the architecture
ESEN

Risk and lint

The decision is ADR 0108. The health that is copied is artifact 1.3.

B is the same as always: complexity 50%, churn 32% and size 18%. When a signal is missing, those weights renormalize. Each signal is divided by its p95 and clamped to 1. Gamma is 1.7. A folder keeps the maximum of its files, not the sum.

Without a lint term, risk = B^1.7. That is the same number as before.

D = errors + 0.25·warnings
nL = clamp(D / 10, 0, 1)
raw = min(B + 0.2·nL, 1)
risk = raw^1.7 0..1
score = 100·raw^1.7 0..100

Info does not enter D. α = 0.2 and Dsat = 10 are not calibrated. Lint never subtracts. Once raw is 1, more debt does not raise the index: a two-file map is often already at that ceiling, because the p95 is the smaller of the two.

Per file, the view that comes from its scopeHealth:

FieldWhat it is
freshtrue when meta.tree is the snapshot checksum. false when both exist and differ. null when there was no comparison.
countsErrors, warnings, info and findings, counted from the messages.
coverage.stateunmeasured, unknown, partial or complete.
coverage.eligibleSize of the universe. null is not zero.
coverage.measuredIt does not enter the formula.
coverage.reasonsThe contract codes. not-found, not-eligible and no-eligible matter.
applicabilityapplicable, na or not-found.
reasonThe first reason, so na is evidenced.

Project health is not passed, nor the whole artifact. With no artifact there is no view. A file missing from files is not filled with 0.

lintView wins over the legacy number. That number only remains for callers that still do not build the view: it is read as fresh debt of unknown coverage, and options.lint is required.

SituationWhat the index does
fresh === true and there are errors or warnings, even when the state is unknownIt adds. Confidence is an observed minimum, not a closed measurement.
fresh === true, coverage complete, eligible > 0, debt 0 and info 0It adds nothing. The file can be called clean.
fresh === true and debt 0 with an unknown universeIt adds 0. It does not lower the others and is not called clean.
fresh === falseNo penalty. The tree is not this one.
fresh === nullNo penalty. There was no comparison (freshness-unverified).
applicability: "na"No penalty. It is not zero.
applicability: "not-found"No penalty. It is not not-applicable and it is not zero.
No artifactNo view. Risk is B^1.7.

Each signal has points, percent and weight.

  • points are points of the 0..100 index. Those that are not null sum to score.
  • percent is the percentage of that index. Null when the index is 0 or the signal does not count.
  • weight is the nominal weight (0.50, 0.32, 0.18, and 0.2 for lint when nL exists). It is not the renormalized share or the percentage.

points null means the signal does not count. It is not a zero.

The object is what riskBreakdown returns in @codarch/metrics (packages/metrics/src/risk.ts). The render model stores it on each file as riskBreakdown, and the card reads that. It is not written to cc.json. MCP and the screenshot copy it only into their output. When the snapshot has no metrics, the field is null: the card does not recompute it.