Concepts

Methodology versions

The complete version history of the inspect.software metrics methodology — every formula, weight, and threshold change, dated and documented.

Methodology v2.10.0Updated 2026-08-25

The methodology is versioned as a whole. Any change to a formula, a weight, or a band threshold bumps the metrics version, and every published report records the version it was produced under (metrics.metrics_version). That makes results auditable over time: a historical value can be re-derived under the exact rules that produced it.

The current version is 2.10.0. Its implementation is published at inspect-software/scanner. A report's metrics.metrics_version can be matched to METRICS_VERSION in the repository history to identify the code used to compute it.

Each entry identifies the precise change, its scope, and whether existing results remain comparable. Dates are part of the public methodology record.

Version history

2.10.0 — 2026-08-22

An interface is only expected of software that could meaningfully lack it. The machine-readable-interfaces metric judged every repository it admitted against all three of its checks, so a examples/ directory — which nearly every library ships — was enough to be told the project was missing an OpenAPI schema and an MCP server. Just over a quarter of the record entered the metric on examples alone. A maintainer receiving a badge pull request put it plainly: he had no idea how either check applied to his database driver, and he was right. An API schema is now expected only of network services and chat bots, an MCP server only of network services, and runnable examples of everything; anything else is excluded and the remaining weights renormalize. Evidence still counts wherever it exists — a library that does publish a schema earns the points, because the classification decides whether absence is a finding, never whether evidence is real. No repository enters the metric that was not already in it, and no score moves downward.

2.9.0 — 2026-08-22

A registry that hosts documentation for everything it publishes counts as the documentation site. Version 2.7.0 accepted a documentation URL declared through the registry. crates.io goes further: it builds and serves a documentation page for every crate it accepts, whether or not the manifest names one — so a crate that simply skipped the optional key still lost the points, which measured paperwork rather than documentation. The documentation check now falls back to that hosted page, after every declared URL has been considered. Only crates.io qualifies today; an ecosystem joins that list when its hosting has been measured, not when it looks similar. Reported by maintainers reading their own reports. Scores can only rise, and the correction applies without rescanning, since it reads what the report already records.

2.8.0 — 2026-08-22

An organization's verified domain is finally read, and "not read" stops meaning "unverified." The stewardship verified-domain check took its flag from GitHub's user endpoint, which serves organizations but omits the verified-domain field entirely — only the organization endpoint carries it. Every organization in the record therefore failed a 20-point check regardless of its actual status, and 59% of the record is organization-owned. A maintainer reading his own report found it. Collection now asks the organization endpoint for organizations only. Scoring changes with it: an unread flag — in every report written before this change, and whenever the lookup fails — is now excluded and the remaining weights renormalized, rather than scored as unverified: a request that did not happen is not evidence of an unverified domain. Organization scores rise where the flag was unknown, and settle at the true value on rescan.

2.7.0 — 2026-08-20

Documentation declared through the registry counts. The documentation metric's documentation-site check accepted only the GitHub homepage field. Rust libraries document on docs.rs, declare it with the manifest's documentation key — mirrored by crates.io — and rarely set a GitHub homepage, so an entire ecosystem's libraries lost these points; a maintainer receiving a badge pull request found the error on his own report, and syn and serde carried the same one. The check now falls back to a documentation or homepage URL declared through the package registry: crates.io documentation and homepage, PyPI project_urls, RubyGems documentation_uri, Hex docs links, the npm and Packagist homepage, NuGet projectUrl. A homepage hosted on github.com restates the repository link and is ignored. Scores can only rise, and only where a registry declares what the repository already publishes. Existing reports gain the correction as they are rescanned, since the registry declaration is recorded at collection time.

2.6.0 — 2026-08-19

Adoption evidence must point back. Ecosystem adoption counts downloads and registry dependents only from packages whose registry entry declares the scanned repository as its own. A package name declared in the repository's manifests whose registry entry declares no repository keeps the benefit of the doubt for existence, but no longer lends the repository its download figures: that rule let an unrelated npm package's 25 downloads/month stand on a report in place of the project's ~14M/month on PyPI — found by the project's own maintainer. Excluded packages are now named in the metric's inputs. Repositories whose only figures were unverified show the metric as no-data and renormalize. Scores move only where unverified numbers were being counted; verified evidence is unchanged.

2.5.0 — 2026-08-04

The classification touches a score for the first time: the security posture fallback's dependency-lockfile expectation is restored for published applications. Publication alone used to waive the check, which excused exactly the repositories the guidance is about — ruff, black and poetry are published applications, and the package managers' own advice tells applications to commit the lockfile. A published package whose manifest declares an executable now keeps the expectation.

Two guardrails accompany the change. The standing rule, which every future connection will follow: scoring reads manifest declarations only — a label inferred from file structure, topics or the description is displayed but never moves a score. And the blast radius was measured before shipping: the lockfile component exists only in the fallback used when OpenSSF Scorecard is unavailable (472 of 49,846 stored reports), and within it exactly four reports change — one gains points, three lose. The change is effectively prospective: it governs future scans without Scorecard, and makes the methodology practice its own words.

2.4.0 — 2026-08-04

The classification vocabulary becomes an explicit two-level tree — Library · Application · Host extension · Notebook, with subtypes under Application and Host extension — replacing the flat nineteen-label list. No score is affected.

Three structural changes. Five labels merge into Library: framework, SDK, API client, middleware and driver had no defensible boundaries — axios is an API client and a library, flask is a framework and a library — and no consumer treated the distinction as meaning anything. The answer may stop at the top level: a Cargo binary target and Go's cmd/ layout prove an executable without saying what kind, and such repositories are now classified simply Application instead of being forced into "command-line tool" at reduced weight. Host extensions are subtyped by host class — plugin, browser extension, editor extension, theme — because the class determines the inherited trust surface, while the WordPress-versus-Chrome naming difference determined nothing.

2.3.2 — 2026-08-04

Three classification corrections around Go repositories and code-quality tools, found by reviewing go-critic — a Go linter whose report read Library on the strength of a single fact: its module resolves on the Go proxy. No score is affected.

The Go module proxy stops counting as publication. Every other registry records an intentional act by the maintainer; the proxy indexes any repository with a go.mod the moment anyone requests it, so existence there says "this is a Go module", not "this is meant to be depended on" — servers and command-line tools carry the entry exactly as libraries do. Like the MCP signal in 2.3.1, it now corroborates rather than decides: repositories whose only library evidence was the proxy entry lose the label until stronger evidence arrives.

Go's file tree is read as the declaration it is. The language has no manifest field for what it builds; the cmd/ layout and the compiler-enforced internal/ rule are how it says so. Any source file inside a cmd/ directory now marks a binary — previously only a file literally named main.go did, which hid go-critic's second command — and packages the internal/ rule does not seal off count toward Library, corroborating the proxy entry.

Linter and formatter tags carry the command-line reading — except on host extensions. A repository tagged linter or formatter almost always ships a runnable checker. The exception is systematic rather than random: measured across the record, 42 of 256 linter-tagged repositories are rule packs or configs for a host linter, and there the runnable tool is the host. The contribution is withdrawn entirely whenever independent evidence marks the repository as a plugin, extension, theme, or editor tooling.

2.3.1 — 2026-08-03

A correction to the classification published hours earlier: the Model Context Protocol signal no longer identifies a repository as an MCP server on its own. No score is affected.

That signal fires on .mcp.json — the file that configures an editor to call MCP servers — and on any dependency whose name ends in mcp, which a client declares exactly as a server does. It records that a project is set up to work with coding agents, not that it is one of the servers they call. Measured across the record it alone accounted for 1,746 of the 3,115 repositories carrying the label, freeCodeCamp among them. It now requires corroboration; a genuine server still classifies through its topic or its dependency.

2.3.0 — 2026-08-03

Every report now states what the repository builds: whether the software is consumed as code, run as a program, or installed into a host that supplies its trust model. No score moves in this version — the classification is published as data and is not yet an input to any metric.

Until now a single proxy stood in for the question: does the repository publish a package to a registry. That reads every command-line tool on PyPI as a library, and every application that happens to ship one helper package as one too — while the expectations that follow differ materially. A published library is expected not to commit a dependency lockfile; the application beside it in the catalogue is expected to.

The classification carries every reading the evidence supports, not one. Software that is both a published library and a runnable tool is the ordinary case rather than a contradiction, and such a repository will owe the obligations of both readings rather than the laxest of them. Evidence is ranked by how far it can be trusted: what a build manifest declares outright — an OutputType, a Composer type, an npm bin entry, a console-script entry point — outweighs file-tree structure, declared dependencies and self-assigned topics, and no single weak signal carries a reading on its own. Where the evidence does not answer the question, the report records that instead of guessing.

Wiring the classification into the metrics that depend on it — dependency lockfiles first, where the present rule is demonstrably wrong for published tools — is a separate, dated version.

2.2.0 — 2026-08-02

The High-Risk Jurisdiction classifier stops reading a denial as a declaration, and now treats a named place outside the policy scope as conflicting evidence.

Both faults were found by testing the policy's North Korea scope against live profiles. Locations reading "not north korea", "def not north korea" and "Seoul, Korea (not DPRK)" were all returning a confident match: the country was named precisely in order to be disowned, and the policy recorded it as a self-declaration. A denial is now honoured — but only where it sits beside the match, so "No. 5 Lenin St, Moscow, Russia" still declares Russia and retracts nothing.

The second fault was structural. The packaged place gazetteer holds Russian, Iranian and North Korean places and nothing else, so a foreign city standing next to a policy match was invisible and the match read as unopposed: "Seoul, North Korea" and "New Dehli / Beijing / Hong Kong / Pyongyang" both scored as confident. Capitals, major cities and technology hubs outside the scope now make a location ambiguous, exactly as a foreign country name already did, and US state names apply to every policy country rather than to Russia alone.

Measured across the whole record before release: of 358 distinct high-confidence locations, two change — one reading "London, Munich, St. Petersburg", which is an office list rather than a declaration, and one reading "Amsterdam, Netherlands / Leningrad, Russia". A single repository loses its flag. Scores can only rise under this change.

2.1.0 — 2026-08-02

Responsiveness gains a Newcomer PR acceptance component (weight 13.) Of the pull requests decided in the last 30 days whose author had no previously merged pull request in that repository, the component scores the share that were merged. Bot-authored pull requests are excluded before anything is counted. The two lifetime components are re-weighted to make room — issue resolution 46.75 → 42, PR acceptance 38.25 → 30 — and the OpenSSF Scorecard Code-Review component stays at 15.

The existing PR acceptance component is a lifetime ratio, and on an established project it barely moves: a repository with thousands of merged pull requests cannot shift it inside a year whatever it does now. Nor can it separate a project that merges its regulars' work promptly from one that merges nothing arriving from outside that circle. Those two rates come apart often enough that only the second describes what a first-time contributor should expect.

The component is excluded, with the metric's remaining weights renormalized, when no first-time contributor's pull request was decided in the window. Nobody knocking is not the same fact as nobody being let in, and only the second is the project's own doing. The denominator is newcomers' decided pull requests rather than their share of all merges, so a mature project where regulars land most of the work is not marked down for having regulars.

The evidence is collected during the scan, so it appears only on reports produced after this version. Earlier reports lack the input and renormalize without it; the change therefore takes effect as repositories are rescanned rather than across the record at once. Scores can move in either direction where the component is present.

Community health reports the README's status badges, unscored. How many badges a README displays, and which services they come from, are now carried in the report as observations with no weight. Every fact a badge asserts — that CI runs, that coverage exists, that a release is published — is already measured directly from the repository, and a badge is one line of Markdown that nothing verifies as pointing at the project it sits in.

2.0.0 — 2026-08-02

The first major revision of the scale itself, in three connected parts. The whole record was re-scored under it; scores published before and after this version are not comparable point-for-point — bands, not points, are the unit of comparison across the boundary.

The overall index is calibrated to the public record. The weighted category mean used the 1–100 range badly: measured across all 47,516 inspected repositories, half the record sat between 50 and 69 and the top decile of open source reached only the high 70s, so most of the scale distinguished nothing. The published index now applies a fixed monotone curve — anchored to chosen percentiles of the record's empirical distribution at a dated snapshot — to the raw weighted mean. Bands thereby carry percentile meaning, and the raw mean remains in every report (overall.inputs.weighted_overall_raw) for auditability. The curve is a constant of this version, not a live percentile: a score moves only when the repository's own evidence moves. The curve saturates at the top of the scale — a raw mean of 91 or above publishes as 100 — because the last raw points above that line distinguished nothing a reader should act on. Category and metric values are published uncalibrated.

Five bands become seven. Weak (35–49) now sits between At Risk and Moderate, and Exceptional (93–100) above Excellent. New thresholds: critical 1–19, at risk 20–34, weak 35–49, moderate 50–64, good 65–79, excellent 80–92, exceptional 93–100 — chosen so the calibrated bands split the record into comparably sized populations where the old Moderate alone held roughly half of it. Each band also carries a letter grade, C through AAA. Red-flag ceilings moved with the bands they name: the High-Risk Jurisdiction and likely-abandonment ceilings are now 34 (top of At Risk, previously 49), the malicious-dependency and declared-abandonment ceilings 19 (top of Critical, previously 29), and the overall-score policies now act on the calibrated index, so a report's stated ceiling is the number the page displays.

AI Readiness joins the weighted mean at 4%. The category was measured and published at weight 0 since its introduction; agent tooling has since become an ordinary maintenance signal and now carries real — deliberately small — weight. The other categories yield one point each: Sustainability & Governance 23%, Vitality 21%, Engineering Quality 19%, Community & Adoption 17%, Security 16% (unchanged). The weight is sized together with the calibration curve's saturation point so that a repository with zero AI Readiness signals can still reach 100/100 — the category can nudge an index, never gate the top of the scale.

1.14.0 — 2026-08-02

The High-Risk Jurisdiction Policy now requires a contributor-side match to carry commit weight before it flags: at least 50 commits, or at least 10% of the sampled human commits. Owner matches are unaffected.

The previous rule flagged a repository for any high-confidence location match among its displayed top contributors, however small their contribution. Measured on the production record, 1,763 repositories carried the flag and only 199 through the owner account; of the remainder, 56% rested on a matched contributor with fewer than ten commits, and 70% on one below 5% of the project's commit history. Widely used projects were flagged for single low-ranked contributors near 1% of their history. A location match on an incidental contributor is disclosure, not exposure, and a flag that fires on it tells a reviewer nothing about who stewards the software.

Matches below both thresholds remain on the report as recorded, review-only evidence; they raise no flag and move no score. Scores can only rise under this change, and only for repositories whose flag rested entirely on sub-threshold matches. The thresholds are published in every report, and the commit counts the rule reads were already collected, so existing reports were re-scored without rescanning.

1.13.0 — 2026-07-22

Two corrections, both prompted by the first malicious-dependency finding this record ever published.

Red flags stop compounding. Each policy used to multiply whatever the previous one left, so a repository carrying two landed on the product of both. One project went from a weighted 50 to 18 under the malicious-dependency multiplier and then to 11 under abandonment — a number no policy chose, and none could be pointed at to explain. A multiplier states how serious a finding is; it is not a cost to be added up. The strictest policy now governs alone and the others are reported without moving the score again. Scores can only rise under this change, and only for repositories carrying more than one flag.

A withdrawn package is no longer scored as live malware. Every malicious finding now asks the registry whether it still serves that exact version. Where it does not, nothing installable remains: the finding stays on the report, because the project depends on a name that was compromised, but it raises no flag and costs no points.

The check asks about the resolved version rather than the package's latest one, and the distinction decides real cases. After a takedown npm leaves a placeholder release as the package's latest, which protects everyone resolving a version range and nobody who pinned the bad version exactly. Reading the latest version would have cleared the very repository this finding first fired on, which pins the compromised package at the precise version the registry still serves. Where the question cannot be answered at all, the finding is scored as though the package were live — failing to reach a registry is not evidence that malware was withdrawn.

1.12.0 — 2026-07-22

The Abandonment Policy's declared tier was over-firing on registry evidence that did not belong to the repository it was judging.

That tier exists to quote the maintainer rather than infer anything: a project is declared unmaintained when it is archived, or when every package it publishes has been retired. Two defects widened it. A package counted as the project's own unless the registry positively said otherwise — which admitted entries declaring no repository at all, exactly the shape a squatted name takes. And a yanked latest release counted as retirement, though withdrawing a release is usually a bad build with a fix right behind it.

Together they took one 68-rated project to 27 on the strength of a PyPI placeholder it does not publish. A package must now declare this repository and be deprecated outright; a yanked release no longer contributes. Of 403 repositories in the declared tier, 391 rested on GitHub's own archive flag and were never in question.

1.11.0 — 2026-07-21

Abandonment becomes a red flag over the whole report.

Every tool in this space answers "is this project dead?" with days since the last commit, and every one of them is wrong about the same projects: a small, complete library that has not needed a commit in three years is finished, not abandoned. Marking it dead costs a public record its credibility on exactly the software that deserves the most confidence.

So the assessment rests on a different question — abandonment is an unmet obligation, not an absence of noise. Silence is measured from the last human commit and is never a finding on its own; it becomes one only when work is visibly arriving and not being acted on: an unanswered contribution queue, issues no maintainer ever replied to, an unfixed advisory in a direct dependency, a release stall measured against the project's own cadence, a failing or year-stale CI, a sole maintainer absent from the whole window. Readings that explain the silence hold the result at dormant, which carries no penalty — quiet is already priced inside development activity, and charging for it twice would punish the finished libraries the distinction exists to protect.

Findings multiply the health index: 85% at risk, 60% likely abandoned with an at-risk ceiling of 49, 40% declared with a critical ceiling of 29. Declared is the maintainer's own statement quoted rather than inferred — the repository is archived, or every package it publishes is deprecated or yanked. Repositories that cannot be assessed read unverified and are not penalized. See abandonment.

Comparability: values can only fall relative to 1.10.0, and only for repositories where a drought is corroborated by unmet obligations. Quiet, well-kept projects are unaffected by design.

1.10.0 — 2026-07-21

Dependencies reported as malicious packages become a security red flag of their own, separate from vulnerability advisories.

The evidence was already arriving. OSV.dev serves the OpenSSF malicious-packages corpus alongside ordinary advisories, on the same query this record already made — but a malicious-package report carries no severity rating and no fixed version, so it was falling through to "unknown severity" and scoring like a moderate vulnerability. A package found to be malware counted for slightly less than an average CVE.

Malicious packages are now removed from the advisory findings and scored on their own terms: a 35% multiplier on security posture and on the weighted health index, with a Critical ceiling of 29 on both. That is one band stricter than the high-risk jurisdiction ceiling, because a malicious dependency is a confirmed compromise rather than an exposure to risk. Direct and indirect dependencies count alike — an install-time payload runs at any depth in the resolved graph.

The finding is expected to be rare: run over a 300-repository sample covering 46,889 resolved dependencies before release, it found nothing. Registries remove malicious packages within days, so a lockfile that still resolves to one is unusual. See malicious dependencies.

Comparability: unchanged for every repository with no malicious dependency, which is nearly all of them. Where one is found, Security and the health index are not comparable to any earlier version.

1.9.0 — 2026-07-21

The human-authorship factor introduced in 1.6.0 stops firing on projects that simply automate well.

Heavy automation on its own turned out to be a poor signal. Among the repositories where machines author most of the commit traffic, the healthiest were indistinguishable from the abandoned ones by share alone: one 59,000-star project runs roughly three quarters of its commits through a dependency bot and had a human commit two days ago, and a package registry whose entire purpose is automated version bumps runs at 93%. Both were being marked down.

The discount now requires a second condition: the machines must also have been committing alone for more than 90 days. The gap is measured inside the sampled commit window rather than against the clock, so a stored report always rescores to the same value. Repositories with a recent human commit are no longer affected at any level of automation; genuinely automation-sustained projects keep their discount.

Comparability: values can only rise relative to 1.8.0, and only in Vitality.

1.8.0 — 2026-07-21

A signal is withdrawn. Growth authenticity's pre-substance spike claimed that a burst arriving before a project's first release was evidence of something. Measured against 795 ordinary repositories, it fired in every one of the five findings the policy produced — and every one of those five was an ordinary launch. Publish, attract attention, release later is how projects work.

The comparison was unsound in a second way. The release list a report carries is capped at its newest 100 entries, so for any project past that cap the earliest entry is not its first release, and every burst appears to predate it.

What replaces it, no released substance, keeps only the absolute case: the project has never published a release at all. It is deliberately weaker, and it corroborates rather than concludes. Findings across the ordinary population return to none, and both confirmed findings in the evaluation sample survive.

A published methodology that cannot withdraw a signal it can no longer defend is not a methodology. This is what the version history is for.

1.7.0 — 2026-07-21

Growth authenticity gains a fifth signal, star concentration: the five busiest days holding 80% or more of every star the scan collected.

It was added after the first live evaluation of the policy, which found it precise but nearly blind — across 714 ordinary repositories it flagged none, and across 45 selected for the shape purchased attention leaves it flagged one. The threshold is read off the record rather than chosen in advance: among 502 ordinary repositories in the 100–1,500 star band, the median puts 6.9% of its stars in the five busiest days, and none reached 80%.

The signal corroborates a burst; it never concludes on its own. A legitimate announcement-driven release approaches the same shape — a research model release measured 73.7% — and a signal that cannot tell those apart must not decide alone.

Scores can only fall under this change, and only for repositories that already showed a burst. Nothing else moves.

1.6.0 — 2026-07-21

Inputs that can be inflated stop counting at face value.

Added growth authenticity. The per-day star and fork history collected for every report is now read for growth whose shape organic attention does not produce, and the Inorganic Growth Policy discounts the stars and forks components of popularity by 40% for one confirmed window and 70% for more. A burst on its own is never a finding: confirmation requires at least two independent corroborating signals, so launches and front-page days read as organic. Repositories whose collected history cannot answer the question read unverified and are not penalized. The policy carries no additive weight, so a clean history can never raise a score.

Development activity gains a human-authorship factor over its commit cadence and commit volume components. A project sustained entirely by its own robots no longer reads as actively developed; full marks apply from a 40% human share upward, so heavy but genuine automation is unaffected. Maintainer resilience now counts people only — automation accounts were previously ranked among a project's maintainers, which flattered exactly the projects that automate most.

AI Readiness stops measuring only which files exist. Agent context gains a legible commit history component and rebalances away from llms.txt: before this change the metric could only ask whether a rare file had been written, and most projects had no way to move it at all. Verify loop gains its first two components that observe an outcome rather than the presence of a file: demonstrated agent practice, and automated maintenance — whether a dependency bot's machine-authored changes actually land, judged on observed commits rather than a configuration file, since the most widely used tool is routinely configured outside the repository. It also now credits a language toolchain as a one-command bootstrap, which had scored well-run Rust projects zero for shipping no Makefile. The badge still carries no weight in the health index.

Existing values remain comparable except in Community & Adoption for repositories with a confirmed growth finding, and in Vitality and Sustainability & Governance for repositories whose contributor list is largely automation. Scores under these changes can only fall, never rise.

1.5.0 — 2026-07-20

Added dependency advisories. The resolved dependency set already collected for every report — direct dependencies plus the transitive closure — is now matched against the OSV advisory database, and affected packages are reported with their severity and the version each was fixed in.

Security becomes a weighted mean of security posture at 80% and the new metric at 20%. The High-Risk Jurisdiction Policy multiplier is unchanged: it still applies to posture and to the weighted overall score, and carries no additive weight of its own.

The new metric is excluded, with the remaining weight renormalized, whenever the dependency graph or the advisory lookup was unavailable — a repository is never penalized for having its dependency graph switched off. Existing values remain comparable except in Security, where any repository with a dependency graph is now scored on evidence that was not previously considered.

1.4.0 — 2026-07-19

Added High-Risk Jurisdiction Exposure for high-confidence self-published public profile evidence within the Russia, Iran, and North Korea policy scope. It is a hierarchy-wide policy multiplier: owner 20%, displayed top contributor 50%, public contributor-organization affiliation 75%, no match 100%. A confirmed match multiplies and caps Security posture at 49; Security reflects that adjusted posture. The same multiplier and cap then apply to the weighted overall score. Missing, ambiguous, and clean evidence do not reduce either score.

The classifier is offline, adds no API request, excludes internationally recognized Ukrainian territories from Russia place matching unless Russia is explicitly self-declared, and publishes only aggregate country/role evidence. The signal routes a dependency into enhanced review; it does not determine nationality, citizenship, sanctions status, malicious intent, or individual trustworthiness.

Comparability: affected repositories can move to a lower Security and overall band. Existing reports contain owner and top-contributor locations and can be rescored without repository network access. Organization-affiliation location is available only on new scans because schema 0.15.0 adds it to the existing batched GraphQL selection.

1.3.0 — 2026-07-18

Community health's license signal became a three-state tier — standard, custom, or none — replacing a single present/absent test. A repository whose license file exists but whose text is not a recognized license now earns three quarters of the license weight rather than either full credit or none.

Detection also changed: the state is resolved from all three license sources together (the repository's license metadata, GitHub's community profile, and the Scorecard License check) instead of preferring Scorecard alone. Presence is a logical OR, so a file that any one source sees counts. The sources disagree on roughly 1% of repositories.

Custom licenses already scored slightly below standard ones before this version, because Scorecard grades them 9 out of 10 rather than 10. That gap was inherited from the tool rather than stated as a position; it is now deliberate and documented.

Comparability: existing results were recomputed under 1.3.0 from the data already stored in each report — no repository was rescanned, so nothing moved for any reason other than this change. Movement is small: the license row is 22.5 of 100 points within community health, itself 35% of Community & Adoption, which is 18% of the index.

1.2.0 — 2026-07-14

Published-package registry adapters were added for Go (the module proxy), Maven Central, and NuGet, and PyPI package identification was extended to legacy setup.py manifests. Repositories publishing in those ecosystems now carry registry evidence in package maintenance — publish recency, version history, deprecation state — and NuGet additionally feeds ecosystem adoption through its lifetime download total. Go and Maven Central publish no download statistics of any kind, so they contribute no adoption signal. No formulas or weights changed — only which repositories have registry evidence available.

1.1.0 — 2026-07-14

Community health now detects a license once. It previously carried two overlapping license components — a GitHub community-profile flag and a separate License shared-evidence card. These are merged into a single License row detected by OpenSSF Scorecard's License check, with the community-profile flag kept only as a fallback for repositories that have no Scorecard. Scorecard's own License check remains a full component of Security posture. The merge removes double-counting and defers to Scorecard's more reliable detection where the two sources disagree. This release changes affected community_health scores; reports remain reproducible through their recorded metrics_version.

1.0.0 — 2026-07-13

OpenSSF Scorecard checks now provide shared evidence where a security practice also substantiates another health dimension. Scorecard remains fully risk-weighted in Security posture; seven selected checks additionally receive small, documented weights in their destination metrics: Maintained, Signed-Releases, Contributors, Code-Review, License, CI-Tests, and Pinned-Dependencies.

This is intentional cross-category influence, not a reuse of Scorecard's security-risk weights. A check reported as n/a, or unavailable Scorecard data, is excluded from the destination metric and its remaining components are renormalized. This release changes affected repository scores; reports remain reproducible through their recorded metrics_version.

0.9.0 — 2026-07-07

The security posture fallback stopped treating a missing dependency lockfile as a fault for published libraries. Lockfiles are an application-level practice; many libraries and gems correctly omit them. For those repositories, the fallback component is now excluded and the remaining components renormalize. The OpenSSF Scorecard path was unchanged.

0.8.0 — 2026-06-30

Added the AI Readiness category with four metrics: (agent context, verify loop, code legibility, interfaces) assessing whether a repository supports reliable AI-assisted development. The category carries weight 0.0: it is an independent, additive badge and never changes the overall health index. Existing repository formulas were unchanged.

0.7.0 — 2026-06-20

Supported ecosystems extended. Ecosystem adoption falls back to lifetime total downloads when a registry publishes no monthly figure (RubyGems), so Ruby and Hex packages now receive adoption values. RubyGems and Hex registry adapters added; declared-dependency parsing extended to Go, Maven, RubyGems, NuGet, and Hex. See supported ecosystems.

0.6.0 — 2026-06-09

Security posture rebuilt on the OpenSSF Scorecard: tool-agnostic, risk-weighted checks that no longer penalize projects for using non-GitHub tooling, with inconclusive checks excluded rather than counted as zero. Coarse file-tree checks remain as a fallback. Only the Security category affected.

0.5.0 — 2026-05-29

Package-ecosystem metrics added: ecosystem adoption (registry downloads) in Community & Adoption and package maintenance (publish recency, deprecation) in Sustainability & Governance. Both are null for repositories that publish no package. Category inner weights rebalanced; category weights and other formulas unchanged.

0.4.0 — 2026-05-18

Metrics regrouped into five weighted categories with rolled-up values. Four new repository metrics: release discipline, popularity, stewardship, and documentation. activity renamed development activity. The overall index now rolls up categories rather than individual metrics.

0.3.0 — 2026-05-06

Organization metrics added — profile completeness, portfolio activity, community reach, and an organization overall (see organization assessment). Repository formulas unchanged.

0.2.0 — 2026-04-25

Per-component results added to every metric, so a report shows exactly which criteria passed, partially passed, or were excluded. Formulas, weights, and band thresholds unchanged from 0.1.0.

0.1.0 — 2026-04-15

Initial methodology.

What versioning guarantees

  • Reproducibility — reports record their inputs and methodology version, and the corresponding scoring implementation is published. The documented privacy exception for contributor profiles applies.
  • Comparability — two repositories inspected under the same version are measured by identical rules.
  • Accountability — methodology changes are public, dated, and explained; there are no silent adjustments.

Related: the health index · rating bands · scan configuration