scoring

package
v0.2.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 1 Imported by: 0

Documentation

Overview

Package scoring computes the per-dimension scores (0-100) and the weighted global score from a set of findings, using the configurable weights from .codefit.yaml (PRD RF-07).

Compute returns a ScoreSummary (per-dimension and weighted global score), and IsBlocked reports whether a critical, unconsented security finding must block the deploy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultWeights

func DefaultWeights() map[findings.Dimension]int

DefaultWeights are the per-dimension score weights (PRD RF-07, re-balanced by ADR 0055); they sum to 100, and every dimension core/findings declares has an entry — Compute iterates this map, so an unweighted dimension would be silently dropped the moment a sensor measured it.

practices is a dimension of its own and carries the smallest weight: codefit audits what the developer never sees, and `any` / `console.log` / a missing catch are the most visible defects there are — a linter flags them in the editor. Its 5 points come from complexity, which is never measured (post-v1.0), so the re-balance moves no score codefit produces today.

The PRD's defaults line still reads complexity 15; it is exempt from reflect-today and is not corrected.

These are the DEFAULTS, not the effective weights: since roadmap P1-2 a project may override them with `report.score_weights` in .codefit.yaml, resolved by ResolveWeights and consumed at both call sites. Until then the key was validated and never read — a config knob that did nothing — and this comment said so; it is corrected here rather than left to contradict the code three lines below it.

func DimensionScore

func DimensionScore(fs []findings.Finding) int

DimensionScore returns the 0-100 score for a single dimension's findings: a base of 100 minus the severity penalties of the counting findings, clamped to a floor of 0.

func IsBlocked

func IsBlocked(fs []findings.Finding) bool

IsBlocked reports whether the report must block the deploy: a critical security finding that is neither suppressed (consent) nor baselined. This is non-configurable — critical security always blocks (PRD §18).

func MissingWeights added in v0.2.0

func MissingWeights(measured []findings.Dimension, weights map[findings.Dimension]int) []findings.Dimension

MissingWeights returns the measured dimensions that have NO weight. Compute iterates the weights map, so such a dimension would be silently dropped (no by_dimension entry, no global contribution). A caller runs this guard before Compute and fails loudly on a non-empty result: a measured dimension without a weight is a codefit wiring bug, never a silently incomplete score (ADR 0021).

func ResolveWeights added in v0.2.8

func ResolveWeights(userWeights map[string]int) map[findings.Dimension]int

ResolveWeights decides WHICH weight map a scan-all run uses: userWeights (typically cfg.Report.ScoreWeights, string-keyed as .codefit.yaml spells dimension names) converted to findings.Dimension keys, when the caller named at least one entry; DefaultWeights() otherwise (roadmap P1-2 — report.score_weights was validated and then never read).

This does NOT re-validate the sum-to-100 contract — config.Validate already rejected a map that does not sum to 100 before it ever reaches here — and it does NOT pad a partial map with defaults for the dimensions it omits: a map naming only {"security": 100} resolves to exactly {security: 100}, nothing else. Whether that partial map is USABLE for a given scan (every dimension the scan actually measured has a weight) is Compute's/MissingWeights' concern, not this function's — ResolveWeights only picks the map.

Types

type ScoreSummary

type ScoreSummary struct {
	Global      int                         `json:"global"`
	ByDimension map[findings.Dimension]*int `json:"by_dimension"`
}

ScoreSummary is the computed result of an audit: the global score and the per-dimension breakdown, each on a 0-100 scale. A dimension whose sensor did not run is "not measured" and reported as nil (JSON null) — distinct from a dimension that was audited and scored 100. The global is re-normalized over the measured dimensions only, so unmeasured dimensions never inflate it (PRD section 21).

func Compute

func Compute(measured []findings.Dimension, fs []findings.Finding, weights map[findings.Dimension]int) ScoreSummary

Compute calculates the per-dimension scores and the weighted global score. Only the dimensions in measured are scored (others are reported as nil, "not measured"); a measured dimension with no findings scores 100. The global is the weighted average over the measured dimensions' weights only.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL