# inspect.software > A public record of open-source software health. Repositories are measured > against a transparent, versioned methodology spanning maintainability, > engineering quality, security posture, ecosystem adoption, and governance; > results are published as reports, 1–100 health indices, and embeddable > badges. Results are signals, not warranties, and are independent of payment. Every page below is served as source Markdown at the linked .md URL; the same content renders as HTML without the extension (e.g. /methodology.md → /methodology). The full corpus in one file: https://inspect.software/llms-full.txt ## Institution - [About inspect.software](https://inspect.software/about.md): A public record of open-source software health — every repository inspected by one published method, versioned methodology, results independent of payment. - [Methodology](https://inspect.software/methodology.md): The complete inspect.software methodology — versioned formulas, category weights, rating bands, missing-data rules, the organization assessment, and the open-source engine that computes them. - [Certification & pricing](https://inspect.software/pricing.md): Free public-interest inspection for high-value open-source repositories; paid certification for private and niche repositories. Payment never changes a result. - [GitHub badges](https://inspect.software/badges.md): Embeddable inspect.software badges — a live health signal for any inspected repository, updated automatically after every scan. Markdown and HTML snippets. - [Frequently asked questions](https://inspect.software/faq.md): Answers about inspect.software — how repositories are inspected, what results mean, free vs. paid coverage, badges, corrections, and independence. - [Contact](https://inspect.software/contact.md): How to reach inspect.software — certification enquiries, data corrections, security disclosures, and general questions. - [Press & brand assets](https://inspect.software/press.md): Logos, colours, boilerplate texts and usage rules for inspect.software — the media kit for journalists, directories, conference organizers and integration documentation. ## Concepts - [The health index](https://inspect.software/wiki/health-index.md): How inspect.software computes the 1–100 open-source health index — components, metrics, weighted categories, and the rules for missing data. - [Rating bands](https://inspect.software/wiki/scoring-bands.md): The seven standardized rating bands — exceptional, excellent, good, moderate, weak, at risk, critical — and the letter grades used across every inspect.software health metric and category. - [Certification levels](https://inspect.software/wiki/certification-levels.md): The three inspect.software certification levels — Certified (A), Certified with Excellence (AA), and Certified AAA — how each maps to the calibrated health index, what a level asserts, and how levels change. - [Signals, not warranties](https://inspect.software/wiki/signals-not-warranties.md): What an inspect.software result does and does not claim — the honest boundary between visible practice signals and a formal audit or guarantee. - [Methodology versions](https://inspect.software/wiki/methodology-versions.md): The complete version history of the inspect.software metrics methodology — every formula, weight, and threshold change, dated and documented. - [Supported package ecosystems](https://inspect.software/wiki/supported-ecosystems.md): The package ecosystems inspect.software reads — nine registries with published-package facts, plus dependency manifests across all of them. - [Software classification](https://inspect.software/wiki/software-classification.md): How inspect.software determines what a repository builds — the multi-label reading of whether software is consumed as code, run as a program, or installed into a host. - [Scan configuration](https://inspect.software/wiki/scan-configuration.md): How parts of the inspect.software methodology can be switched off per scan — and how every report documents exactly what was and was not measured. ## Scoring categories - [Vitality](https://inspect.software/wiki/vitality.md): The Vitality category of the inspect.software health index — whether code is actively written and versioned releases actually ship. Weight: 21% of the overall index. - [Community & Adoption](https://inspect.software/wiki/community-adoption.md): The Community & Adoption category — users, downloads, attention, and a welcoming contributor setup. Weight: 17% of the inspect.software health index. - [Sustainability & Governance](https://inspect.software/wiki/sustainability-governance.md): The heaviest category of the inspect.software health index (23%) — bus factor, responsiveness, organizational stewardship, and package upkeep. - [Engineering Quality](https://inspect.software/wiki/engineering-quality.md): The Engineering Quality category — CI, tests, linting, and documentation practice. Weight: 19% of the inspect.software health index. - [Security](https://inspect.software/wiki/security.md): The Security category — visible OpenSSF Scorecard hygiene and known-vulnerable dependencies, under two red-flag policies. Weight: 16% of the inspect.software health index. - [AI Readiness](https://inspect.software/wiki/ai-readiness.md): The AI Readiness badge — how well a repository supports AI coding agents: agent context, verify loop, code legibility, machine-readable interfaces. ## Repository metrics - [Development activity](https://inspect.software/wiki/development-activity.md): How inspect.software measures development activity — push recency, weekly commit cadence, and commit volume. 12.6% of the overall health index. - [Release discipline](https://inspect.software/wiki/release-discipline.md): How inspect.software measures release discipline — whether versioned releases ship, how recently, and on what cadence. 8.4% of the overall health index. - [Popularity](https://inspect.software/wiki/popularity.md): How inspect.software measures repository popularity — stars, forks, and watchers on a logarithmic scale. 6.8% of the overall health index. - [Community health](https://inspect.software/wiki/community-health.md): How inspect.software measures community health — README, license, contributing guide, code of conduct, and issue/PR templates. 5.95% of the overall index. - [Ecosystem adoption](https://inspect.software/wiki/ecosystem-adoption.md): How inspect.software measures real package adoption — registry downloads and dependents across npm, PyPI, Packagist, and more. 4.25% of the overall index. - [Maintainer resilience](https://inspect.software/wiki/maintainer-resilience.md): How inspect.software measures bus factor, contributor concentration, and breadth — whether a project can survive losing its top maintainer. 6.9% of the index. - [Responsiveness](https://inspect.software/wiki/responsiveness.md): How inspect.software measures responsiveness — issue resolution, lifetime pull-request acceptance, and how a project treats first-time contributors. 5.75% of the overall index. - [Stewardship](https://inspect.software/wiki/stewardship.md): How inspect.software measures who stands behind a repository — organization vs. personal ownership, verified domain, reach, and track record. 5.75% of the index. - [Package maintenance](https://inspect.software/wiki/package-maintenance.md): How inspect.software measures registry upkeep — publish recency, version history, and deprecation state of published packages. 4.6% of the overall index. - [Engineering practices](https://inspect.software/wiki/engineering-practices.md): How inspect.software measures baseline engineering hygiene — CI, tests, linting, pre-commit hooks, and editorconfig. 11.4% of the overall health index. - [Documentation](https://inspect.software/wiki/documentation.md): How inspect.software measures documentation — README, docs directory, documentation site, description, topics, and wiki. 7.6% of the overall health index. - [Security posture](https://inspect.software/wiki/security-posture.md): How inspect.software measures security posture with the OpenSSF Scorecard — risk-weighted, tool-agnostic checks with a documented fallback. 16% of the index. - [Dependency advisories](https://inspect.software/wiki/dependency-advisories.md): How inspect.software matches a repository's resolved dependencies against the OSV advisory database — severity, fix versions, coverage, and the limits of the signal. 20% of the Security category. ## AI Readiness metrics - [AI agent context](https://inspect.software/wiki/ai-agent-context.md): How inspect.software measures agent guidance — CLAUDE.md, AGENTS.md, Cursor rules, Copilot instructions, llms.txt, and whether the commit history states its intent. Part of the AI Readiness badge. - [AI verify loop](https://inspect.software/wiki/ai-verify-loop.md): How inspect.software measures the agent verify loop — one-command bootstrap, tests, lint, type checking, reproducible environments. The heaviest AI Readiness metric. - [AI code legibility](https://inspect.software/wiki/ai-code-legibility.md): How inspect.software measures code legibility for AI models — type-checkable code and manageable file sizes. Part of the AI Readiness badge. - [AI interfaces](https://inspect.software/wiki/ai-interfaces.md): How inspect.software measures machine-readable interfaces — API schemas, MCP servers, and runnable examples. Part of the AI Readiness badge. ## Red flags and policies - [Abandonment](https://inspect.software/wiki/abandonment.md): How inspect.software decides a project has been left unmaintained — why silence alone is never the finding, what counts as an unmet obligation, and what holds the assessment back. - [Malicious dependencies](https://inspect.software/wiki/malicious-dependencies.md): How inspect.software identifies dependencies reported as malicious packages by the OpenSSF corpus, why they are scored apart from vulnerabilities, and what the finding does and does not claim. - [High-Risk Jurisdiction Exposure](https://inspect.software/wiki/jurisdiction-exposure.md): How inspect.software turns public repository-profile evidence into an explainable high-risk jurisdiction exposure signal for repository review. - [Growth Authenticity](https://inspect.software/wiki/growth-authenticity.md): How inspect.software reads a repository's day-by-day star and fork history for growth that organic attention does not produce, and what the Inorganic Growth Policy does about it. ## Organization assessment - [Organization assessment](https://inspect.software/wiki/organization-assessment.md): How inspect.software assesses GitHub organizations — portfolio activity, community reach, and profile completeness on the same 1–100 scale and bands. - [Portfolio activity](https://inspect.software/wiki/portfolio-activity.md): How inspect.software measures an organization's portfolio activity — recently active repos, yearly activity, portfolio size, and original work. 45% of the org index. - [Community reach](https://inspect.software/wiki/community-reach.md): How inspect.software measures an organization's community reach — followers and portfolio-wide stars on logarithmic scales. 30% of the organization index. - [Profile completeness](https://inspect.software/wiki/profile-completeness.md): How inspect.software measures organization profile completeness — verified domain, description, homepage, contact, and identity fields. 25% of the org index. ## Inspection reports The record itself — one report per inspected repository, ~26,000 of them. Every report page is served as Markdown at the same .md convention used above: - Report (Markdown): https://inspect.software/software/{owner}/{name}.md — the health index, every category and metric, the per-criterion breakdown behind each number, and the repository facts they were derived from - Report (HTML): https://inspect.software/software/{owner}/{name} — the same report rendered for readers - Browse or filter the record: https://inspect.software/api/catalog (JSON), or https://inspect.software/sitemap.xml for every report URL ## Machine-readable data - [OpenAPI schema](https://inspect.software/api/openapi.json): machine-readable description of every endpoint below - [Sitemap](https://inspect.software/sitemap.xml): every published page and inspection record - [Catalogue API](https://inspect.software/api/catalog): JSON list of inspected repositories (filters: q, ecosystem, language, band, scanned_within_days, growth, sort) - [Insights API](https://inspect.software/api/insights): aggregate statistics over the record — health distribution, practice adoption, stewardship, ecosystem comparison (optional ?ecosystem=; rendered at /insights) - Report API: https://inspect.software/api/repositories/{owner}/{name}/report — the full JSON inspection report, including every metric's inputs and per-component points - Related API: https://inspect.software/api/repositories/{owner}/{name}/related — inspected repositories sharing this one's catalogue tags and ecosystems - Badge: https://inspect.software/badge/v1/{owner}/{name}.svg — live health badge for any repository in the record ## Optional - [Terms of service](https://inspect.software/terms.md): The terms under which inspect.software publishes inspection results, issues badges, and accepts public-repository submissions. - [Privacy](https://inspect.software/privacy.md): What personal data inspect.software processes, on what legal basis, how long it is kept, who receives it, and the rights that apply. --- # About inspect.software > A public record of open-source software health — every repository inspected by one published method, versioned methodology, results independent of payment. **inspect.software** keeps a public record of open-source software health. Each repository is assessed with the same published, versioned methodology across maintainability, engineering quality, security posture, ecosystem adoption, and governance. The weights and production scanner are public, and payment cannot change a result. ## Mission Make the health, quality, and security of open-source software **legible and trustworthy** for everyone who depends on it — developers choosing a library, security teams reviewing a supply chain, procurement functions approving a vendor's stack. ## Who operates it inspect.software is run by **Vitalii Stepanenko**, from València, Spain. The full identification is in section 10 of the [terms](/terms); enquiries go through [contact](/contact). ## The problem the record exists to solve Modern software is assembled from thousands of open-source dependencies, yet the signals used to judge them are weak. Stars measure popularity, not health. Bus factor is invisible: a package with fifty million weekly downloads maintained by one exhausted volunteer is a systemic risk — the pattern behind left-pad, Log4Shell, and the xz-utils backdoor. Security practice is opaque, and maintenance velocity takes manual digging to read. No consistent, transparent, third-party signal aggregated these into something a developer, a security team, or a CTO could act on. The public record exists to be that signal. Technical health is only part of an enterprise dependency decision. The record also makes policy-defined context visible through signals such as [high-risk jurisdiction exposure](/wiki/jurisdiction-exposure), helping security and procurement teams identify dependencies that merit enhanced review without turning public profile evidence into a judgement about people. ## Principles 1. **Transparency is the product.** The [methodology](/methodology) and [wiki](/wiki) document every metric, weight, formula, and threshold. The AGPL-licensed [scanner](https://github.com/inspect-software/scanner) is the production engine used to generate reports. Each report includes its observed evidence so the result can be checked manually or recomputed with the published code. 2. **Results are independent of payment.** No commercial relationship — certification fees, sponsorship, vendor alignment — can alter a published result. Payment buys analysis, privacy, and frequency; never a better number. 3. **Signals, not warranties.** The record states exactly what it measures and no more — see [how to read the results](/wiki/signals-not-warranties). 4. **Versioned and accountable.** Methodology changes are dated, explained, and recorded in every report — see [methodology versions](/wiki/methodology-versions). 5. **Public good first.** Inspection of high public-value open-source software is free and its results are public, permanently. ## How the institution sustains itself Free public-interest coverage is funded by paid services around it: audits of private repositories, on-demand certification of niche public repositories, continuous monitoring, and enterprise reporting — described on the [certification & pricing](/pricing) page. The guardrail is absolute: **a higher result is never for sale.** ## The record The [public record](/#record) lists every inspected repository with its full report: category profile, per-metric breakdowns, component evidence, and the raw machine-readable data. Repositories carry [embeddable badges](/badges) reflecting their current standing. Questions and corrections are welcome — data errors can be flagged through the [contact](/contact) channels, and the correction path is part of the methodology's accountability. --- # Methodology > The complete inspect.software methodology — versioned formulas, category weights, rating bands, missing-data rules, the organization assessment, and the open-source engine that computes them. This page specifies how values in the public record are computed. The methodology is **versioned as a whole** — currently **v2.10.0** — and each report records the version used. The production scanner is open source, so the specification can be checked against its implementation. See *Open-source implementation* below. Per-metric detail lives in the [wiki](/wiki); this page describes the complete system.
◇
Signals, not warranties. A high value reflects publicly visible good practice; it is not a code audit and not a security guarantee. See how to read the results.
## The standardized scale Every measurement — component, metric, category, overall — is an integer in **1–100**, higher is better, mapped to seven standardized [rating bands](/wiki/scoring-bands): *exceptional* (93–100), *excellent* (80–92), *good* (65–79), *moderate* (50–64), *weak* (35–49), *at risk* (20–34), *critical* (1–19). The overall index is additionally [calibrated against the distribution of the public record](/wiki/health-index), so its bands carry percentile meaning. Band thresholds and the calibration curve are part of the versioned methodology. ## The three-level hierarchy Values roll up transparently: **components → metrics → categories → overall** (detailed in [the health index](/wiki/health-index)). 1. A **metric** is normally a weighted sum of components; component weights sum to 100. Every component is reported with its earned and maximum points and a status — met, partial, missed, or excluded. Four documented policies are the exception: a dependency reported as a malicious package multiplies and caps Security posture, confirmed high-risk jurisdiction exposure does the same at a looser ceiling, a confirmed inorganic growth finding discounts the stars and forks components of popularity, and an abandonment finding multiplies the health index itself. 2. A **category** is normally the weighted mean of its available metrics. All four policies are penalty multipliers only — none can improve the metric it acts on, and none carries additive weight of its own. 3. The **overall health index** begins as the weighted mean of the available categories, calibrated onto the published index scale. Where a policy fires it applies its multiplier, and some also impose a ceiling: **19 (critical)** for a malicious dependency or a declared abandonment, **34 (at risk)** for high-risk jurisdiction exposure or a likely abandonment. Where several fire, only the strictest applies — they never compound. ### Missing data is never a zero When a component's underlying data is unavailable, it is **excluded and the remaining weights renormalized** — a project is measured only on what can be observed. The same rule applies to whole metrics and categories, and every renormalization is recorded in the affected metric's note. ## Red flags Most evidence in this methodology is scored: it earns points, those points sum into a metric, and the metric averages into a category. A **red flag** is the exception — a finding that does not score into a value but *adjusts* one, and that the report presents as a named alert rather than as a number. The class exists because some findings cannot be averaged away honestly. A dependency reported as malicious is not eight points of engineering practice; it is a state. Stars that arrived on a delivery schedule are not a low score for popularity; they are a reason to stop believing the count. Scoring either as points off would let a strong showing elsewhere absorb it, which is exactly the wrong outcome. Every red flag in this methodology obeys the same five rules: 1. **It only ever moves a value downward.** No red flag carries additive weight, and a clean result never raises anything. Absence of a finding is not a credential. 2. **It is stated, not merely subtracted.** The finding appears as an alert on the report, names its evidence, and links to the guide that defines it. A reader must be able to see *why* a rating moved. 3. **It describes an observation, never an intent.** Each is a statement about public evidence — a location a profile published, a package an advisory database names, the timing of star events. None establishes motive, responsibility, or wrongdoing by any person. 4. **Unanswerable is not clean.** Where the evidence a flag needs was never collected, the report says so. A repository that could not be assessed is never presented as one that passed. 5. **Only the strictest applies.** Where more than one flag fires, the gravest governs the score alone and the rest are reported without moving it again. A multiplier states how serious a finding is; multiplying several together produces a number no policy chose. The flags currently defined are the [Inorganic Growth Policy](/wiki/growth-authenticity), the [Abandonment Policy](/wiki/abandonment), the [Malicious Dependency Policy](/wiki/malicious-dependencies), and the [High-Risk Jurisdiction Policy](/wiki/jurisdiction-exposure), each specified below. How often each is found across the whole record is published in the [aggregate statistics](/insights). ## Repository categories and weights | Category | Weight | Metrics (weight within category) | | -------- | ------ | -------------------------------- | | [Vitality](/wiki/vitality) | 21% | [development activity](/wiki/development-activity) (60%), [release discipline](/wiki/release-discipline) (40%), × [Abandonment Policy](/wiki/abandonment) | | [Community & Adoption](/wiki/community-adoption) | 17% | [popularity](/wiki/popularity) (40%) × [Inorganic Growth Policy](/wiki/growth-authenticity), [community health](/wiki/community-health) (35%), [ecosystem adoption](/wiki/ecosystem-adoption) (25%) | | [Sustainability & Governance](/wiki/sustainability-governance) | 23% | [maintainer resilience](/wiki/maintainer-resilience) (30%), [responsiveness](/wiki/responsiveness) (25%), [stewardship](/wiki/stewardship) (25%), [package maintenance](/wiki/package-maintenance) (20%) | | [Engineering Quality](/wiki/engineering-quality) | 19% | [engineering practices](/wiki/engineering-practices) (60%), [documentation](/wiki/documentation) (40%) | | [Security](/wiki/security) | 16% | [security posture](/wiki/security-posture) (80%), [dependency advisories](/wiki/dependency-advisories) (20%), × [Malicious Dependency Policy](/wiki/malicious-dependencies), × [High-Risk Jurisdiction Policy](/wiki/jurisdiction-exposure) | | [AI Readiness](/wiki/ai-readiness) | 4% | [agent context](/wiki/ai-agent-context) (30%), [verify loop](/wiki/ai-verify-loop) (40%), [code legibility](/wiki/ai-code-legibility) (15%), [interfaces](/wiki/ai-interfaces) (15%) | ### Inorganic Growth Policy A GitHub star is the most widely read trust signal in open source, and the only one with no issuer: stars and forks are sold openly, in bulk. The per-day star and fork history collected for each report is therefore read for growth whose shape organic attention does not produce — a burst that arrived on a schedule, brought no forks, left no tail, or preceded anything the project had released. A burst alone is never a finding; real projects launch and trend. A window is confirmed only when at least two independent signals corroborate it. One confirmed window discounts the stars and forks components of popularity by 40%, two or more by 70%. Watchers and every other category are untouched, and a clean history never raises a score. Repositories whose collected history cannot answer the question — no history, under 100 stars, or a window spanning under 60 days — read **unverified** and are not penalized. Collection is bounded to a recent window, so manipulation older than it is invisible to the policy; *unverified* means unanswerable, not clean. The complete [growth authenticity guide](/wiki/growth-authenticity) states the thresholds, the four states, and the limits of the evidence. This is a statement about the timing of public events. It does not establish that attention was purchased, or that a repository's maintainers were involved if it was. ### Abandonment Policy **A project is not abandoned because it is quiet.** Every tool in this space answers "is this 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. So the finding rests on a different question — abandonment is an *unmet obligation*, not an absence of noise. A quiet repository with nothing open owes nobody anything. A quiet repository with fifteen unreviewed pull requests, or a year-old advisory whose patch shipped the same week, is not resting. Silence is necessary and never sufficient. A drought is measured from the last **human** commit, and it only becomes a finding when unmet obligations corroborate it: an unanswered contribution queue, issues a maintainer never 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, or a sole maintainer absent from the whole commit window. Readings that *explain* the silence — a maintainer answering the tracker, nothing open to answer, a release within the year, clean dependencies — hold the result at **dormant**, and dormant carries no penalty at all. Quiet is already priced inside [development activity](/wiki/development-activity); charging for it twice would punish exactly the finished, stable libraries that deserve confidence. Findings multiply the health index: 85% *at risk*, 60% *likely abandoned* with an At Risk ceiling of 34, and 40% *declared* with a Critical ceiling of 19. *Declared* is the maintainer's own statement quoted rather than inferred — the repository is archived, or every package it publishes has been deprecated or yanked. Repositories with no commit sample, an unreadable tracker, or under 180 days of history read **unverified** and are not penalized. The complete [abandonment guide](/wiki/abandonment) states every threshold, signal and guard. ### Malicious Dependency Policy A vulnerable dependency is a mistake; a malicious one is an attack. Each report matches the resolved dependency graph against the OpenSSF malicious-packages corpus, which OSV.dev serves alongside ordinary advisories — so the check costs no request the report was not already making. A malicious package carries no severity rating and no fixed version, because it has neither: it is a state, not a degree, and the remedy is removal or moving off the compromised name rather than an upgrade. Where the registry has since pulled the exact version a repository resolves to, nothing installable remains: the finding is reported for the record and not scored. Scoring it as an advisory therefore understated it, and it is instead removed from the advisory findings and treated as a flag. Any confirmed report applies a 35% multiplier and a **Critical ceiling of 19** to Security posture and to the health index — stricter than the jurisdiction ceiling, because this 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 graph. The finding is rare by construction — registries remove malicious packages within days, and a pre-release run over 46,889 resolved dependencies found none. It concerns the package as published, not the maintainers of the scanned repository, which may have resolved it unknowingly. The complete [malicious dependencies guide](/wiki/malicious-dependencies) states the source, the scoring, and the limits of the claim. ### High-Risk Jurisdiction Policy High-confidence, self-published public profile evidence within the current Russia, Iran, and North Korea scope creates a High-Risk Jurisdiction Policy alert. Owner evidence multiplies Security posture by 20%, displayed top-contributor evidence by 50%, and a contributor's public organization affiliation by 75%. Ambiguous and missing location data do not reduce the score. This is an enhanced-review signal, not an inference of nationality, citizenship, sanctions status, intent, or trustworthiness. Any confirmed match applies the same multiplier and **At Risk ceiling of 34** to Security posture and to the health index. Security reflects the adjusted posture without multiplying twice. Base and adjusted values remain in the report for transparency. The complete [high-risk jurisdiction exposure guide](/wiki/jurisdiction-exposure) explains the enterprise use cases, evidence safeguards, and proportionate review actions behind the policy. A metric's effective weight is normally *category weight × within-category weight*. The Inorganic Growth, Abandonment, Malicious Dependency and High-Risk Jurisdiction policies are the multiplier exceptions, and none has additive weight of its own. [AI Readiness](/wiki/ai-readiness) carries a deliberately small 4% weight, sized together with the calibration curve so that a repository with no agent tooling can still reach 100/100. The registry-backed metrics ([ecosystem adoption](/wiki/ecosystem-adoption), [package maintenance](/wiki/package-maintenance)) apply only to repositories that publish a package — see [supported ecosystems](/wiki/supported-ecosystems). ### Dependency advisories A repository's dependencies are matched against [OSV](https://osv.dev), the open advisory database aggregating GHSA, PYSEC, RUSTSEC and others. Affected packages are reported with their severity, the advisories concerned, and the version each was fixed in. **What is measured is what a consumer installs.** For a repository that publishes a package, the assessed set is that package's runtime dependency closure — the packages an installation actually pulls in. Only where a repository publishes nothing is its own dependency graph used instead, and that graph also contains development and test pins that never ship. Every report states which of the two it assessed, and names the package. The distinction changes results materially. Flask's repository graph carries advisories against old versions of Werkzeug and Jinja pinned for its own test matrix; installing Flask pulls in six packages, none of them affected. Only the second fact is about the software anyone depends on. Runtime closures are resolvable today for npm, PyPI, crates.io and Maven. Packages published elsewhere are assessed against the repository graph until the index covers them. This is a **separate metric from security posture, deliberately**. Scorecard's own vulnerabilities check already queries the same database and already contributes to posture; scoring a second signal from it inside the same metric would count one body of evidence twice. The two answer different questions — posture asks whether the project carries known-vulnerable dependencies at all, this asks which, how severe, and what fixes them. What it does not claim: an advisory here means a resolved version falls inside an advisory's affected range. Reachability is not analysed, and most advisories in a large dependency closure are not exploitable in context. Every report states its coverage — how many dependencies were assessed and how many could not be. Repositories where neither set can be resolved are not penalized: the metric is excluded and the remaining weight renormalized, exactly as any other unavailable input. ## Shared Scorecard evidence Security posture remains the complete risk-weighted OpenSSF Scorecard assessment. Seven checks also substantiate the other dimensions they plainly describe: maintenance, signed releases, contributors, code review, license, CI tests, and pinned dependencies. Six appear in their destination metric as small additive cards while keeping their Security contribution. The seventh, license, is different: it is one input to the license signal in [community health](/wiki/community-health) rather than the whole of it — see below. This intentional cross-category influence is documented per metric; Scorecard `n/a` and unavailable results are excluded everywhere. ## Licensing A repository's licence resolves to one of three states, from every available source together — the repository's own licence metadata, GitHub's community profile, and the OpenSSF Scorecard `License` check. A file that any one source sees counts as present, so a single unavailable endpoint cannot report a licence as missing. | State | Meaning | Credit | |---|---|---| | Standard | A recognized licence, identified by SPDX code | full | | Custom | A licence file is present, but its text is not a recognized licence | three quarters | | None | No source found a licence file | none | A custom licence is a real licence and scores most of the weight. It does not score all of it: a licence that automated tooling cannot identify is a genuine obstacle to adoption, because policy tooling, corporate review and package registries all key off recognized identifiers, and a reader cannot establish what they are permitted to do without reading the text themselves. Before v1.3.0 custom licences already scored slightly lower, as an artefact of how Scorecard grades them rather than as a stated position. The tier above is deliberate, and it is now the whole licence signal. ## Organization assessment Organizations are assessed on the same scale and bands, in two categories — Activity & Reach (75%) and Governance & Profile (25%) — detailed in [organization assessment](/wiki/organization-assessment). A repository's report also embeds its owning account's profile, which drives the [stewardship](/wiki/stewardship) metric. ## Configuration A scan can disable a component, metric, or category. The exclusion works like missing data and is **embedded in the report**, so its effect on the score can be reproduced. Configuration never alters a formula, weight, or threshold — see [scan configuration](/wiki/scan-configuration). ## Open-source implementation The production scanner is published at [inspect-software/scanner](https://github.com/inspect-software/scanner) under the **GNU Affero General Public License v3.0 or later**. The worker imports this package to produce reports; there is no separate private scoring engine. Its source contains the category weights, red-flag multipliers and ceilings, missing-data rules, and calibration curve described above. A result can be checked at three levels: 1. **Inspect the formula.** The weights, thresholds, and band boundaries are defined in the source. `METRICS_VERSION` in `src/scanner/metrics.py` identifies the methodology implemented by that revision and matches `metrics.metrics_version` in its reports. 2. **Recompute stored evidence.** Download **Raw JSON report** from a report page. Check out the scanner revision whose `METRICS_VERSION` matches the report, then use its `data` and `config` as inputs to `compute_metrics`. 3. **Run a new scan.** `inspect-scan OWNER/REPO` collects current GitHub and registry data and produces the same report schema. ### Reproduction limits Public reports omit contributor profile details such as name, location, company, and organization memberships. These fields are used by [high-risk jurisdiction exposure](/wiki/jurisdiction-exposure), alongside the owner's profile. Recomputing public JSON can therefore produce a different jurisdiction adjustment when contributor evidence affected the original result. An objection under [data-protection law](/privacy) also excludes the relevant profile from future scans. A new scan can differ from an earlier report for two further reasons: - **Repository evidence changes.** Stars, commits, releases, and advisories can change after a report is published. Each report records when its evidence was collected. - **Scorecard is best-effort.** [Security posture](/wiki/security-posture) uses OpenSSF Scorecard, which requires the `scorecard` binary and a GitHub token. If it cannot run, the scanner records that fact and uses coarse file checks. Report engine defects in the scanner's issue tracker. Report vulnerabilities privately. Disputes about published evidence remain [correction requests](/contact). ## Versioning Any change to a formula, weight, band threshold, or the calibration curve bumps the metrics version. The complete dated history — from 0.1.0 to the current 2.10.0 — is in [methodology versions](/wiki/methodology-versions). ## Worked example pallets/flask (organization-owned), with category values as inspected 2026-07-16, recomputed under the current weights — the live figures are always in the [full report](/software/pallets/flask): | Category | Value | Weight | Contribution | | -------- | ----: | -----: | -----------: | | [Vitality](/wiki/vitality) | 70 | 21% | 14.70 | | [Community & Adoption](/wiki/community-adoption) | 96 | 17% | 16.32 | | [Sustainability & Governance](/wiki/sustainability-governance) | 74 | 23% | 17.02 | | [Engineering Quality](/wiki/engineering-quality) | 96 | 19% | 18.24 | | [Security](/wiki/security) | 69 | 16% | 11.04 | | [AI Readiness](/wiki/ai-readiness) | 58 | 4% | 2.32 | | **Raw weighted mean** | | | **79.64 → 80** | | **Calibrated health index** | | | **80 → 94, exceptional (AAA)** | The final row is the [calibration](/wiki/health-index) of the raw mean onto the published index scale, which is what the report and the badge display. The same repository under a personal account with the same following would lose the organization-backing margin and the verified-domain component of [stewardship](/wiki/stewardship), pulling the Governance category down with it. That ownership influence is deliberate, explicit, and auditable. Every figure above is a snapshot. Values move as the evidence changes and as the methodology is versioned; the linked report always carries the current ones. ## Roadmap (not yet measured) - Issue and PR latency percentiles, time-windowed rather than lifetime. - Dependency freshness: how many dependencies are deprecated upstream, archived, or years past their last release. Known advisories are now measured — see [dependency advisories](/wiki/dependency-advisories) — but freshness is a separate signal and is not yet scored. - Popularity-normalized expectations (a 50-star repository is not held to a 50,000-star repository's baseline). - Test coverage and CI pass-rate signals. Each arrives with a version bump, never silently. --- # Certification & pricing > Free public-interest inspection for high-value open-source repositories; paid certification for private and niche repositories. Payment never changes a result. The economics of inspect.software follow one rule: **inspection of software the public depends on is free, and depth and privacy are paid for.** Revenue from paid services funds the free public record.
◇
A higher result is never for sale. Payment buys analysis, privacy, frequency, and reporting — the methodology and the outcome are identical on every tier. See signals, not warranties.
## Free — the public record Repositories of high public value are inspected free of charge: - Full health report against the complete [versioned methodology](/methodology), published in the [public record](/#record). - An embeddable [GitHub badge](/badges) reflecting the current standing. - Re-inspection when a new scan is submitted or scheduled by an operator. Eligibility is assessed automatically at submission against documented public-interest thresholds (adoption, ecosystem presence, activity). Any GitHub account may submit a public repository for consideration. ## Certification levels Certification is graded, not binary. A repository whose inspection places it in one of the top three [rating bands](/wiki/scoring-bands) holds the corresponding [certification level](/wiki/certification-levels): | Level | Grade | Band | Health index | | ----- | ----- | ---- | ------------ | | **Certified AAA** | AAA | Exceptional | 93–100 | | **Certified with Excellence** | AA | Excellent | 80–92 | | **Certified** | A | Good | 65–79 | The level follows mechanically from the published band — the same rule for a free public-interest inspection and a paid on-demand one. Payment determines *whether* an inspection runs, never *what* it finds. ## Paid — certification and depth Repositories outside the free thresholds, and organizations needing more than the public record offers: | Service | For | What it provides | | ------- | --- | ---------------- | | **On-demand certification** | Maintainers of niche public repositories | Full inspection and badge now, without waiting for free coverage; paid from an account balance directly at submission | | **Developer program** | Maintainers inspecting their own work regularly | A subscription covering inspections of repositories the account owns or maintains, however niche — in place of per-inspection credits | | **Private repository audit** | Organizations with closed source | Planned service; currently arranged only through a separate engagement | | **Continuous monitoring** | Engineering and security teams | Scheduled re-inspection with alerts on regressions — band drops, security posture changes, bus-factor decline | | **Deep security review** | Security-conscious organizations | Expanded supply-chain and static-analysis coverage beyond the standard posture signals | | **Enterprise reporting** | Procurement, platform, and compliance teams | Portfolio views across dependencies and exportable, compliance-ready reporting | | **API access** | Platforms and developer tools | Programmatic access to published results and metrics | ## Current prices On-demand certification and the developer program are available today. Prices are in US dollars; payment is handled by Stripe. | Offer | Price | | ----- | ----- | | **Starting balance** | 100 credits, free with every new account | | **Inspection of a below-threshold repository** | 20 credits | | **Credit packs** | $5 — 100 credits · $20 — 450 credits · $50 — 1,250 credits | | **Developer program** | $10 per month | Credits are purchased on the [account profile](/profile) or granted by a code; the profile always shows the prices in force. The remaining services are being introduced in stages; terms are documented per engagement. Enquiries: [mail@inspect.software](mailto:mail@inspect.software). ## What payment can never do - Change a formula, weight, threshold, or published value. - Remove or suppress an unfavorable published result. - Buy placement or ranking in the public record. Where a paid scan narrows the methodology (an agreed [scan configuration](/wiki/scan-configuration)), the report itself documents exactly what was measured and what was excluded. ## Why free coverage is sustainable Free inspection is bounded to genuinely popular, high-public-value software — the packages whose health is systemic. The reasoning is documented openly in the [about](/about) page's principles. --- # GitHub badges > Embeddable inspect.software badges — a live health signal for any inspected repository, updated automatically after every scan. Markdown and HTML snippets. Every repository in the public record carries an embeddable **badge**: a small SVG showing the current health index and [rating band](/wiki/scoring-bands), linking back to the full report. The badge is the record made visible where decisions happen — in the README, next to the installation instructions. ## Embedding a badge Each report page provides copy-ready snippets for its repository. The pattern: ```markdown [![inspect.software](https://raw.githubusercontent.com/inspect-software/badges/main/v1/O/OWNER/REPO.svg)](https://inspect.software/software/OWNER/REPO) ``` ```html inspect.software health badge for OWNER/REPO ``` Replace `OWNER/REPO` with the repository's full name, and `O` with the first character of the owner name in lowercase — badges are filed under that character so no single directory in the repository grows unbrowsable. Copying the exact snippets from the repository's report page in the [public record](/#record) avoids getting it wrong. ## shields.io For READMEs that standardize on [shields.io](https://shields.io) badges, the record is also available through shields' *endpoint badge*. Every repository serves its current state as endpoint JSON at `https://inspect.software/badge/v1/OWNER/REPO.json`, which shields renders in its own visual language: ```markdown [![software health](https://img.shields.io/endpoint?url=https%3A%2F%2Finspect.software%2Fbadge%2Fv1%2FOWNER%2FREPO.json)](https://inspect.software/software/OWNER/REPO) ``` The rendered badge states the same index, band vocabulary, and band color as the native badge — certified repositories lead with their letter grade — and refreshes on the same hourly schedule. All of shields' style parameters (`style=`, `logo=`, …) apply as on any other shields badge. ## How badges behave - **Always current.** The badge reflects the latest published inspection and updates automatically after every scan — no re-embedding needed. - **Served from GitHub.** Badge images are published to the public [inspect-software/badges](https://github.com/inspect-software/badges) repository and delivered by GitHub's own content network. A README carrying a badge does not depend on this site being reachable. - **Versioned path.** The `/v1/` path segment is stable; any future change to badge semantics arrives as a new version, never as a silent change. - **Band-colored.** The badge carries the color of the repository's current band, from *exceptional* deep green to *critical* red, and states the band in words beside the index. - **Certified repositories carry a seal.** Repositories in the top three bands show an embossed rosette bearing their letter grade — **A**, **AA**, or **AAA** — the visible mark of their [certification level](/wiki/certification-levels). The seal is a certification mark, so a repository below *Good* does not carry one; its badge states the band and the index without it. - **One fixed size.** Every badge is 137×20 pixels whatever the index says, so a README never reflows when a score moves and a row of badges stays flush. - **Never broken.** A repository not yet in the record serves a neutral badge rather than a broken image. ## What a badge asserts A badge asserts exactly what the report behind it asserts: measured, publicly visible practice under a [versioned methodology](/methodology) — and nothing more. It is a signal for review, not a warranty of quality or security (see [signals, not warranties](/wiki/signals-not-warranties)). The linked report always shows the full category profile, every metric's components, and the raw data. ## Getting a badge 1. Submit the repository on the [home page](/) (GitHub sign-in required). 2. High public-value repositories are inspected free; others follow the [certification route](/pricing). 3. Once the report is published, copy the badge snippets from the report page. --- # Frequently asked questions > Answers about inspect.software — how repositories are inspected, what results mean, free vs. paid coverage, badges, corrections, and independence. ## About the results ### What does the health index actually measure? Publicly visible practice: commit and release history, contributor distribution, community files, engineering hygiene, security signals, and registry state — combined through a [transparent, versioned methodology](/methodology) into one 1–100 index with seven [rating bands](/wiki/scoring-bands). Full detail per metric is in the [wiki](/wiki). ### Is a high value a guarantee the software is safe? No. Results are **signals, not warranties**: no line-by-line audit is performed, and no methodology can rule out an undiscovered vulnerability. What a high value does mean is documented precisely in [signals, not warranties](/wiki/signals-not-warranties). ### Why did a repository's value change without any code changes? Two legitimate reasons: the observable evidence changed (a release aged past a threshold, an issue backlog grew), or the methodology version changed — every formula change is dated and documented in [methodology versions](/wiki/methodology-versions), and each report records the version that produced it. ### A metric shows "excluded" components or a null value. Is that a penalty? The opposite. Data that cannot be observed — no published package, no issue history — is **excluded and the remaining weights renormalized**, never counted as zero. The rules are in [the health index](/wiki/health-index). ### Why does organization ownership raise a repository's value? Organization backing signals shared, accountable stewardship that can outlive any single maintainer. The lift is deliberate, bounded, and fully documented in [stewardship](/wiki/stewardship) — one of the few places the methodology takes an explicit position. ## Submissions and coverage ### How does a repository get into the record? Any GitHub account may submit a public repository on the [home page](/). Repositories meeting the documented public-interest thresholds are inspected free; others can proceed through the paid [certification route](/pricing) — owners and maintainers can pay from an account balance directly at submission. ### Which ecosystems are supported? GitHub repositories in any language, with registry evidence read from npm, PyPI, Packagist, crates.io, Go, RubyGems, NuGet, and Hex — the full list and fallback rules are in [supported ecosystems](/wiki/supported-ecosystems). ### Can a private repository be inspected? Private repository audits are part of the commercial roadmap, but they are not available through the current self-service product. Contact [mail@inspect.software](mailto:mail@inspect.software) to discuss a future engagement. ### Can a repository be removed from the public record? No. Published results for public repositories stay published. Data errors are corrected, not removed: see the correction question below. ## Trust and independence ### Can payment improve a result? No. Payment buys analysis, privacy, and frequency — never a different number. The methodology and formulas are identical on every tier, and no commercial relationship can alter a published result. See [about](/about) for the institutional principles. ### The data about a repository is wrong. How is it corrected? Flag it through the [contact](/contact) channels with the repository name and the specific value in question. Confirmed data errors trigger a re-scan; methodology disagreements are answered with the documented formula — and sometimes become documented roadmap items. ### Is the scoring engine open source? Yes. [inspect-software/scanner](https://github.com/inspect-software/scanner) is the production scanner used to collect evidence and compute the metrics, bands, and index in each report. It is licensed under the **GNU Affero General Public License v3.0 or later**. The surrounding platform — the website, database, and scan queue — is not open source. A commercial licence is available for uses incompatible with the AGPL; enquire through [contact](/contact). ### Can the results be reproduced independently? Yes, by design. Every report embeds its inputs, per-component points, scan configuration, and methodology version; every formula is published. Any value in the record can be recomputed by hand from the report's own data. ### Can the published statistics be reused? The aggregate statistics on the [insights](/insights) pages, and the JSON endpoint behind them, are published under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — reuse them in an article, a chart, or a paper, commercially or not, carrying the attribution `inspect.software — https://inspect.software` with a link back. The per-repository record is not covered by that licence and stays under the [terms](/terms); individual reports may still be cited and quoted. ## Certification and badges ### What do the certification levels mean? A repository in one of the top three [rating bands](/wiki/scoring-bands) holds the corresponding [certification level](/wiki/certification-levels): **Certified** (Good, grade A), **Certified with Excellence** (Excellent, grade AA), or **Certified AAA** (Exceptional, the record's top ≈5%). The level follows mechanically from the published band — payment can start an inspection but can never choose its outcome. ### How is a badge added to a README? Copy the Markdown or HTML snippet from the repository's report page — the badge updates automatically after every scan. Details on [the badges page](/badges). ### What does the badge show for an unscanned repository? A neutral "pending" badge — never a broken image, and never an invented number. --- # Contact > How to reach inspect.software — certification enquiries, data corrections, security disclosures, and general questions. The channels below route to the people who operate inspect.software directly. ## Certification and commercial enquiries Private repository audits, on-demand certification, monitoring, and enterprise reporting: **[mail@inspect.software](mailto:mail@inspect.software)** The available services and the rules they operate under are described on the [certification & pricing](/pricing) page — including the rule that payment never changes a result. ## Data corrections A factual error in a published report — a mismatched package, stale evidence, a value that cannot be reproduced from its inputs — should be flagged with the repository's full name and the specific metric in question: **[mail@inspect.software](mailto:mail@inspect.software)** Confirmed data errors trigger a re-scan. Disagreements with the methodology itself are answered with the documented formula; well-argued cases inform the [methodology roadmap](/methodology). If the code and documentation disagree, open an issue in the scanner's [public repository](https://github.com/inspect-software/scanner), where the diagnosis and fix can be reviewed. ## Security Report a vulnerability in inspect.software or the published scanner privately to the same address, with *security* in the subject line, before public disclosure. Do not open a public issue. Reports are acknowledged and handled with priority. ## Data protection Requests about personal data — access, correction, erasure, restriction, portability, or an objection to processing — go to the same address, and are answered within one month: **[mail@inspect.software](mailto:mail@inspect.software)** Two cases come up most often. A **contributor** whose public GitHub profile was read for a report may have those enriched fields deleted and excluded from future scans. A **maintainer** whose address was collected from a package registry may have it deleted the same way. Neither request has to be justified. What is processed, on what basis, and for how long is set out on the [privacy](/privacy) page, which also names the supervisory authority. ## Methodology questions Most questions are already answered in public documentation: - [Methodology](/methodology) — the complete specification. - [Wiki](/wiki) — per-metric and per-category reference. - [FAQ](/faq) — common questions, including corrections and independence. - [Scanner source](https://github.com/inspect-software/scanner) — the AGPL-licensed production engine that computes published values. --- # Press & brand assets > Logos, colours, boilerplate texts and usage rules for inspect.software — the media kit for journalists, directories, conference organizers and integration documentation. Everything on this page may be used to refer to inspect.software in editorial coverage, conference material, directories, and documentation that mentions the record. The assets are generated from the running site, so what is downloaded here is what appears in the header. ## Logo The lockup is the primary form: the mark and the name together. The mark alone is for contexts where the name is already established — avatars, app tiles, favicons.
The inspect.software lockup on a light background
LockupLight backgroundsSVGPNG 1024PNG 2048
The inspect.software lockup on a dark background
Lockup on darkDark backgroundsSVGPNG 1024PNG 2048
The inspect.software mark
MarkAvatars, tiles, faviconsSVGPNG 256PNG 512PNG 1024
The inspect.software wordmark
WordmarkWhere a mark already appearsSVGBlackWhite
The one-colour inspect.software lockup in black
One colourPrint, embossing, engravingLockupMark
The one-colour inspect.software lockup in white
One colour, reversedOver photography or solid colourLockupMark
Every file above, together with a short usage summary: **[inspect-software-press-kit.zip](/press/inspect-software-press-kit.zip)**. ## Using the assets - **Keep the proportions.** Scale the files; do not redraw, stretch, rotate, or rebuild the lockup from its parts. - **Keep the colours.** The full-colour files are for colour reproduction; the one-colour files are for everything else. No other recolouring. - **Leave clear space.** At least the height of the mark on every side, free of type, rules, and other logos. - **Respect the minimum size.** The lockup stays legible down to a mark height of 16 pixels; below that, the mark alone. - **No effects.** No shadows, outlines, gradients, glows, or containers added on top of what the files already carry. - **No implied endorsement.** The assets identify inspect.software. They do not signal a partnership, a certification, or an approval of the material they appear in.
△
The badge and the certification seal are not brand assets. A badge states one repository's inspected result, and a seal states its certification level. Both are certification marks, carried only by the repository that earned them, and neither may be used as decoration or as a general logo for inspect.software.
## Colour
Ink#0F2335 Green#25A86F Green on dark#3FD39A Blue#3868FF Ground#F6F9FF
Ink carries the name, green carries the domain, and blue is reserved for links and interactive elements. The band colours that appear in reports — from *exceptional* deep green to *critical* red — belong to the [rating scale](/wiki/scoring-bands) and are documented there. ## Typography The site is set in **Geist** and **Geist Mono**, both under the SIL Open Font License. The wordmark files carry outlines rather than live text, so no font installation is required to reproduce them. ## The name inspect.software is written as one word, lowercase, always with the dot — including at the start of a sentence. Not *Inspect Software*, not *Inspect.Software*, not *inspect-software* outside of a URL or an account handle. On first mention in prose, "the public record inspect.software" reads naturally and avoids a sentence opening on a lowercase word. ## Boilerplate Approved descriptions, in three lengths. Shortening one further risks losing the qualifications that make it accurate. **One line** > inspect.software keeps a public record of open-source software health. **Short** > inspect.software is an independent public record of open-source software > health. Every repository is assessed by the same published, versioned > methodology, spanning maintainability, engineering quality, security > posture, ecosystem adoption, and governance. The scanner that produces the > results is open source, each report carries the evidence behind it, and no > payment can change an outcome. **Long** > inspect.software is an independent public record of open-source software > health. Modern software is assembled from thousands of open-source > dependencies, yet the signals available for judging them are weak: stars > measure popularity rather than health, and a package with millions of > weekly downloads maintained by a single volunteer looks, from the outside, > like any other. > > The record inspects repositories against one published, versioned > methodology, spanning maintainability, engineering quality, security > posture, ecosystem adoption, and governance, and publishes each result as a > report, a health index, and an embeddable badge. Weights, formulas and > thresholds are documented, the production scanner is released under the > AGPL, and every report carries the observed evidence, so any figure can be > checked by hand or recomputed from the published code. Results are signals > rather than warranties, and no commercial relationship can change one. ## Facts - **What it is** — a public record of open-source software health, published as reports, health indices, and badges. - **Methodology** — one published, versioned specification; see [methodology](/methodology) for the current version and its full text. - **Scanner** — AGPL-licensed and public at [inspect-software/scanner](https://github.com/inspect-software/scanner). - **Independence** — results are independent of payment; see [certification & pricing](/pricing). - **Operator** — Vitalii Stepanenko, València, Spain; full identification in section 10 of the [terms](/terms). - **Corpus size** — deliberately not stated here, because it changes daily. The current figures are on the [front page](/) and in the public `/api/stats` endpoint. ## Contact Press enquiries, interview requests, and questions about a published result: **[mail@inspect.software](mailto:mail@inspect.software)**, with *press* in the subject line. Corrections to a specific report follow the [data corrections](/contact) route instead, which triggers a re-scan when an error is confirmed. --- # The health index > How inspect.software computes the 1–100 open-source health index — components, metrics, weighted categories, and the rules for missing data. Every repository in the public record carries a **health index**: a single integer between 1 and 100 that summarizes publicly visible engineering, maintenance, security, and governance practice. The index exists so that a library can be [compared with its alternatives](/compare) at a glance — but it is the *top* of a fully transparent hierarchy, never a black box.
◇
Signals, not warranties. A high index reflects publicly visible good practice. It is not a code audit and not a security guarantee — see how to read the results.
## The three-level hierarchy The index rolls up through three documented levels: 1. **Components** — individual observable facts (a license file exists, the latest release shipped 40 days ago, the bus factor is 3). Each component carries a fixed weight inside its metric. 2. **Metrics** — weighted sums of components, each an integer in 1–100. Examples: [development activity](/wiki/development-activity), [maintainer resilience](/wiki/maintainer-resilience), [security posture](/wiki/security-posture). 3. **Categories** — weighted means of their metrics, also in 1–100. The six weighted categories are [Vitality](/wiki/vitality), [Community & Adoption](/wiki/community-adoption), [Sustainability & Governance](/wiki/sustainability-governance), [Engineering Quality](/wiki/engineering-quality), [Security](/wiki/security), and — at a deliberately small weight — [AI Readiness](/wiki/ai-readiness). The **overall health index** starts as the weighted mean of the available categories: | Category | Weight in overall | | -------- | ----------------- | | [Sustainability & Governance](/wiki/sustainability-governance) | 23% | | [Vitality](/wiki/vitality) | 21% | | [Engineering Quality](/wiki/engineering-quality) | 19% | | [Community & Adoption](/wiki/community-adoption) | 17% | | [Security](/wiki/security) | 16% | | [AI Readiness](/wiki/ai-readiness) | 4% | A metric's effective weight in the overall index is *category weight × within-category weight*. Every report shows this figure on each metric card, and every published value maps to one of seven [rating bands](/wiki/scoring-bands). ## Calibration to the public record The weighted mean is then **calibrated onto the published index scale** through a fixed monotone curve anchored to the empirical distribution of the public record. Calibration is what gives the bands their percentile meaning — *Exceptional* is genuinely the record's top tier — and it lets the index use the whole 1–100 range instead of crowding half the record into twenty points of it. The curve saturates at the top: a raw weighted mean of 91 or above publishes as 100, which is also why a repository with no [AI Readiness](/wiki/ai-readiness) signals (4% of the raw weight) can still reach 100/100. The raw weighted mean stays visible in every report's `overall.inputs.weighted_overall_raw`, so the arithmetic remains fully auditable. Category and metric values are published uncalibrated — the curve describes, and is fitted to, the overall index only. ## Red flags cap the index Four policies stand outside the weighted mean. None of them rewards a clean result — a repository with no finding simply keeps its calibrated index — but a confirmed finding multiplies the published value and, in the gravest cases, holds it under a stated ceiling: | Policy | Applies to | Ceiling | | ------ | ---------- | ------- | | [Malicious dependencies](/wiki/malicious-dependencies) | security posture and the overall index | 19 — top of *Critical* | | [Abandonment](/wiki/abandonment) | the overall index | 34 when likely, 19 when declared | | [High-Risk Jurisdiction Exposure](/wiki/jurisdiction-exposure) | security posture and the overall index | 34 — top of *At Risk* | | [Growth authenticity](/wiki/growth-authenticity) | the stars and forks components of [popularity](/wiki/popularity) | none | Since methodology v1.13.0 the policies do not compound. The strictest one that fires governs alone and the others are reported without moving the value again: a multiplier states how serious a finding is, and a value multiplied twice is a number no policy chose and none can explain. Repositories whose evidence cannot answer a policy's question read *unverified* and are never penalized for the gap. ## Missing data is never a zero If a component's underlying data is unavailable — a registry publishes no download figures, the contributor list cannot be sampled — the component is **excluded and the remaining weights renormalized**. The same rule applies one level up: a metric with no data becomes `null` and its category redistributes the weight; a category with no scorable metric is dropped from the overall. This rule is central to fairness. A project is measured only on what can actually be observed, and absence of evidence is reported as absence — the metric's `note` field records every renormalization, so a reader always knows what was and was not measured. ## Reading a report - **Read the profile, not just the number.** A 74 built on balanced categories is a different proposition from a 74 masking a Security value of 25. The report's radar chart makes spike-and-crater profiles visible immediately. - **Check the bands.** Values map to seven standardized bands from `exceptional` to `critical`; band thresholds are part of the versioned methodology. - **Recompute anything.** Every metric echoes its inputs and per-component points in the report, so any published value can be verified by hand from the `data` section of the JSON report. - **Read candidates against each other.** An index is only meaningful next to the alternatives actually under consideration. The [comparison view](/compare) puts up to six records on one set of axes — category profile, growth trajectory, and every underlying figure — so the spread between them is visible rather than inferred. ## Versioning Formulas, weights, and band thresholds are versioned as a whole. Any change bumps the metrics version recorded in every report, and the full history is public — see [methodology versions](/wiki/methodology-versions). Parts of the methodology can be switched off per scan; the report then documents exactly what was disabled — see [scan configuration](/wiki/scan-configuration). Related: [rating bands](/wiki/scoring-bands) · [certification levels](/wiki/certification-levels) · [software classification](/wiki/software-classification) · [signals, not warranties](/wiki/signals-not-warranties) · [methodology versions](/wiki/methodology-versions) --- # Rating bands > The seven standardized rating bands — exceptional, excellent, good, moderate, weak, at risk, critical — and the letter grades used across every inspect.software health metric and category. Every value in an inspect.software report — components rolled into metrics, metrics rolled into categories, and the overall health index — lives on one standardized 1–100 scale, higher is better. To make those numbers readable at a glance, each value maps to one of **seven standardized bands**, used consistently across health, security, and quality measurements. Each band also carries a compact **letter grade** (C to AAA) for surfaces where a word does not fit.
Critical 1–19 At Risk 20–34 Weak 35–49 Moderate 50–64 Good 65–79 Excellent 80–92 Exceptional 93–100
The seven bands of the standardized scale. Thresholds are part of the versioned methodology.
## What each band means | Band | Grade | Range | Meaning | | ---- | ----- | ----- | ------- | | **Exceptional** | AAA | 93–100 | The record's top tier (≈ top 5%); essentially all checked criteria met | | **Excellent** | AA | 80–92 | Strong across the board; minor gaps | | **Good** | A | 65–79 | Healthy; gaps are limited and manageable | | **Moderate** | BBB | 50–64 | Acceptable with notable gaps; review recommended | | **Weak** | BB | 35–49 | Material weaknesses across several areas | | **At Risk** | B | 20–34 | Significant weaknesses; adoption warrants caution | | **Critical** | C | 1–19 | Severe problems — e.g. abandoned, single-maintainer, no hygiene | ## Calibrated to the public record Band floors for the overall health index are not arbitrary round numbers: the index is **calibrated against the empirical distribution of the public record** (47,516 inspected repositories at the calibration snapshot), so each band states where a repository stands within inspected open source. On the uncalibrated weighted mean, half the record crowded into a 20-point stretch of the scale and the top decile of open source sat in the high 70s — numbers that used the 1–100 range badly and made every band boundary misleading. After calibration the bands split the record into meaningful, comparably sized populations, and *Exceptional* means what a reader assumes it means: roughly the top 5% of inspected open source. The calibration curve is a fixed constant of the versioned methodology, not a live percentile — a repository's score moves only when its own evidence moves, never because other repositories were inspected. Recalibration against a newer snapshot is a methodology version bump like any other, recorded in every report. Certain [red-flag policies](/wiki/health-index) bound the index regardless of the weighted result: an unresolved High-Risk Jurisdiction exposure holds the index at the top of *At Risk* (34), and a confirmed malicious dependency or a declared-dead project holds it inside *Critical* (19). ## How bands should be read - **Bands are coarse on purpose.** The difference between 71 and 74 is noise; the difference between *good* and *at risk* is information. Procurement and review decisions should key on bands and on the category profile, not on single-point differences. The [comparison view](/compare) is built around this: it states the spread between the records on screen in index points, so a three-point gap can be recognized as one and set aside. - **Bands apply at every level.** A repository can sit in the *good* band overall while one category sits in *critical* — the per-category bands exist precisely so that strength in one area cannot silently mask risk in another. (Calibration applies to the overall index; category and metric values map to the same thresholds directly.) - **Thresholds are versioned.** Band boundaries are part of the methodology and only change with a version bump recorded in every report — see [methodology versions](/wiki/methodology-versions). ## Certification levels The three bands above *Moderate* carry the record's [certification levels](/wiki/certification-levels): **Certified** (Good, grade A), **Certified with Excellence** (Excellent, grade AA), and **Certified AAA** (Exceptional). A level is the band the published evidence supports, stated as a certification mark — see [how levels are earned and change](/wiki/certification-levels), and [certification & pricing](/pricing) for the paid on-demand path. ## Where the bands appear The bands drive the color coding across the whole record: catalogue cards, the report gauge, category headers, individual metric cards, and the [GitHub badge](/badges). A repository with no completed inspection yet shows a neutral *pending* state rather than a band. Related: [the health index](/wiki/health-index) explains how the underlying 1–100 values are computed; [signals, not warranties](/wiki/signals-not-warranties) explains what they do and do not claim. --- # Certification levels > The three inspect.software certification levels — Certified (A), Certified with Excellence (AA), and Certified AAA — how each maps to the calibrated health index, what a level asserts, and how levels change. A repository whose latest inspection places it in one of the top three [rating bands](/wiki/scoring-bands) holds an inspect.software **certification level**. The level is nothing more — and nothing less — than the band the published evidence supports, stated in the vocabulary of a certification mark: | Level | Grade | Band | Health index | | ----- | ----- | ---- | ------------ | | **Certified AAA** | AAA | Exceptional | 93–100 | | **Certified with Excellence** | AA | Excellent | 80–92 | | **Certified** | A | Good | 65–79 | Repositories below the *Good* band hold no certification level; their reports state a diagnosis — [Moderate, Weak, At Risk, or Critical](/wiki/scoring-bands) — not an award. The [calibration of the index](/wiki/health-index) gives each level percentile meaning across the public record: *Certified AAA* marks roughly the top 5% of inspected open source. ## What a level asserts A certification level asserts exactly what the report behind it asserts: measured, publicly visible engineering, maintenance, security, and governance practice under a [versioned methodology](/methodology) — nothing more. It is not a code audit, not a security guarantee, and not an endorsement — see [signals, not warranties](/wiki/signals-not-warranties). The full evidence for any level is one click away in the repository's public report. ## How a level is earned Every inspection — free public-interest coverage or [on-demand certification](/pricing) — runs the identical methodology, and the level follows mechanically from the resulting band. Payment buys an inspection; it cannot buy a level, and no commercial relationship can move a published result. ## How a level changes Levels track the latest published inspection. A re-inspection that moves the index across a band boundary moves the level with it, in either direction — a certification that could not be lost would assert nothing. Because band thresholds and the calibration curve are part of the versioned methodology, any change that could move levels is dated and documented in [methodology versions](/wiki/methodology-versions). ## Badges The embeddable [GitHub badge](/badges) is the certification mark. A certified repository's badge carries an embossed rosette bearing its letter grade — **A** for Certified, **AA** for Certified with Excellence, **AAA** for Certified AAA — beside the band word and the index. Repositories below *Good* show the same badge without a rosette: the seal marks certification, and nothing else may wear it. The badge follows the level automatically. A repository that reaches a higher level at its next inspection gets the higher seal without re-embedding anything, and one that falls below *Good* loses the rosette the same way — which is the point of a mark that is re-derived rather than issued once. Related: [rating bands](/wiki/scoring-bands) · [the health index](/wiki/health-index) · [signals, not warranties](/wiki/signals-not-warranties) · [methodology versions](/wiki/methodology-versions) --- # Signals, not warranties > What an inspect.software result does and does not claim — the honest boundary between visible practice signals and a formal audit or guarantee. Every report, badge, and certification published by inspect.software carries the same disclaimer: **results are signals, not warranties.** This page states precisely what that means, because trust in the record depends on never claiming more than the evidence supports. ## What a result claims A health index and its underlying metrics reflect **publicly visible practice**: commit and release history, contributor distribution, community files, CI and test configuration, registry publishing state, and security-relevant signals such as those measured by the [OpenSSF Scorecard](/wiki/security-posture). Every claim is: - **Observable** — derived from public data anyone can fetch. - **Reproducible** — reports record their metric inputs and methodology version. The formulas and production [scanner](https://github.com/inspect-software/scanner) are published; the [methodology](/methodology) documents the privacy exception. - **Versioned** — each report records the metrics version it was produced under, so a result can be re-derived later. ## What a result does not claim - **It is not a code audit.** No line-by-line review of correctness, performance, or vulnerability is performed. A project with exemplary process can still ship a defect. - **It is not a security guarantee.** [Security posture](/wiki/security-posture) measures visible security hygiene — it cannot rule out an undiscovered vulnerability or a compromised maintainer account. - **It is not a judgement about a person or country.** [High-Risk Jurisdiction Exposure](/wiki/jurisdiction-exposure) routes policy-defined public profile evidence into enhanced review. It does not determine nationality, citizenship, trustworthiness, sanctions status, repository permissions, or malicious intent. - **It is not an endorsement.** Inclusion in the public record means a repository was inspected, not that inspect.software recommends it. - **It is not a ranking.** Two records can be read side by side — the [comparison view](/compare) exists for exactly that — but the index weighs categories that different projects have different and legitimate reasons to answer differently. A comparison is a reading, not an order of merit. - **It is not a prediction.** A well-maintained project can be abandoned next month. Scores describe the observable present and recent past.
△
Certifications are signals, not warranties. They inform review and procurement; they do not replace expert judgement, legal review, or an independent security assessment where one is required.
## Why this boundary is kept strict The value of the record comes from its restraint. A registry that overstated its results would be gamed by marketing and discounted by engineers; one that states exactly what it measures can be relied on for exactly that. The same restraint appears in the formulas themselves: missing data is excluded and weights renormalized — never guessed, never counted against a project (see [the health index](/wiki/health-index)). ## Independence Published results are independent of payment. Free public-interest scans and paid certifications run the same versioned methodology, and no commercial relationship — sponsorship, certification fees, vendor alignment — can alter a published value. Where a scan intentionally narrows the methodology, the report says so explicitly (see [scan configuration](/wiki/scan-configuration)). Related: [the health index](/wiki/health-index) · [certification levels](/wiki/certification-levels) · [rating bands](/wiki/scoring-bands) · [methodology versions](/wiki/methodology-versions) --- # Methodology versions > The complete version history of the inspect.software metrics methodology — every formula, weight, and threshold change, dated and documented. 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](https://github.com/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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/software-classification) touches a score for the first time: the [security posture](/wiki/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](/wiki/software-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](/wiki/software-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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/ai-readiness) stops measuring only which files exist. [Agent context](/wiki/ai-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](/wiki/ai-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](/wiki/dependency-advisories). The resolved dependency set already collected for every report — direct dependencies plus the transitive closure — is now matched against the [OSV](https://osv.dev) 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](/wiki/security-posture) at 80% and the new metric at 20%. The [High-Risk Jurisdiction Policy](/wiki/jurisdiction-exposure) 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](/wiki/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](/wiki/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](/wiki/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](/wiki/package-maintenance) — publish recency, version history, deprecation state — and NuGet additionally feeds [ecosystem adoption](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/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](/wiki/ai-readiness)** category with four metrics: ([agent context](/wiki/ai-agent-context), [verify loop](/wiki/ai-verify-loop), [code legibility](/wiki/ai-code-legibility), [interfaces](/wiki/ai-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](/wiki/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](/wiki/supported-ecosystems). ### 0.6.0 — 2026-06-09 [Security posture](/wiki/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](/wiki/ecosystem-adoption) (registry downloads) in Community & Adoption and [package maintenance](/wiki/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](/wiki/release-discipline), [popularity](/wiki/popularity), [stewardship](/wiki/stewardship), and [documentation](/wiki/documentation). `activity` renamed [development activity](/wiki/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](/wiki/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](/wiki/health-index) · [rating bands](/wiki/scoring-bands) · [scan configuration](/wiki/scan-configuration) --- # Supported package ecosystems > The package ecosystems inspect.software reads — nine registries with published-package facts, plus dependency manifests across all of them. A repository is more than its GitHub presence: most reusable software ships through a **package registry**, and the registry holds adoption and maintenance evidence GitHub cannot show — real download volume, publish recency, deprecation state. inspect.software resolves the packages a repository publishes and folds registry data into two metrics: [ecosystem adoption](/wiki/ecosystem-adoption) and [package maintenance](/wiki/package-maintenance). ## Registries read today | Ecosystem | Registry | Adoption figure | | --------- | -------- | --------------- | | JavaScript / Node | npm | monthly downloads | | Python | PyPI | monthly downloads | | PHP | Packagist | monthly downloads | | Rust | crates.io | monthly downloads | | Ruby | RubyGems | lifetime total downloads | | Elixir / Erlang | Hex | download figures | | .NET | NuGet | lifetime total downloads | | Go | Go module proxy | no public download counter | | Java / JVM | Maven Central | no public package-download counter | All nine registries contribute published-package facts — latest version, publish recency, version history, deprecation state — to [package maintenance](/wiki/package-maintenance). Where a registry publishes no monthly download figure (RubyGems, NuGet), the adoption metric falls back to **lifetime total downloads** — whichever figure the registry actually provides, so no ecosystem is structurally disadvantaged. The Go module proxy and Maven Central publish no download statistics of any kind. For Go this leaves maintenance evidence as the only signal; for Maven Central the dependent-project count published by deps.dev supplies a comparable adoption measure. NuGet is incrementally discovered from its official catalog feed. Its public search metadata supplies lifetime total downloads, which are used for the catalogue threshold. Maven Central is incrementally discovered from the official Maven Central Indexer. Central publishes no package download counter, so eligibility instead relies on the deps.dev dependent-project count together with a declared GitHub source; packages meeting the dependents threshold are auto-queued like other ecosystems. ## Go module discovery The catalogue worker also reads the official public **Go Module Index** to find new stable releases. The index publishes a module path, version, and timestamp but no download/adoption counter. Automatic Go candidates therefore need a direct `github.com/owner/repo` module path and a stable release published within the last 730 days; they are ranked by release freshness, not by invented download figures. The normal low-priority catalogue queue and scan still verify the repository before it appears in the public record. ## Declared dependencies Independently of publishing, the inspection parses **dependency manifests** across ecosystems — npm, PyPI, Packagist, crates.io, Go, Maven, RubyGems, NuGet, and Hex — and records the declared **direct** dependency list in every report. Resolving those dependencies against registries and vulnerability databases (freshness, known CVEs) is on the published methodology roadmap. ## All dependencies Alongside the direct list, the inspection records the repository's **full resolved dependency set** — direct plus indirect (transitive) — from GitHub's dependency graph, which covers the transitive closure whenever the repository commits a lockfile. The report states direct and indirect counts separately and names the source of the resolved set. This collection is best-effort: when the dependency graph is unavailable, the report says so explicitly and every other part of the inspection proceeds unaffected. ## Repositories that publish no package Applications, infrastructure repositories, and documentation projects often publish nothing to any registry. For them the two registry-backed metrics are `null`: **excluded from their categories with weights renormalized**, never counted as zero. A non-publishing repository is measured purely on its other evidence — see [the health index](/wiki/health-index) for the missing-data rules. ## Package-to-repository matching A package only contributes to a repository's report when the registry entry verifiably points back to that repository. A package that claims a different source repository is listed in the report but flagged and left out of the computation — preventing adoption figures from being borrowed or spoofed. ## Multi-ecosystem, multi-language repositories One codebase can legitimately live in several ecosystems at once — a Rust core with Python bindings and an npm wrapper publishes to crates.io, PyPI, and npm from a single repository. Scoring already treats this soundly: download counts are summed across every verified package. Wherever the public record *lists* a repository's ecosystems — catalogue cards, filters, report chips — the order reflects **evidence strength**, not the alphabet: ecosystems with verified published packages come first, ranked by download volume; ecosystems seen only in dependency manifests follow. A package that points at a different source repository never leads the list. Languages follow the same discipline. The languages shown for a repository are those holding **at least 10% of its code by volume**, largest first — so CI scripts and generated markup do not masquerade as a project language, and a genuinely bilingual codebase is presented as one. Catalogue cards show up to three ecosystems and three languages per repository. Related: [ecosystem adoption](/wiki/ecosystem-adoption) · [package maintenance](/wiki/package-maintenance) · [software classification](/wiki/software-classification) · [methodology versions](/wiki/methodology-versions) --- # Software classification > How inspect.software determines what a repository builds — the multi-label reading of whether software is consumed as code, run as a program, or installed into a host. A repository is not simply "a project". It builds something, and what it builds decides which practices are reasonable to expect from it. A published library is expected **not** to commit a dependency lockfile — the versions it pins would be ignored by everyone installing it. The application beside it in the catalogue is expected to commit one, because the versions it pins are exactly what gets deployed. Judging both by one rule misreads one of them. Until metrics 2.3.0 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. ## Every reading the evidence supports The classification is **multi-label**. Software that is both a published library and a runnable tool is the ordinary case, not a contradiction to be resolved: ripgrep is a crate and a binary, esbuild is an npm package and an executable. A repository therefore keeps every reading its evidence supports. The vocabulary is a **two-level tree**. The top level answers the question that matters — how the software is consumed — and a repository can carry more than one branch: | Top level | What it makes reasonable to expect | | --- | --- | | **Library** — consumed as code | A stable interface, a changelog, versioning other software can depend on | | **Application** — run as a program | Pinned dependencies, deployment and configuration hygiene | | **Host extension** — installed into a host | The host supplies the trust model and the release cadence | | **Notebook** | None of the above — it is read and run by a person, imported by nothing, installed into nothing | Where both apply, both apply — a hybrid owes the obligations of every reading it carries, never the most lenient one. ## The subtypes Subtypes exist only where the finer answer changes what a reader should expect: an application's interface modality, or the host class an extension inherits its trust surface from. | Application | Host extension | | --- | --- | | Command-line tool | Plugin | | Terminal interface | Browser extension | | Desktop | Editor extension | | Mobile | Theme | | Web interface | | | Network service | | | Chat bot | | | MCP server | | **Library has no subtypes on purpose.** Earlier revisions distinguished framework, SDK, API client, middleware and driver, and those boundaries do not exist: axios is an API client *and* a library, flask is a framework *and* a library — a question with no right answer. What a library connects to is recorded elsewhere, as an integration fact, not here. **The answer may stop at the top level.** A Cargo binary target and Go's `cmd/` layout prove that the repository builds *an executable* — not whether it is a command-line tool or a server. Such a repository is classified simply **Application**, and gains the subtype only when evidence for it exists. A generic answer supported by evidence beats a specific one that would be a guess. ## How the answer is reached Evidence is ranked by how far it can be trusted, and **no single weak signal produces a label**. | Evidence | Examples | Weight | | --- | --- | --- | | **Declared in a build manifest** | an npm `bin` entry, a `console_scripts` entry point, `Exe`, Composer's `type`, Maven's ``, a Cargo `[lib]` target | Decisive | | **Declared by the registry** | a Packagist type, a NuGet package type, a crates.io category | Strong | | **Declared dependencies** | a web framework, a CLI argument parser, a chat-platform client | Moderate | | **File-tree structure** | `cmd/…/main.go`, `src-tauri/`, a Helm chart, a browser-extension manifest | Supporting | | **Repository topics and registry keywords** | `cli`, `wordpress-plugin`, `self-hosted` | Weak — self-assigned | | **The repository description** | "a CLI for…", "a library for…" | Weak — self-assigned | The first two are the strongest because they are not opinions: a maintainer who writes `Exe` is not describing the software, the build would not work otherwise. A topic is an opinion, and two of them agreeing is the minimum that carries anything at all. Evidence also runs the other way. A Cargo package with `publish = false`, a Composer `type` of `project`, a `.NET` tool, a Maven `war` — each **rules out** being something other software can depend on, whatever else the repository looks like. ## Where the answer is absent Three situations produce no classification, and all three are ordinary: - **The report predates the classification.** Every stored report was reclassified from the facts it already carried, but the manifest evidence is collected during a scan — so reports gathered earlier carry the weaker tiers only, and gain the full reading when the repository is next inspected. - **The evidence does not answer the question.** Many repositories publish no manifest, carry no informative topics, and describe themselves in prose that states nothing structural. - **The answer would be a guess.** Where signals are present but too weak to cross the threshold, nothing is claimed. In all three the report simply shows no classification. **Absence is never presented as a finding**, nothing is scored on it, and a repository without one is not marked, ranked, or penalized in any way. ## Repositories that build several things A monorepo holding a deployable service beside three published libraries is not one artifact, and rolling it up to a single answer would lose the fact that both readings are true. Each manifest is therefore classified on its own declarations, and the repository carries the union. One consequence is worth stating plainly: the single **primary** label shown for such a repository is the best-supported one, which in a large monorepo can be a published build tool rather than the product the project is known for. The primary label exists for display and for grouping comparable repositories — it is never the basis of a scoring decision. ## What it affects today One check, under a standing rule. Since metrics 2.5.0 the [security posture](/wiki/security-posture) fallback's **dependency-lockfile expectation** reads the classification: a published package whose manifest declares an executable counts as an application and keeps the expectation, where publication alone used to waive it. The standing rule is that **scoring reads manifest declarations only**. A label inferred from file structure, topics or the description is displayed and recorded, but never moves a score — only what a build manifest states outright (a `bin` entry, a console-script entry point, an `OutputType`) can. Everything else about the classification remains data: `metrics.classification` in every report, alongside the evidence that produced it. Further connections will be recorded in the [methodology versions](/wiki/methodology-versions) as they land. Related: [supported ecosystems](/wiki/supported-ecosystems) · [the health index](/wiki/health-index) · [security posture](/wiki/security-posture) · [scan configuration](/wiki/scan-configuration) · [signals, not warranties](/wiki/signals-not-warranties) --- # Scan configuration > How parts of the inspect.software methodology can be switched off per scan — and how every report documents exactly what was and was not measured. A scan can switch off any part of the methodology — a single **component**, a whole **metric**, or an entire **category**. This exists for legitimate narrowing (an internal policy that excludes popularity signals, a security-only certification) while keeping every published result honest: the configuration is **embedded in the report itself**, so it is always explicit what was and was not measured. ## How disabling works Disabling behaves exactly like missing data (see [the health index](/wiki/health-index)): the disabled item is excluded and the remaining weights are **renormalized**. The result stays on the 1–100 scale and is never dragged down by a zero for something deliberately not measured. Disabling every metric in a category — or the category itself — drops that category from the overall index, with its weight redistributed. ```jsonc // scan-config.json { "disabled_categories": ["security"], "disabled_metrics": ["popularity"], "disabled_components": { "documentation": ["Wiki", "Topics"] } } ``` Category and metric keys are the identifiers documented in each wiki article (`security`, `popularity`, `security_posture`, …); component names are the exact display names shown on metric cards (`Wiki`, `Stars`, `README`, …). Unknown keys are reported as warnings and ignored. ## What configuration cannot do Configuration selects *which* parts of the fixed methodology are active — it never changes a formula, a weight, or a band threshold. Those remain governed by the versioned methodology (see [methodology versions](/wiki/methodology-versions)). There is no mechanism, paid or otherwise, to adjust how an active metric is computed. ## How a configured scan reads - Every report carries its configuration at the top level, so the result is reproducible as published. - The report renders a **scan configuration** section listing everything that was disabled — or states that the full methodology ran. - Each affected metric's `note` records the renormalization, at the exact place a reader would look.
◇
Transparency rule. A narrowed scan is a valid measurement of a narrower question — and the report always says which question was asked.
Related: [the health index](/wiki/health-index) · [signals, not warranties](/wiki/signals-not-warranties) --- # Vitality > The Vitality category of the inspect.software health index — whether code is actively written and versioned releases actually ship. Weight: 21% of the overall index. **Vitality** answers the most basic question about an open-source project: *is it alive?* Code that stopped moving stops absorbing bug reports, security fixes, and compatibility work — and dependency on a dormant project is one of the most common, least visible risks in a software supply chain. The category carries **21% of the overall health index**, second only to [Sustainability & Governance](/wiki/sustainability-governance). ## Metrics in this category | Metric | Weight in category | Weight in overall | | ------ | ------------------ | ----------------- | | [Development activity](/wiki/development-activity) | 60% | 12.6% | | [Release discipline](/wiki/release-discipline) | 40% | 8.4% | [Development activity](/wiki/development-activity) measures whether code is being written: push recency, weekly commit cadence over the last year, and commit volume. [Release discipline](/wiki/release-discipline) measures whether that work actually reaches users as versioned releases — recency and cadence of published releases. Scorecard's `Maintained` and `Signed-Releases` checks are also shared evidence in these two metrics. This intentionally lets observable maintenance and release provenance influence both Vitality and Security, with different weights. The split is deliberate. A repository can show constant commits yet never cut a release users can adopt; another can ship tidy quarterly releases from a low-traffic default branch. Healthy projects do both, and the category rewards exactly that combination. ## Reading the category value - A **high Vitality with weak Governance** often marks a fast-moving project carried by one person — cross-check [maintainer resilience](/wiki/maintainer-resilience). - A **low Vitality on a mature library** is not automatically fatal: some foundational packages are genuinely finished and change rarely. The category reports observable motion; judgement about whether motion is *required* belongs to the reader. - When release data is unavailable, release discipline is `null` and the category renormalizes onto development activity alone — the report's notes say so (see [the health index](/wiki/health-index)). ## Improving Vitality - Keep the default branch moving: merge maintained work regularly rather than batching months of changes. - Publish versioned releases on a predictable cadence, even for small changes; recency and rhythm both count. - If a project is intentionally in maintenance mode, state it in the README — the record cannot read intent, but downstream users can. Related: [abandonment](/wiki/abandonment) · [rating bands](/wiki/scoring-bands) · [methodology versions](/wiki/methodology-versions) --- # Community & Adoption > The Community & Adoption category — users, downloads, attention, and a welcoming contributor setup. Weight: 17% of the inspect.software health index. **Community & Adoption** measures whether a project has users, attention, and a setup that welcomes contributors. Adoption is evidence: widely installed software is exercised against more environments, more edge cases, and more eyes than software nobody runs — and a project set up to receive contributors converts that attention into maintenance capacity. The category carries **17% of the overall health index**. ## Metrics in this category | Metric | Weight in category | Weight in overall | | ------ | ------------------ | ----------------- | | [Popularity](/wiki/popularity) | 40% | 6.8% | | [Community health](/wiki/community-health) | 35% | 5.95% | | [Ecosystem adoption](/wiki/ecosystem-adoption) | 25% | 4.25% | [Popularity](/wiki/popularity) reads GitHub attention — stars, forks, watchers — on a logarithmic scale. [Community health](/wiki/community-health) is a checklist of the files that make participation possible: README, license, contributing guide, code of conduct, issue and PR templates. [Ecosystem adoption](/wiki/ecosystem-adoption) goes past GitHub to the package registries, where real download volume beats stars as an adoption signal. ## Reading the category value - **Registry downloads outrank stars.** Stars measure attention; downloads measure use. A package with modest stars and a million monthly installs is more load-bearing than a viral repository nobody depends on. - **Repositories that publish no package** are not penalized: ecosystem adoption is `null` for them and the category renormalizes onto the other two metrics (see [supported ecosystems](/wiki/supported-ecosystems)). - **Small-but-healthy is visible.** The community-health checklist does not depend on scale, so a young project with complete contributor infrastructure reads well even before adoption arrives. ## Improving Community & Adoption - Complete the participation files: README, LICENSE, CONTRIBUTING, code of conduct, and issue/PR templates each carry documented weight. - Publish to the ecosystem's registry and keep the package's repository link accurate — adoption evidence only counts when the package verifiably points back to the repository. - Popularity follows use; the durable lever is making the project easy to adopt, document, and contribute to. Related: [growth authenticity](/wiki/growth-authenticity) · [rating bands](/wiki/scoring-bands) · [the health index](/wiki/health-index) --- # Sustainability & Governance > The heaviest category of the inspect.software health index (23%) — bus factor, responsiveness, organizational stewardship, and package upkeep. **Sustainability & Governance** asks whether a project will survive its people. Most open-source risk is not technical: it is a lone maintainer burning out, an issue tracker going quiet, a package abandoned on its registry while the repository still looks alive. This category measures the structures that make a project durable. It is the **heaviest category — 23% of the overall health index** — a deliberate statement that continuity risk outweighs any single technical signal. ## Metrics in this category | Metric | Weight in category | Weight in overall | | ------ | ------------------ | ----------------- | | [Maintainer resilience](/wiki/maintainer-resilience) | 30% | 6.9% | | [Responsiveness](/wiki/responsiveness) | 25% | 5.75% | | [Stewardship](/wiki/stewardship) | 25% | 5.75% | | [Package maintenance](/wiki/package-maintenance) | 20% | 4.6% | [Maintainer resilience](/wiki/maintainer-resilience) measures the bus factor and contributor concentration. [Responsiveness](/wiki/responsiveness) reads how issues and pull requests are actually handled. [Stewardship](/wiki/stewardship) examines who stands behind the repository — organization or personal account, verified domain, track record. [Package maintenance](/wiki/package-maintenance) checks that the published package is current and not deprecated, because registry upkeep is distinct from GitHub activity. ## Reading the category value - This category is where **organization backing** influences the index: an organization signals shared, accountable stewardship that can outlive any single person. The lift is deliberate, documented, and auditable — see [stewardship](/wiki/stewardship). - A strong [Vitality](/wiki/vitality) with weak Sustainability describes a productive project one departure away from stalling — the classic single-maintainer profile. - Metrics with no observable data (no issues yet, no published package) are excluded and renormalized, never counted as zero. ## Improving Sustainability & Governance - Grow the maintainer circle: review rights and merge rights for more than one person move the bus factor — the single heaviest component. - Keep the issue tracker decided: triage, close, or merge; unresolved volume reads as risk. - Move flagship projects from personal accounts to an organization, and verify the organization's domain. - Keep registry releases current and never leave a deprecated latest version standing without a successor. Related: [organization assessment](/wiki/organization-assessment) · [the health index](/wiki/health-index) --- # Engineering Quality > The Engineering Quality category — CI, tests, linting, and documentation practice. Weight: 19% of the inspect.software health index. **Engineering Quality** measures whether baseline engineering and documentation practices are in place: continuous integration, automated tests, lint and formatting discipline, and documentation a newcomer can actually learn from. These are the practices that make change safe — for human contributors and, increasingly, for [AI coding agents](/wiki/ai-readiness). The category carries **19% of the overall health index**. ## Metrics in this category | Metric | Weight in category | Weight in overall | | ------ | ------------------ | ----------------- | | [Engineering practices](/wiki/engineering-practices) | 60% | 11.4% | | [Documentation](/wiki/documentation) | 40% | 7.6% | [Engineering practices](/wiki/engineering-practices) is a weighted checklist of hygiene evidence: CI workflows, a test suite, linter configuration, pre-commit hooks, and an `.editorconfig`. [Documentation](/wiki/documentation) measures whether the project explains itself: README, a documentation directory or site, repository description, topics, and wiki. ## What this category deliberately measures The signals are **presence-based**: they confirm the infrastructure exists, not how good it is. That restraint is intentional — grading test *quality* or documentation *prose* from the outside would be guesswork presented as measurement. Presence signals are cheap to verify, hard to argue with, and already separate disciplined projects from undisciplined ones remarkably well. Deeper signals (coverage, CI pass rates) are on the [methodology roadmap](/methodology) and will arrive with a version bump. ## Reading the category value - A low value here rarely lies: missing CI and missing tests are visible facts, not judgement calls. - A high value means the *scaffolding* of quality is present. It does not certify that the code inside is good — see [signals, not warranties](/wiki/signals-not-warranties). - Documentation weighs 40%: a well-tested project that explains nothing to newcomers is measurably less adoptable, and the category reflects that. ## Improving Engineering Quality - Add CI that runs the test suite on every push and pull request — the two heaviest components in [engineering practices](/wiki/engineering-practices). - Commit linter and formatter configuration; add pre-commit hooks and an `.editorconfig` for full marks. - Maintain a real README, a `docs/` directory or documentation site, a repository description, and topics — each is an individually weighted component of [documentation](/wiki/documentation). Related: [AI readiness](/wiki/ai-readiness) · [the health index](/wiki/health-index) --- # Security > The Security category — visible OpenSSF Scorecard hygiene and known-vulnerable dependencies, under two red-flag policies. Weight: 16% of the inspect.software health index. **Security** measures visible security and supply-chain practice: dependency update automation, static analysis, signed releases, least-privilege CI tokens, known-vulnerable dependencies, security policy, and policy-defined high-risk jurisdiction exposure. It answers the question a dependency reviewer actually asks: *does this project practice security in the open?* The category carries **16% of the overall health index**. Two metrics combine as a weighted mean; two red-flag policies carry no additive weight and are applied to security posture before the category is assembled, so clean evidence can never lift weak hygiene: `Security = 0.8 × adjusted_security_posture + 0.2 × dependency_advisories` ## Metrics in this category | Metric | Weight in category | Weight in overall | | ------ | ------------------ | ----------------- | | [Security posture](/wiki/security-posture) | 80% | 12.8% | | [Dependency advisories](/wiki/dependency-advisories) | 20% | 3.2% | | [Malicious dependencies](/wiki/malicious-dependencies) | red flag | multiplier and ceiling on posture | | [High-Risk Jurisdiction Exposure](/wiki/jurisdiction-exposure) | red flag | multiplier and ceiling on posture | [Dependency advisories](/wiki/dependency-advisories) sits at 20% rather than higher because well-run projects genuinely do not ship known-vulnerable dependencies: the metric is near-constant across the record, and a signal that rarely varies must not outweigh the one that does. Where the dependency graph or the advisory lookup is unavailable, the metric is excluded and posture carries the category alone — a repository is never penalized for the gap. Only the strictest red flag that fires governs the result; since methodology v1.13.0 the policies no longer compound. A dependency reported as [malicious](/wiki/malicious-dependencies) is scored apart from ordinary advisories, because it is a confirmed compromise rather than an exposure to risk. The jurisdiction risk signal uses only high-confidence, self-published public profile evidence within the current Russia, Iran, and North Korea scope. Ambiguous evidence and missing locations never reduce the score. A confirmed match creates an enhanced-review priority; it is not an inference of nationality, citizenship, sanctions status, malicious intent, or individual trustworthiness. See the full [evidence, scoring, and enterprise interpretation guide](/wiki/jurisdiction-exposure). [Security posture](/wiki/security-posture) is backed by the **OpenSSF Scorecard**, the neutral, versioned security standard maintained by the Open Source Security Foundation. Each Scorecard check becomes a component, weighted by Scorecard's own risk level, and checks Scorecard cannot determine are excluded rather than counted as zero. When the Scorecard tooling is unavailable, the metric falls back to coarse file-tree signals and the report says so. Some Scorecard practices also substantiate another health dimension. Since methodology v1.0.0, seven selected checks provide small shared-evidence components in their relevant cards while retaining their full Security weight. The mappings and category-specific weights are published in [Security posture](/wiki/security-posture) and [methodology versions](/wiki/methodology-versions). ## Why tool-agnostic The methodology deliberately rewards the *practice*, not a vendor's config file: any accepted dependency-update tool (Dependabot, Renovate, …), any SAST (CodeQL, Semgrep, …). Projects on non-GitHub tooling are not structurally penalized — a fairness property inherited from Scorecard and preserved by excluding inconclusive checks (see [methodology versions](/wiki/methodology-versions), 0.6.0). ## Reading the category value
△
A security value is not a security guarantee. It reflects visible hygiene — it cannot rule out an undiscovered vulnerability, a malicious release, or a compromised account. See signals, not warranties.
- The full per-check breakdown — every Scorecard check, its score, and its reasoning — is rendered in each report, with links to Scorecard's own documentation per check. - A *critical* Security band on an otherwise healthy project is the classic case where the overall index must not be read alone: the per-category bands exist to surface exactly this. ## Improving Security - Publish a `SECURITY.md` with a disclosure channel. - Turn on automated dependency updates and a SAST workflow — any accepted tool counts. - Grant CI workflows least-privilege tokens, pin dependencies where appropriate, and sign releases. - Address known-vulnerable dependencies promptly; that check carries Scorecard's highest risk weighting. Related: [security posture](/wiki/security-posture) · [dependency advisories](/wiki/dependency-advisories) · [malicious dependencies](/wiki/malicious-dependencies) · [high-risk jurisdiction exposure](/wiki/jurisdiction-exposure) · [the health index](/wiki/health-index) --- # AI Readiness > The AI Readiness badge — how well a repository supports AI coding agents: agent context, verify loop, code legibility, machine-readable interfaces. **AI Readiness** measures how well a repository is equipped to be developed and maintained **with AI coding agents**: whether an agent arriving in the codebase finds guidance, can set up and verify its own changes, can read the code within model constraints, and can discover machine-readable interfaces. The category carries a **deliberately small weight of 4%** in the overall health index. Agent tooling has become a real maintenance signal — but the weight is sized, together with the index's [calibration curve](/wiki/health-index), so that its absence never gates the top of the scale: a solid pre-AI-era project with zero AI Readiness signals can still reach 100/100. A project that invests in agent tooling earns a visible distinction and a few index points; one that does not is never pushed out of any band's reach by that fact alone. ## Metrics in this category | Metric | Weight in category | | ------ | ------------------ | | [AI verify loop](/wiki/ai-verify-loop) | 40% | | [AI agent context](/wiki/ai-agent-context) | 30% | | [AI code legibility](/wiki/ai-code-legibility) | 15% | | [AI interfaces](/wiki/ai-interfaces) | 15% | The [verify loop](/wiki/ai-verify-loop) carries the heaviest weight because it is the crux of autonomous work: an agent that can bootstrap the project, run the tests, and check its own change is categorically more useful than one that cannot. [Agent context](/wiki/ai-agent-context) covers instruction files (`CLAUDE.md`, `AGENTS.md`, …) and machine-readable docs (`llms.txt`). [Code legibility](/wiki/ai-code-legibility) measures type-checkability and manageable file sizes. [Interfaces](/wiki/ai-interfaces) looks for API schemas, MCP servers, and runnable examples. ## Measurement honesty Signals are **presence- and size-based** heuristics from the file tree — no file contents are graded. They show that the infrastructure exists, not how good it is. Substance is weighted where it is cheap to detect: an instruction file below ~200 bytes registers as a stub and earns partial credit, a specific defense against gaming the badge. Metrics that do not apply produce `null`, never a penalty: a docs-only repository is not judged on code legibility, and a plain library with no API surface is not judged on interface schemas. ## Reading the badge - The badge answers a genuinely new procurement question — *can a team point agents at this codebase productively?* — that the classic health signals were never designed to capture. - At 4% of the raw weight — inside a calibration curve that saturates at raw 91 — AI Readiness can nudge the health index but can neither make nor break a rating: every band, including a 100/100, remains reachable with the category at zero. ## Improving AI Readiness - Add a substantive `CLAUDE.md` or `AGENTS.md` and an `llms.txt`. - Provide a one-command bootstrap (Makefile, justfile, …), automated tests, lint config, and type checking — the verify loop. - Keep source files below ~1,500 lines and adopt type checking. - Ship OpenAPI/GraphQL/protobuf schemas, an MCP server, or runnable examples where they fit the project's nature. Related: [engineering quality](/wiki/engineering-quality) · [methodology versions](/wiki/methodology-versions) --- # Development activity > How inspect.software measures development activity — push recency, weekly commit cadence, and commit volume. 12.6% of the overall health index. **Development activity** answers the first question anyone asks of an open-source dependency: *is code actively being written?* It reads the repository's push and commit history over the last year and rewards recency, rhythm, and volume — in that order of weight. - **Category:** [Vitality](/wiki/vitality) (60% within category) - **Weight in overall index:** 12.6% - **Metric key:** `development_activity` ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Push recency | 36 | same thresholds as v0.9.0, scaled to 36 points | | Commit cadence | 36 | share of the last 52 weeks with at least one commit, × the human-authorship factor | | Commit volume | 18 | log-scaled; roughly 100 commits per year earns full points, × the human-authorship factor | | OpenSSF Scorecard: Maintained | 10 | Scorecard's 0–10 result, scaled to 10 points | The value is the weighted sum, rounded and clamped to 1–100, and maps to a [rating band](/wiki/scoring-bands). Components without data are excluded and the remaining weights renormalized (see [the health index](/wiki/health-index)). `Maintained` is shared evidence, not a replacement for the scanner's own commit history: it also remains a full component of [Security posture](/wiki/security-posture). If Scorecard is unavailable or marks the check `n/a`, this component is excluded. ## The human-authorship factor Cadence and volume count commits, and a commit made by a robot counts exactly like a commit made by a maintainer. A repository whose dependency bot opens and merges an update every week therefore reads as one under continuous development. The newest 100 commits are checked for who authored them, and the two commit-counting components are multiplied by the human share of that window, reaching full marks at 40% and above. Two conditions must hold together. A low human share alone means only that a project automates heavily, which the best-maintained ones often do — a 59,000-star tool runs roughly three quarters of its commits through a dependency bot, and a package registry whose product *is* automated version bumps runs higher still. Both have human commits days old. So the discount also requires that no human has committed for more than 90 days: it is the silence, not the automation, that marks a project as sustained by its robots. The gap is measured inside the commit window itself — the newest commit against the newest human one — so a stored report always rescores to the same value rather than drifting as it ages. It applies no additive weight of its own — it can lower a value, never raise one — and it is skipped entirely when the commit sample is unavailable or smaller than 20 commits, so nothing is inferred from too little evidence. Only automation carrying a GitHub App identity is recognized; a bot operating under an ordinary user account still counts as a person. ## Why cadence outweighs volume A repository with a commit every week for a year is more dependable evidence of maintenance than the same number of commits landed in one burst. Cadence measures *sustained* attention; volume is log-scaled precisely so that commit count cannot be inflated into a high value — the difference between 100 and 1,000 yearly commits is small by design. ## Reading the result - **Recency dominates short-term change.** A project that pauses for six months loses the recency component first; the cadence component then decays as inactive weeks accumulate. - **Genuinely finished software exists.** A stable, feature-complete library can read low here while remaining safe to use — this is why development activity is one metric inside a weighted index, not a verdict. Cross-read with [release discipline](/wiki/release-discipline) and [responsiveness](/wiki/responsiveness). - **Monorepos and mirrors:** activity is read from the repository being inspected; work happening in a different repository does not count. ## Improving the value - Merge maintained work continuously instead of batching long-lived branches. - Keep at least a weekly heartbeat of real changes where the project genuinely needs maintenance — bug fixes and reviewed dependency updates count, and so do automated updates as long as human work continues alongside them. - Avoid empty activity: the log scale on volume makes synthetic commit inflation nearly worthless, and commits authored by automation are discounted once they crowd out human ones. Related: [release discipline](/wiki/release-discipline) · [Vitality](/wiki/vitality) --- # Release discipline > How inspect.software measures release discipline — whether versioned releases ship, how recently, and on what cadence. 8.4% of the overall health index. **Release discipline** measures whether a project ships versioned releases — the mechanism by which work in the repository actually reaches users. Downstream consumers pin versions, read changelogs, and upgrade on release boundaries; a project that never cuts releases forces every user onto unversioned snapshots. - **Category:** [Vitality](/wiki/vitality) (40% within category) - **Weight in overall index:** 8.4% - **Metric key:** `release_discipline` ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Ships releases | 27 | any published releases; same condition as v0.9.0, scaled to 27 points | | Release recency | 36 | same thresholds as v0.9.0, scaled to 36 points | | Release cadence | 27 | same thresholds as v0.9.0, scaled to 27 points | | OpenSSF Scorecard: Signed-Releases | 10 | Scorecard's 0–10 result, scaled to 10 points | When release data is unavailable the metric is `null` — excluded from [Vitality](/wiki/vitality) with weights renormalized, never counted as zero. The Scorecard component is likewise excluded when Scorecard is unavailable or reports `n/a`; it remains a full Security signal as well. ## Why releases are measured separately from commits Commit activity and shipping are different disciplines. A repository can show constant motion on its default branch while users wait a year for a release containing the fixes; the inverse — calm branches, punctual releases — also exists. Splitting [development activity](/wiki/development-activity) from release discipline makes both patterns visible instead of letting one hide the other. ## Reading the result - **Recency is the heaviest component.** A project with a strong release history that stopped releasing eighteen months ago reads materially lower than one that shipped last quarter. - **Cadence rewards rhythm, not frequency for its own sake.** A steady quarterly cycle earns most of the cadence points; the top tier simply reflects the short iteration loops common in actively developed libraries. - **GitHub releases are the source.** Projects that tag versions without publishing releases, or release only through a registry, may read lower here; registry publish recency is measured separately in [package maintenance](/wiki/package-maintenance). ## Improving the value - Publish releases through the repository's release mechanism, not only as tags. - Release on a predictable cadence — small, regular releases outscore rare large ones and serve users better for the same reason. - After any dormant period, a single fresh release immediately restores the recency component. Related: [development activity](/wiki/development-activity) · [package maintenance](/wiki/package-maintenance) --- # Popularity > How inspect.software measures repository popularity — stars, forks, and watchers on a logarithmic scale. 6.8% of the overall health index. **Popularity** measures how much adoption and attention a repository has gathered on GitHub itself: stars, forks, and watchers. Attention is weak evidence compared to real installation data — but it is universal (every repository has it, packaged or not) and correlates with the size of the community that would notice a problem. - **Category:** [Community & Adoption](/wiki/community-adoption) (40% within category) - **Weight in overall index:** 6.8% - **Metric key:** `popularity` ## How the value is computed All three components are **logarithmically scaled** — each order of magnitude matters roughly equally, so the difference between 50 and 500 stars counts about as much as between 500 and 5,000. | Component | Weight | Saturates around | | --------- | ------ | ---------------- | | Stars | 60 | ~5,000 | | Forks | 25 | ~1,000 | | Watchers | 15 | ~500 | A count of 1 or 2 earns no points — a single star or fork is noise rather than adoption — so each component only begins scoring from 3 upward. ## Stars and forks can be bought They are the only inputs in the model with no issuer, and they are sold openly in bulk. Where a repository's collected day-by-day history shows growth that organic attention does not produce, the [Inorganic Growth Policy](/wiki/growth-authenticity) discounts the stars and forks components — by 40% for one confirmed burst, 70% for more. Watchers are untouched, a clean history never raises the value, and a repository whose history cannot answer the question is not penalized at all. ## Why the log scale A linear scale would make the metric a proxy for fame, dominated by a handful of mega-projects and useless for comparing everything else. The log scale compresses the top and stretches the middle, where most real dependency decisions are made. Saturation points mean that beyond ~5,000 stars, additional attention adds nothing — the metric has answered its question. ## Reading the result - **Popularity is the weakest form of adoption evidence.** Stars accumulate and never decay, so old attention lingers. Where the project publishes a package, [ecosystem adoption](/wiki/ecosystem-adoption) — real download volume — is the stronger signal, and the category weights reflect that hierarchy. - **Forks carry independent information**: they indicate people working with the code, not just bookmarking it. - **Low popularity is not a defect.** Young or niche projects read low here by nature; the metric is 6.8% of the overall precisely so that quality and governance evidence can outweigh fame. ## Improving the value There is no direct lever, and that is by design — attention follows usefulness. The durable path is the same as for [Community & Adoption](/wiki/community-adoption) generally: make the project easy to discover, adopt, and contribute to, and publish it where its users already are. Related: [ecosystem adoption](/wiki/ecosystem-adoption) · [community health](/wiki/community-health) --- # Community health > How inspect.software measures community health — README, license, contributing guide, code of conduct, and issue/PR templates. 5.95% of the overall index. **Community health** measures whether a repository is set up to receive users and contributors: the standard files that tell a newcomer what the project is, on what terms it may be used, and how to participate. These files are the difference between a codebase and a community. - **Category:** [Community & Adoption](/wiki/community-adoption) (35% within category) - **Weight in overall index:** 5.95% - **Metric key:** `community_health` ## How the value is computed A weighted checklist of the standard files, each present or absent (the license row can also earn partial credit — see below): | Component | Weight | | --------- | ------ | | README | 22.5 | | License | 22.5 | | CONTRIBUTING guide | 18 | | Code of conduct | 13.5 | | Issue template | 7.2 | | PR template | 6.3 | ## How the license is detected License presence is checked once, from three sources considered together: the repository's own license metadata, GitHub's community profile, and [OpenSSF Scorecard](https://github.com/ossf/scorecard)'s published, tool-neutral `License` check. A file that **any** source sees counts as present — the sources disagree on roughly 1% of repositories, and a single unavailable endpoint must not report a license as missing. The result is one of three states: | State | Meaning | Credit | | ----- | ------- | ------ | | Standard | A recognized license, identified by SPDX code | 22.5 | | Custom | A license file is present, but its text is not a recognized license | 16.9 | | None | No source found a license file | 0 | A **custom license** is a real license and earns most of the weight. It does not earn all of it: a license automated tooling cannot identify is a genuine obstacle to adoption, because policy tooling, corporate review and package registries all key off recognized identifiers, and a reader cannot establish what they are permitted to do without reading the text themselves. GitHub reports this case as `NOASSERTION` — a license it found but could not classify, which is not the same as no license at all. The Scorecard result remains a component of the [security](/wiki/security-posture) metric; here it is one input among three, shown simply as `License`. ## Why these files carry weight - **README and license are load-bearing.** A repository without a README is unadoptable; a repository without a license is legally unusable in most organizations — no downstream legal team will approve a dependency whose terms are undefined. Together they carry half the metric. - **CONTRIBUTING and a code of conduct** convert drive-by interest into sustained participation, which feeds directly into the continuity measured by [maintainer resilience](/wiki/maintainer-resilience). - **Templates** raise the signal quality of incoming issues and pull requests, reducing maintainer triage load — a small but real factor in the [responsiveness](/wiki/responsiveness) a project can sustain. ## Reading the result - The checklist is scale-independent: a week-old project can reach 100 before its first star, and a famous project missing a license reads visibly incomplete. That is intended — this metric measures preparation, not traction. - Presence is what is verified, not prose quality — see the measurement honesty note in [signals, not warranties](/wiki/signals-not-warranties). ## Improving the value Every component is directly actionable within an hour: - Write a README covering what the project does, installation, and a minimal example. - Add a `LICENSE` file with a recognized SPDX license. - Add `CONTRIBUTING.md`, a `CODE_OF_CONDUCT.md`, and issue/PR templates under `.github/`. This is typically the fastest metric to move in the entire methodology. Related: [Community & Adoption](/wiki/community-adoption) · [documentation](/wiki/documentation) --- # Ecosystem adoption > How inspect.software measures real package adoption — registry downloads and dependents across npm, PyPI, Packagist, and more. 4.25% of the overall index. **Ecosystem adoption** measures how widely a package is actually installed, using the package registries themselves — npm, PyPI, Packagist, crates.io, RubyGems, Hex, and the other [supported ecosystems](/wiki/supported-ecosystems). Real download volume beats GitHub stars as adoption evidence: downloads measure use, stars measure attention. - **Category:** [Community & Adoption](/wiki/community-adoption) (25% within category) - **Weight in overall index:** 4.25% - **Metric key:** `ecosystem_adoption` - **Applies to:** repositories that publish at least one package; otherwise `null` ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Monthly downloads | 80 | summed across the repository's packages, log-scaled — ~1,000,000/month saturates | | Total downloads | 80 | fallback when a registry publishes no monthly figure (e.g. RubyGems); log-scaled, ~50,000,000 all-time saturates | | Registry dependents | 20 | log-scaled; reported by some ecosystems only, excluded elsewhere | The download component uses the monthly figure where available and the lifetime total otherwise — whichever the registry provides, so no ecosystem is structurally disadvantaged. ## Fairness rules - **Non-publishing repositories are not penalized.** Applications and infrastructure projects that ship nothing to a registry get `null` here, and [Community & Adoption](/wiki/community-adoption) renormalizes onto its other metrics. - **Packages must point back.** A registry package only counts when its metadata verifiably references the inspected repository; mismatched packages are listed in the report but excluded from the computation. - **Log scaling** keeps the metric meaningful across the whole range — a package going from 1,000 to 10,000 monthly downloads moves as much as one going from 100,000 to 1,000,000. ## Reading the result - Within its category, this is the strongest adoption evidence available — stronger than [popularity](/wiki/popularity), which is why a heavily downloaded but modestly starred package can outread a famous one. - Download figures vary by registry in meaning (mirrors, CI traffic); the log scale absorbs most of that noise, and the exact inputs are echoed in every report for inspection. ## Improving the value - Publish the package to its ecosystem's registry and keep the repository link in the package metadata accurate. - Beyond that, downloads follow genuine use — the honest lever is the project's usefulness and discoverability, not the metric. Related: [package maintenance](/wiki/package-maintenance) · [supported ecosystems](/wiki/supported-ecosystems) --- # Maintainer resilience > How inspect.software measures bus factor, contributor concentration, and breadth — whether a project can survive losing its top maintainer. 6.9% of the index. **Maintainer resilience** asks the uncomfortable question: *can this project survive losing its most important person?* The pattern it measures — a single maintainer carrying essentially all of the work — is the most common structural failure mode in open source, and it is invisible in commit counts and stars. - **Category:** [Sustainability & Governance](/wiki/sustainability-governance) (30% within category) - **Weight in overall index:** 6.9% - **Metric key:** `maintainer_resilience` - **`null`** when the contributor list is unavailable, or when every contributor turned out to be an automation account ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Bus factor | 54 | v0.9.0 bus-factor curve, scaled to 54 points | | Commit distribution | 22.5 | `(1 − top contributor's share of human commits) × 22.5` | | Contributor breadth | 13.5 | `min(13.5, human contributors sampled × 1.35)` | | OpenSSF Scorecard: Contributors | 10 | Scorecard's 0–10 result, scaled to 10 points | The **bus factor** is the smallest number of contributors who together account for the majority of the work — the number of people whose departure would stall the project. Every figure here counts **people only**. Automation accounts are removed before the bus factor, the distribution, or the breadth is derived, because a release robot cannot inherit a project. The removal is not cosmetic: in several widely used repositories, dependency bots rank second and third among all contributors by commit count, and counting them made the maintainer base look broader and less concentrated than it is. Only automation carrying a GitHub App identity is recognized, so a bot operating under an ordinary user account is still counted as a person. The Scorecard component measures contributing organizations/companies, a useful complementary signal of institutional resilience. It also remains part of Security and is excluded here if unavailable or `n/a`. ## Why the curve is shaped this way The jump from a bus factor of 1 to 2 (10 → 28 points) is the largest single step in the methodology, because it is the largest real-world risk reduction: the difference between a project with a single point of failure and one without. Returns diminish beyond 4–5 — once several people genuinely share the work, adding more changes little. Commit distribution complements the bus factor: a project can technically have five contributors while one person authors 95% of the changes. The distribution component makes that concentration visible. ## Reading the result - A **low value on a high-[Vitality](/wiki/vitality) project** is the classic solo-maintainer profile: productive today, fragile tomorrow. - Cross-read with [stewardship](/wiki/stewardship) — organization backing mitigates (but does not remove) the risk this metric measures. - Contributor data is sampled from the repository's public history. Automation accounts are reported — the count removed is echoed in the report alongside the other inputs — but they are excluded from every figure scored here. - For the displayed top ten contributors, authenticated scans also collect self-published GitHub profile name, location, company, and public organization memberships in one batched request. This enrichment is not used in the score and is withheld from public API and HTML reports; it supports internal identity-resolution research without changing the bus-factor calculation. ## Improving the value - Grant review and merge rights to at least one more person — moving the bus factor from 1 to 2 is the single biggest gain available. - Actively distribute work: route reviews and releases across maintainers rather than through one person. - Convert recurring contributors into maintainers; breadth counts, and the pipeline starts with [community health](/wiki/community-health). Related: [stewardship](/wiki/stewardship) · [Sustainability & Governance](/wiki/sustainability-governance) --- # Responsiveness > How inspect.software measures responsiveness — issue resolution, lifetime pull-request acceptance, and how a project treats first-time contributors. 5.75% of the overall index. **Responsiveness** measures whether the work arriving at a project — bug reports, feature requests, contributed patches — actually gets handled. An issue tracker where reports accumulate unanswered, or a queue of pull requests closed without engagement, predicts the experience every future user and contributor will have. - **Category:** [Sustainability & Governance](/wiki/sustainability-governance) (25% within category) - **Weight in overall index:** 5.75% - **Metric key:** `responsiveness` - **`null`** when the repository has no issues and no decided pull requests ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Issue resolution | 42 | ratio of closed to total issues × 42 | | PR acceptance | 30 | `merged / (merged + closed unmerged) × 30` | | Newcomer PR acceptance | 13 | merged share of the pull requests decided in the last 30 days whose author had no previously merged pull request here | | OpenSSF Scorecard: Code-Review | 15 | Scorecard's 0–10 result, scaled to 15 points | The first two counts are lifetime totals. Newcomer PR acceptance reads a 30-day window instead; it excludes bot-authored pull requests, and it is excluded itself — with the remaining weights renormalized — when no first-time contributor's pull request was decided in that window. It appears only on reports produced under methodology 2.1.0 or later (see [methodology versions](/wiki/methodology-versions)). Latency percentiles — *how fast* issues and pull requests are decided — remain on the published roadmap. `Code-Review` is complementary shared evidence: it checks approvals on changesets, whereas PR acceptance measures merge outcomes. It remains a Security component and is excluded here if Scorecard is unavailable or `n/a`. ## What the ratios mean - **Issue resolution** reads the fraction of filed issues that reached a decision. Projects that triage honestly — fixing, answering, or closing with a reason — read well; projects where issues silently pile up read low. - **PR acceptance** reads what happens to contributed code among pull requests that reached a decision. A very low merge share often marks a project that receives contributions but cannot or will not absorb them. - **Newcomer PR acceptance** reads the same outcome for authors with no previously merged pull request in the repository. A project can be quick and generous with its regulars and merge nothing arriving from outside that circle; the two rates come apart often enough that only this one describes what a first-time contributor should expect. ## Reading the result - **Closing is deciding.** The metric does not require that every issue be fixed — a maintained "wontfix" is a decision. What it penalizes is unbounded accumulation. - **Lifetime ratios move slowly.** A project that recently improved its triage will see this metric recover gradually; the roadmap's time-windowed latency measures will make recent behavior more visible. - **A window with no newcomers is not a low score.** Nobody knocking is not the same fact as nobody being let in, and only the second is the project's own doing, so the component is excluded rather than scored as zero. The denominator is newcomers' *decided* pull requests, not their share of all merges: a mature project where regulars land most of the work is not marked down for having regulars. - Repositories with issues disabled and no PR history are `null` here, with weights renormalized — see [the health index](/wiki/health-index). ## Improving the value - Triage on a schedule: label, answer, and close stale reports with a stated reason rather than leaving them open indefinitely. - Decide pull requests both ways — merging good ones and explicitly declining unsuitable ones both count as stewardship. - Templates from [community health](/wiki/community-health) raise incoming quality and make sustained triage cheaper. Related: [maintainer resilience](/wiki/maintainer-resilience) · [Sustainability & Governance](/wiki/sustainability-governance) --- # Stewardship > How inspect.software measures who stands behind a repository — organization vs. personal ownership, verified domain, reach, and track record. 5.75% of the index. **Stewardship** examines who stands behind a repository. Ownership is a governance fact with long-term consequences: an organization signals shared, accountable stewardship that can outlive any single person, while a personal-account project — however excellent — carries the continuity risk of its one owner. This is the one place in the methodology where **organization backing deliberately influences the health index**, and the lift is documented to the point. - **Category:** [Sustainability & Governance](/wiki/sustainability-governance) (25% within category) - **Weight in overall index:** 5.75% - **Metric key:** `stewardship` - **`null`** when the owner profile is unavailable ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Ownership backing | 30 | organization → 30 pts, personal (user) account → 10 | | Verified domain | 20 | organization with a verified domain → 20, without → 0; **excluded for personal accounts** | | Owner reach | 25 | followers of the owning account, log-scaled — ~3,000 saturates | | Track record | 25 | account age (≥6 years → 12 pts) + public repositories (log-scaled → 13 pts) | For personal accounts the verified-domain component is excluded and weights renormalize — a person is not penalized for a check that cannot apply to them. The remaining gap is the ownership-backing margin itself. ## The organization lift, made explicit A repository moved from a personal account to an organization gains up to 20 points of backing plus access to the verified-domain component. Worked through the weights, that is the difference between a *moderate* and a *good* governance profile for many projects — a deliberate, transparent preference for structures that survive their founders. The full arithmetic is in the [methodology](/methodology). ## Reading the result - **Verified domains bind identity.** An organization that verified its domain has proven control of a real-world identity — meaningful supply-chain evidence, not decoration. - **Reach and track record are secondary.** They add texture (an established account with history versus a fresh one) but cannot substitute for the structural components. - The owner profile also records GitHub's self-published location alongside name, company, website, and avatar. Location is evidence for identity resolution only and does not affect the stewardship score. - Stewardship measures the *owner*, not the code — read alongside [maintainer resilience](/wiki/maintainer-resilience), which measures the people doing the work. ## Improving the value - Move flagship projects from personal accounts into a GitHub organization. - Verify the organization's domain in GitHub settings. - Maintain a complete organization profile — it also feeds the [organization assessment](/wiki/organization-assessment) when the org itself is inspected. Related: [organization assessment](/wiki/organization-assessment) · [Sustainability & Governance](/wiki/sustainability-governance) --- # Package maintenance > How inspect.software measures registry upkeep — publish recency, version history, and deprecation state of published packages. 4.6% of the overall index. **Package maintenance** checks that a project's published package is current, resolvable, and not deprecated on its registry. Registry upkeep is distinct from GitHub activity: a library can go stale — or be explicitly marked abandoned — on npm or Packagist while its repository still sees commits, and users install the package, not the repository. - **Category:** [Sustainability & Governance](/wiki/sustainability-governance) (20% within category) - **Weight in overall index:** 4.6% - **Metric key:** `package_maintenance` - **Applies to:** repositories that publish at least one package; otherwise `null` ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Published & resolvable | 25 | at least one of the repository's packages resolves on its registry | | Publish recency | 35 | latest publish ≤180 days → 35 pts, ≤365 → 26, ≤730 → 14, older → 4 | | Version history | 20 | ≥5 published versions → 20, ≥2 → 12, otherwise 4 | | Not deprecated | 20 | deprecated (npm), abandoned (Packagist), or yanked latest → 0; otherwise 20 | ## Why each component matters - **Resolvable** is the baseline: the package installs from the registry a user would actually reach for. - **Publish recency** catches the silent failure where fixes land in the repository but never ship — the registry copy quietly ages while the repository looks alive. - **Version history** distinguishes a maintained release line from a one-shot publish. - **Deprecation** is the registry's own strongest signal, set by the maintainers themselves; a deprecated latest version zeroes the component outright. ## Reading the result - Cross-read with [release discipline](/wiki/release-discipline): GitHub releases and registry publishes usually move together, and divergence between them is itself informative. - Only packages whose registry metadata verifiably points to the inspected repository are counted — see [supported ecosystems](/wiki/supported-ecosystems) for the matching rule. - Non-publishing repositories are `null` here and their category renormalizes — never a penalty for being an application. ## Improving the value - Publish releases to the registry as part of the release process, not as an afterthought. - Keep at least a yearly publish cadence for maintained packages — even a patch release restores recency. - Never leave a deprecated or yanked version as the latest; publish a successor or clear the flag. Related: [ecosystem adoption](/wiki/ecosystem-adoption) · [release discipline](/wiki/release-discipline) --- # Engineering practices > How inspect.software measures baseline engineering hygiene — CI, tests, linting, pre-commit hooks, and editorconfig. 11.4% of the overall health index. **Engineering practices** measures baseline engineering hygiene: the infrastructure that makes change safe. Continuous integration and an automated test suite are the two practices with the strongest documented relationship to sustainable quality, and together they carry most of this metric. - **Category:** [Engineering Quality](/wiki/engineering-quality) (60% within category) - **Weight in overall index:** 11.4% - **Metric key:** `engineering_practices` ## How the value is computed A weighted checklist of visible practice evidence: | Component | Weight | Evidence | | --------- | ------ | -------- | | CI workflows | 24 | continuous-integration configuration present | | Tests present | 24 | a test suite exists in the repository | | Linter config | 16 | lint/format configuration committed | | Pre-commit hooks | 9.6 | pre-commit configuration present | | .editorconfig | 6.4 | editor conventions committed | | OpenSSF Scorecard: CI-Tests | 20 | Scorecard's 0–10 result, scaled to 20 points | ## Why these five - **CI plus tests** form the verification loop: every change is exercised against the suite before it lands. Their combined 60 weight reflects that no other visible practice substitutes for it. - **Linting** enforces consistency mechanically, keeping review attention on substance. - **Pre-commit hooks and `.editorconfig`** are smaller signals of a project that has invested in contributor ergonomics — changes arrive pre-checked and consistently formatted regardless of who wrote them. The same evidence feeds the [AI verify loop](/wiki/ai-verify-loop): the infrastructure that lets a human contributor verify a change is exactly what lets an AI coding agent verify one. Scorecard's `CI-Tests` is shared evidence: unlike the local presence checks, it asks whether merged pull requests were checked by CI. It also remains a full Security component. `n/a` or unavailable Scorecard evidence is excluded. ## Reading the result - These are **presence signals** — they confirm the scaffolding exists, not how rigorous it is. Coverage percentages and CI pass rates are on the [methodology roadmap](/methodology). - A missing test suite is one of the most reliable negative signals in the entire methodology; very few disciplined projects lack one. ## Improving the value - Add a CI workflow that runs the test suite on every push and pull request — the two heaviest components, often achievable in a single afternoon. - Commit the linter and formatter configuration the project already uses locally. - Add a pre-commit configuration and an `.editorconfig` for the remaining points. Related: [documentation](/wiki/documentation) · [AI verify loop](/wiki/ai-verify-loop) --- # Documentation > How inspect.software measures documentation — README, docs directory, documentation site, description, topics, and wiki. 7.6% of the overall health index. **Documentation** measures whether a newcomer can learn what a project is and how to use it. Undocumented software externalizes its cost onto every user; documented software scales its maintainers' knowledge. For a dependency decision, documentation is also evidence of care — projects that explain themselves tend to be projects that maintain themselves. - **Category:** [Engineering Quality](/wiki/engineering-quality) (40% within category) - **Weight in overall index:** 7.6% - **Metric key:** `documentation` ## How the value is computed A weighted checklist: | Component | Weight | Evidence | | --------- | ------ | -------- | | README | 30 | a README file at the repository root | | Documentation directory | 25 | a `docs/` (or equivalent) directory | | Documentation / homepage site | 15 | the GitHub homepage field, or a documentation/homepage URL declared through the package registry | | Repository description | 10 | the one-line description set on GitHub | | Topics | 10 | GitHub topics assigned | | Wiki | 10 | repository wiki enabled | ## The layers, from essential to discoverable - **README (30)** is the front door; nothing else is read if it is missing. - **A docs directory (25)** marks documentation that grew past one file — usually guides, reference, or architecture notes. - **A documentation site (15)** signals sustained investment: rendered, navigable docs for users rather than repository visitors. The evidence is the GitHub homepage field or, failing that, a documentation or homepage URL the project declares through its package registry — the `documentation` key in `Cargo.toml` mirrored by crates.io (docs.rs), PyPI's `project_urls`, RubyGems' `documentation_uri`, Hex's docs links, or the homepage in `package.json` and its equivalents. A homepage that merely restates the repository link is not counted. - **Description, topics, and wiki (30 combined)** are discoverability metadata: they determine whether the project can be found and classified at all — by people, package indexes, and increasingly by AI tooling. ## Reading the result - Presence is what is measured, not prose quality — the honest limit of external inspection (see [signals, not warranties](/wiki/signals-not-warranties)). - Cross-read with [community health](/wiki/community-health): README overlaps as the shared foundation, but the two metrics answer different questions — *can it be learned* versus *can it be participated in*. ## Improving the value - Keep a substantive README: purpose, installation, minimal example, links onward. - Move growing documentation into `docs/` and publish it as a site (GitHub Pages or any generator) — the two steps together carry 40 points. - Set the repository description and topics; enable the wiki where it fits the project's workflow. Related: [community health](/wiki/community-health) · [Engineering Quality](/wiki/engineering-quality) --- # Security posture > How inspect.software measures security posture with the OpenSSF Scorecard — risk-weighted, tool-agnostic checks with a documented fallback. 16% of the index. **Security posture** measures visible security hygiene, backed by the **[OpenSSF Scorecard](https://github.com/ossf/scorecard)** — the neutral, versioned, tool-agnostic security standard maintained by the Open Source Security Foundation. It supplies the base value of the [Security](/wiki/security) category, which carries **16% of the overall index**; [high-risk jurisdiction exposure](/wiki/jurisdiction-exposure) can only reduce that base through the published policy multiplier and rating ceiling. - **Category:** [Security](/wiki/security) (base value before multiplier) - **Weight in overall index:** 16% before the jurisdiction policy adjustment - **Metric key:** `security_posture` ## How the value is computed Each Scorecard check becomes a component, **weighted by Scorecard's own risk level**: | Scorecard risk level | Component weight | | -------------------- | ---------------- | | Critical | 10 | | High | 7.5 | | Medium | 5 | | Low | 2.5 | The rolled-up 1–100 value therefore tracks Scorecard's 0–10 aggregate (`value ≈ aggregate × 10`). Checks Scorecard reports as **inconclusive** — for example Branch-Protection without an admin token — are **excluded and renormalized**, never counted as zero. That rule is what keeps well-run projects on non-GitHub tooling from reading near zero, and it is documented in [methodology versions](/wiki/methodology-versions) (0.6.0). Every report renders the full per-check breakdown — score, reasoning, and a link to Scorecard's documentation for each check. ## Shared evidence Security keeps the complete risk-weighted Scorecard result. Seven checks also substantiate other health dimensions. Six provide small, separately weighted `OpenSSF Scorecard: …` components there: `Maintained`, `Signed-Releases`, `Contributors`, `Code-Review`, `CI-Tests`, and `Pinned-Dependencies`. The seventh, `License`, is the sole license signal in [community health](/wiki/community-health) — shown there generically as `License`, with a fallback to GitHub's community profile when no Scorecard is available. This is an intentional cross-category influence, not reuse of Scorecard's security risk weights. Inconclusive (`n/a`) checks remain excluded everywhere. ## What the checks reward The practice, never a vendor's config file: - **Dependency update automation** — Dependabot, Renovate, or any accepted tool. - **Static analysis (SAST)** — CodeQL, Semgrep, or equivalent. - **No known-vulnerable dependencies** — the highest-risk check. - **Least-privilege workflow tokens**, **pinned dependencies**, **signed releases**, a **security policy**, and more. ## The fallback path Running Scorecard requires its CLI; when unavailable, the metric falls back to coarse file-tree signals, and the report marks the source explicitly (`inputs.source == "file_signals"`): | Fallback component | Weight | Note | | ------------------ | ------ | ---- | | Security policy (SECURITY.md) | 30 | | | Dependabot configuration | 25 | | | Dependency lockfiles | 25 | applications only — libraries conventionally publish without committing a lockfile, so the check is excluded for them. A published package whose manifest declares an executable counts as an application and keeps the expectation (see the [software classification](/wiki/software-classification) and metrics 2.5.0) | | CodeQL workflow | 20 | | ## Reading the result
△
Not a vulnerability scan of the code. A strong value means strong visible practice; it cannot rule out an undiscovered flaw or a compromised account. See signals, not warranties.
- Compare the aggregate with the per-check table: a middling value with one failed critical check is a different situation from uniform mediocrity. - `n/a` rows are inconclusive checks — excluded, not failed. ## Improving the value - Publish `SECURITY.md`, enable automated dependency updates, and add a SAST workflow. - Resolve known-vulnerable dependencies first — highest risk weight, highest real-world payoff. - Set explicit least-privilege permissions on CI workflows and pin third-party actions. Related: [Security](/wiki/security) · [high-risk jurisdiction exposure](/wiki/jurisdiction-exposure) · [methodology versions](/wiki/methodology-versions) --- # Dependency advisories > How inspect.software matches a repository's resolved dependencies against the OSV advisory database — severity, fix versions, coverage, and the limits of the signal. 20% of the Security category. **Dependency advisories** asks a narrow, checkable question: do the dependency versions this repository actually resolves to appear in any published security advisory? It carries **20% of the [Security](/wiki/security) category**, alongside [security posture](/wiki/security-posture) at 80%. The weight is deliberately modest. Calibration against sixteen widely used packages found fifteen with no known advisories at all: well-maintained projects genuinely do not ship vulnerable dependencies, so a clean result here is the norm rather than a distinction. A signal that is nearly always full marks must not outweigh the one that actually varies. ## What is measured: what a consumer installs For a repository that **publishes a package**, the assessed set is that package's **runtime dependency closure** — every package an installation actually pulls in, direct and transitive — resolved from the open [deps.dev](https://deps.dev) index. The report names the exact package and version assessed. Only where a repository publishes nothing does the inspection fall back to the repository's **own dependency graph**, computed by the hosting platform from committed manifests and lockfiles. That graph is a different thing: it also contains development and test pins, which no installer ever downloads. Reports in this scope say so. Runtime closures are currently resolvable for **npm, PyPI, crates.io and Maven** packages. Repositories publishing to Go, NuGet, RubyGems, Packagist or Hex are assessed against their repository graph until the index covers them — a limit of the data source, not a judgement about those ecosystems. The distinction is not academic. Flask's repository graph contains old versions of Werkzeug and Jinja that the project deliberately pins to test against; they carry advisories, and none of them reaches anyone who installs Flask. The published closure is six packages, none affected. Measuring the first would report on Flask's test matrix while appearing to report on Flask. Either set is matched against **[OSV](https://osv.dev)**, the open advisory database maintained by the Open Source Security Foundation, which aggregates GitHub Security Advisories, PYSEC, RUSTSEC, Go's vulnerability database and others behind one schema. OSV is free, public, and versioned — the same properties that make the Scorecard a defensible backbone for [security posture](/wiki/security-posture). The same query also returns packages reported as **malicious**. Those are not vulnerabilities and are not counted here: they carry no severity and no fixed version, and are reported and scored separately as [malicious dependencies](/wiki/malicious-dependencies). A package appearing there does not also appear in the counts on this page. ## What is reported For each affected package: the resolved version, whether it is a direct or an indirect dependency, the worst severity across its advisories, how many advisories apply, their identifiers, and — where the advisory states one — **the version the problem was fixed in**. Severity comes from the advisory database's own label. Records that carry no severity, common for PYSEC entries, are reported as *unknown* rather than assigned a guessed value. ## How it scores Three components: | Component | Weight | | --------- | -----: | | Direct dependencies free of known advisories | 35 | | Indirect dependencies free of known advisories | 25 | | No advisories left outstanding | 40 | Direct dependencies weigh more than transitive ones because they are the project's own declared choice; transitive ones arrive with them. **Severity is the published CVSS base score**, not a coarse label. Each affected package contributes its score on a 0–1 scale. The database's own `critical`/`high`/`moderate`/`low` wording is used only where an advisory publishes no CVSS vector. Within the first two components the **single worst finding dominates**, and the remaining volume matters progressively less. One critical-severity dependency costs about three quarters of its component; eight low-severity ones cost about a third. That ordering is deliberate — a hundred trivial advisories are not equivalent to one critical — and the volume term never drives a component to zero, so a project with 300 findings still scores below one with 30 rather than tying with it. The third component asks a different question: **how long has the fix been available?** Being hit by an advisory published last week is bad luck. Still resolving to a version affected by one published a year ago is a failure to track dependencies. A package counts here once its oldest advisory passes 90 days. Where no advisory carries a publication date the component is excluded and its weight renormalized, never assumed clean. A dependency set with no known advisories scores full marks on all three. ## Coverage is stated, never assumed Some entries in a dependency graph carry no recorded version. A package without a version cannot be matched against a version range, so it is skipped and **counted** — every report states how many dependencies were assessed and how many were not. Repositories whose dependency graph is unavailable or switched off are not penalized. The metric is excluded and the remaining Security weight renormalized, exactly as with any other unavailable input — see [the health index](/wiki/health-index). ## What this does not claim An advisory here means one thing precisely: **the version recorded in the dependency graph falls inside an advisory's affected range.** It does not mean the vulnerable code path is reachable from this project, and it does not mean the project is exploitable. Most advisories in a large transitive closure are not exploitable in context. Where a report falls back to the repository's own dependency graph — because the repository publishes no package — it cannot separate what the project ships from what it uses to build and test itself. Those reports say which scope they used, and their findings should be read as being about the repository's development environment as much as its software. Read alongside [signals, not warranties](/wiki/signals-not-warranties): a clean result is not a security guarantee, and a finding is a prompt to look, not a verdict. ## Why it is separate from security posture The Scorecard's own vulnerabilities check queries the same advisory database and already contributes to [security posture](/wiki/security-posture). Scoring a second signal derived from OSV inside that same metric would count one body of evidence twice. Keeping them apart also keeps them honest about their different granularity. Security posture asks whether a project carries known-vulnerable dependencies at all, as one check among nineteen. This metric asks which packages, at what severity, and fixed in which version — the form an answer has to take before anyone can act on it. Related: [Security](/wiki/security) · [security posture](/wiki/security-posture) · [malicious dependencies](/wiki/malicious-dependencies) · [supported ecosystems](/wiki/supported-ecosystems) · [signals, not warranties](/wiki/signals-not-warranties) --- # AI agent context > How inspect.software measures agent guidance — CLAUDE.md, AGENTS.md, Cursor rules, Copilot instructions, llms.txt, and whether the commit history states its intent. Part of the AI Readiness badge. **AI agent context** measures whether a repository gives AI coding agents guidance and machine-readable documentation. An agent dropped into an unfamiliar codebase faces the same problem as a new hire — except it reads the onboarding material in milliseconds, every session. Projects that write that material down get measurably better agent output. - **Category:** [AI Readiness](/wiki/ai-readiness) (30% within category) - **Weight in overall index:** 1.2% - **Metric key:** `ai_agent_context` ## How the value is computed | Component | Weight | Evidence | | --------- | ------ | -------- | | Agent instructions | 45 | `CLAUDE.md`, `AGENTS.md`, `.cursor/rules`, Copilot instructions, `GEMINI.md`, or equivalent; a file below ~200 bytes registers as a stub and earns partial credit | | Machine-readable docs | 15 | `llms.txt` or `llms-full.txt` present | | Legible commit history | 40 | share of human commits that state their intent; full marks from 75% upward | ## Why the commit history counts Written guidance is a file someone had to decide to create, and most projects never have. The commit history is different: every project produces one already, and an agent consults it before changing unfamiliar code — to learn why the surrounding decisions were made, not just what the code does. A commit counts as stating its intent when its subject is structured — in conventional-commit form, or referencing the issue or pull request behind the change — **or** when its body explains the change rather than restating the subject. Either form qualifies, because either requirement alone would be parochial: the Linux kernel writes no conventional prefixes and almost always explains itself, while other projects run a fully conventional history with one-line messages. Both are legible; both count. Commits made by automation are excluded, since machine-generated subjects are uniformly well-formed and say nothing about the project's own practice. ## What good agent context contains An effective instruction file tells an agent what the README tells a human, plus what only maintainers know: how to build and test, which directories matter, project conventions, and the traps ("the container serves built images — rebuild after editing"). The `llms.txt` convention complements it by giving language models a curated index of the project's documentation. The stub rule exists because presence signals can be gamed: an empty `CLAUDE.md` created for the badge is detectably different from a real one, and the methodology weights substance where it is cheap to detect. ## Reading the result - Signals are presence- and size-based from the file tree; content is not graded — the honest limit stated across the [AI Readiness](/wiki/ai-readiness) category. - Any of the recognized instruction conventions counts; the methodology is vendor-neutral across agent tooling, mirroring the tool-agnostic stance of [security posture](/wiki/security-posture). ## Improving the value - Write a substantive `CLAUDE.md` or `AGENTS.md`: build and test commands, layout, conventions, and known pitfalls. Keep it current — it is documentation with an executable audience. - Add an `llms.txt` indexing the project's documentation for language-model consumption. - Reference the issue or pull request in commit subjects, or explain the change in the body. Both are ordinary review discipline; both leave the history readable by whoever — or whatever — maintains the project next. Related: [AI verify loop](/wiki/ai-verify-loop) · [AI Readiness](/wiki/ai-readiness) --- # AI verify loop > How inspect.software measures the agent verify loop — one-command bootstrap, tests, lint, type checking, reproducible environments. The heaviest AI Readiness metric. **AI verify loop** measures whether an AI coding agent can set up the project, run it, and verify its own change without human help. This is the crux of autonomous agent work — an agent that can check its work compounds; one that cannot merely generates plausible text — and it carries the heaviest weight in the [AI Readiness](/wiki/ai-readiness) badge. - **Category:** [AI Readiness](/wiki/ai-readiness) (40% within category) - **Weight in overall index:** 1.6% - **Metric key:** `ai_verify_loop` ## How the value is computed | Component | Weight | Evidence | | --------- | ------ | -------- | | One-command bootstrap | 18 | Makefile, Taskfile, justfile, mise, or noxfile earns full credit; a toolchain that defines the command itself (`Cargo.toml`, `go.mod`, `mix.exs`, Maven, Gradle, `.csproj`) earns most of it | | Automated tests | 22 | a test suite the agent can run to self-check (shared with [engineering practices](/wiki/engineering-practices)) | | Lint / format config | 11 | shared with the engineering linter signal | | Static type checking | 11 | a statically typed language, or a type-check configuration (mypy, pyright, tsconfig, `py.typed`) | | Reproducible environment | 10 | devcontainer, Dockerfile, Nix, or a dependency lockfile | | Demonstrated agent practice | 10 | share of recent commits authored or co-authored by a coding agent; full marks from 5% upward | | Automated maintenance | 8 | dependency-update bot commits observed in the sample; a configuration with nothing observed earns partial credit | | OpenSSF Scorecard: Pinned-Dependencies | 10 | Scorecard's 0–10 result, scaled to 10 points | `Pinned-Dependencies` is shared evidence: it adds supply-chain reproducibility information to the agent verification loop while remaining a full Security component. It is excluded when Scorecard is unavailable or reports `n/a`. ## Evidence, not only equipment Every other component here reads the repository's files: a task runner exists, a lockfile exists. Each is a proxy for a loop nobody has watched run. Commits authored by a coding agent — or credited to one in a `Co-authored-by` trailer — are the one available record that the loop was actually closed. A change was proposed, verified, and merged with an agent in the loop, and the project's own history says so. A dependency bot's pull request is machine-authored too, and it must clear the same gates: the tests run, the checks pass, it merges. A project already absorbing that traffic has shown the pathway an agent needs, which is why **automated maintenance** is scored beside agent practice rather than folded into it — either can be present without the other. What counts is the observed commits, not the configuration file. A `dependabot.yml` can sit in a repository with the integration switched off, and Renovate is commonly configured outside the repository altogether: two widely used projects run it across roughly a third of their commits while carrying no recognizable config file at all. Only bots that author their own content qualify — a robot that merges other people's work is not writing changes. The same commits count *against* a repository in [development activity](/wiki/development-activity), where automation crowding out human work is a warning sign. That is deliberate. The two metrics ask different questions: whether people still maintain a project, and whether machines can contribute to it. Both answers can be true at once. This evidences **adoption, not autonomy**. A maintainer working interactively with an agent leaves the same trace as an unattended run, and public data cannot tell the two apart, which is why the component carries a modest weight and makes no claim about how much of the work the agent did. Detection also recognizes only the agents it knows about, so a project using an unrecognized tool simply reads as having no evidence — never as failing. The component is excluded rather than scored as zero when no commit sample was collected. ## Why the toolchain counts as a bootstrap `cargo test` and `go test ./...` are the canonical verify loops of their languages. Crediting only task runners charged those ecosystems for having better defaults — well-run Rust projects scored zero on this component for shipping no Makefile. `package.json` and `pyproject.toml` are deliberately not credited: npm and Python define no universal test command, and whether a given project defines one lives inside file contents this metric does not read. ## Why this loop decides agent usefulness Each component removes one failure mode of autonomous work: - **Bootstrap** — the agent can go from clone to running without archaeology. - **Tests** — the agent can prove a change did what was intended. - **Lint and types** — entire classes of error are caught mechanically, before review. - **Reproducible environment** — "works in the agent's sandbox" means works elsewhere too. Notably, this is the same infrastructure that serves human contributors — the metric rewards no agent-specific exotica beyond what a disciplined project already has. A strong [Engineering Quality](/wiki/engineering-quality) project typically starts strong here. ## Reading the result - Signals confirm the loop's *existence*, not its speed or coverage — the presence-based honesty rule of the whole badge. - A high verify loop with a stub [agent context](/wiki/ai-agent-context) usually means a well-engineered project that simply has not written agent guidance yet — the cheapest possible improvement. ## Improving the value - Add a Makefile (or justfile/Taskfile) exposing `install`, `test`, and `lint` targets. - Keep an automated test suite runnable locally in one command. - Adopt type checking — even a minimal mypy/tsconfig counts. - Commit a lockfile, Dockerfile, or devcontainer for environment reproducibility. - Where agents are already used, keep the `Co-authored-by` trailer the tools add by default. Stripping it removes the only public evidence that the loop closes in practice. Related: [AI code legibility](/wiki/ai-code-legibility) · [engineering practices](/wiki/engineering-practices) --- # AI code legibility > How inspect.software measures code legibility for AI models — type-checkable code and manageable file sizes. Part of the AI Readiness badge. **AI code legibility** measures whether a codebase is legible to a language model: whether the code carries machine-checkable type information and whether files fit comfortably in a model's working context. The same properties that help a human navigate an unfamiliar codebase help a model — but for models, oversized files are a hard constraint rather than an annoyance. - **Category:** [AI Readiness](/wiki/ai-readiness) (15% within category) - **Weight in overall index:** 0.6% - **Metric key:** `ai_code_legibility` - **`null`** for repositories with no detectable source files — docs-only projects are not penalized ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Type-checkable code | 45 | statically typed language → 45 pts; dynamically typed with a type-check configuration → 27; neither → 0 | | Manageable file sizes | 55 | `(1 − oversized / total) × 55`, where a source file over ~60 KB (~1,500 lines) counts as oversized; vendored and generated paths are excluded | ## Why these two signals - **Types are compressed documentation.** A typed signature tells a model what a function accepts and returns without reading its body — and a type-checker turns the model's misunderstandings into immediate, mechanical errors instead of latent bugs. Partial credit for dynamically typed projects with a checker (mypy, pyright, tsconfig) reflects that gradual typing captures much of the benefit. - **File size distribution** determines whether a model can hold a unit of code in context whole. A codebase of focused modules can be read piecewise; a 5,000-line file forces truncation, and truncation is where agent errors concentrate. Vendored and generated code is excluded so that a committed `vendor/` tree or generated bindings do not distort the measurement. ## Reading the result - The metric reads structure, not style — naming, comments, and architecture are not graded (see the honesty rules in [AI Readiness](/wiki/ai-readiness)). - The file-size component is proportional: one oversized file among fifty costs little; a codebase of monoliths reads accordingly. ## Improving the value - Adopt a type checker; in dynamic languages, even a permissive initial configuration earns the partial credit and creates the ratchet. - Split files approaching ~1,500 lines along their natural seams. - Keep generated and vendored code in conventionally named paths so it is excluded from measurement. Related: [AI verify loop](/wiki/ai-verify-loop) · [AI interfaces](/wiki/ai-interfaces) --- # AI interfaces > How inspect.software measures machine-readable interfaces — API schemas, MCP servers, and runnable examples. Part of the AI Readiness badge. **AI interfaces** measures whether a project exposes machine-readable interfaces: formal API schemas, a Model Context Protocol server, or runnable examples. Where they exist, an AI agent can consume the software through a contract instead of reverse-engineering behavior from source. - **Category:** [AI Readiness](/wiki/ai-readiness) (15% within category) - **Weight in overall index:** 0.6% - **Metric key:** `ai_interfaces` - **`null`** when the repository exposes none of the signals — absence is treated as not-applicable, never as a penalty ## How the value is computed | Component | Weight | Evidence | | --------- | ------ | -------- | | API schema | 40 | OpenAPI/Swagger, GraphQL SDL, protobuf, or AsyncAPI files | | MCP server | 20 | a Model Context Protocol server dependency or `mcp.json` configuration | | Runnable examples | 40 | `examples/`, `recipes/`, or `samples/` directories, or notebooks | ## The null rule, explained A plain utility library legitimately has no API schema, no MCP surface, and possibly no examples directory — and it would be wrong to mark it down for its nature. The metric therefore only produces a value when at least one signal is present; otherwise it is `null` and the [AI Readiness](/wiki/ai-readiness) category renormalizes onto its other metrics, following the methodology-wide missing-data rule (see [the health index](/wiki/health-index)). ## Why these three signals - **API schemas** are contracts a model can read exactly — endpoints, types, and errors without inference. - **An MCP server** is the strongest possible statement of agent readiness: the project ships a first-class interface for AI tooling. - **Runnable examples** are executable documentation. For an agent, a working example is a verified starting point rather than prose to interpret — and examples double as a de-facto test of the public API. ## Improving the value - Publish the API schema the project already implies: generate OpenAPI from the framework, commit the `.proto` or GraphQL SDL files. - Maintain an `examples/` directory with small, runnable programs kept current in CI. - Where the project naturally serves tooling, consider shipping an MCP server. Related: [AI agent context](/wiki/ai-agent-context) · [AI Readiness](/wiki/ai-readiness) --- # Abandonment > How inspect.software decides a project has been left unmaintained — why silence alone is never the finding, what counts as an unmet obligation, and what holds the assessment back. Every tool in this field answers the question with one number — days since the last commit — and every one of them is wrong about the same projects. A small, complete library that has needed no changes in three years is not abandoned. It is finished. Marking it dead costs a record its credibility precisely on the software that deserves the most confidence. So silence is never the finding here. The assessment rests on a different proposition: > Abandonment is an unmet obligation, not an absence of noise. A project incurs obligations when work arrives from outside it — a pull request that wants review, an issue that wants an answer, a published fix for a vulnerability in something it ships. A quiet project with no such demands owes nobody anything and cannot be failing them. A quiet project with fifteen pull requests nobody has looked at in two years, and a year-old advisory whose patch shipped the same week, is not resting. - **Category:** [Vitality](/wiki/vitality) (0% within category) - **Effect:** a multiplier on the overall rating, and a ceiling in the severest states - **Metric key:** `abandonment` ## What the assessment reads **Declared.** The maintainer said so. GitHub's archive flag, or a registry deprecation covering every package the repository publishes. Nothing is inferred and nothing needs corroborating — the record is quoting its subject. **Drought.** No *human* commit for a long time. Deliberately not the repository's push recency, which counts a dependency bot's version bump as a sign of life: projects whose only activity for a year was automated updates report a last push measured in days. Commit authorship is read per commit, and automated authors are excluded. Drought is a necessary condition and never a finding on its own. **Unmet obligations.** The corroborating signals — pull requests left unanswered, issues left unanswered, a published fix left unapplied, releases stalled, continuous integration broken, a sole maintainer absent, or OpenSSF Scorecard independently reporting the project unmaintained. Each is a duty the project is visibly not discharging. **Guards.** Evidence that someone is still there, or that nothing is being asked of them: a maintainer still replying, nothing open to answer, a release within the year, no affected dependency. Two guards hold the result short of a finding however many obligations fired, because both readings — "someone is answering" and "nobody is asking" — fully explain the silence. ## What the states mean | State | Meaning | | ----- | ------- | | `maintained` | Human work is recent; no finding | | `unverified` | The collected evidence cannot answer the question | | `dormant` | Quiet, but explained — held there by guards, or nothing is owed | | `abandoned` | Drought plus unmet obligations, uncontested | | `declared` | The maintainer archived it or deprecated its packages | Anything the data cannot answer is `unverified` and costs the repository nothing. An unauthenticated scan reads no commit sample and no tracker queues, so it can reach no conclusion — recorded as an absence of evidence rather than evidence of absence. ## Reading the result - **The alert names its evidence.** The drought length is stated with the obligations beside it, so the finding can be checked rather than trusted. - **The drought may be a floor.** The commit sample is bounded; when it holds no human commit at all, the true gap predates the window and is reported as "at least" that long. - **A finding is not a verdict on the maintainers.** Projects are abandoned for ordinary reasons — jobs change, interest moves, people fall ill. The record states what a consumer would find, not why. - **Automation does not rescue a project here, and does not condemn it either.** Bot commits are excluded from the drought calculation, so a repository kept warm by a dependency bot reads as quiet as it truly is. Heavy automation beside recent human work is not a signal at all — see [development activity](/wiki/development-activity). ## Improving the value - Answer what is open, or close it. An unanswered queue is the single strongest contributor to a finding. - Apply published security fixes to dependencies, or state why they do not apply. - If the project is finished rather than abandoned, say so — archiving it, or marking its packages deprecated, replaces an inference with a fact. Related: [development activity](/wiki/development-activity) · [maintainer resilience](/wiki/maintainer-resilience) · [Vitality](/wiki/vitality) --- # Malicious dependencies > How inspect.software identifies dependencies reported as malicious packages by the OpenSSF corpus, why they are scored apart from vulnerabilities, and what the finding does and does not claim. A vulnerable dependency is a mistake. A **malicious** dependency is an attack. They are not the same finding, and this record does not score them the same way. **Malicious dependencies** asks one question: does the dependency graph this repository resolves to contain a package that has been reported as malware? ## Where the evidence comes from The source is the OpenSSF [malicious-packages](https://github.com/ossf/malicious-packages) corpus — an openly licensed, community-maintained record of packages found to be malicious across public registries: typosquats, account takeovers, dependency-confusion attacks, and packages shipping prebuilt malicious binaries. [OSV.dev](https://osv.dev) ingests that corpus and serves it under `MAL-` identifiers alongside ordinary security advisories. Because this record already queries OSV for [dependency advisories](/wiki/dependency-advisories), malicious packages arrive on a query that was already being made. The finding costs no additional request, no additional wait, and no additional dependency on a third party. ## Why it is scored apart from advisories Until methodology v1.10.0 these reports were counted as ordinary advisories, and that was wrong in a way worth stating plainly. A malicious-package report carries no CVSS vector and no severity label — there is nothing to score, because malware has no severity, only a state. Scored as an advisory it fell through to `unknown` severity, which is weighted like a *moderate* vulnerability. A package that had been found to steal credentials counted for slightly less than an average CVE. The three properties that make a vulnerability scoreable are all absent: - **No fixed version.** There is no corrected release of the same artifact to upgrade to. The remedy is removal, or moving off the compromised name. - **No partial exposure.** A vulnerability may sit in an unreachable code path. An install-time payload runs when the package is installed. - **No degrees.** A package either is or is not reported as malicious. So a malicious dependency is now removed from the advisory findings entirely and treated as a **red flag**: a multiplier and a ceiling rather than points off. It applies a 35% multiplier to the [security posture](/wiki/security-posture) score and to the calibrated health index, and caps both at **19 — the top of the Critical band**. That is stricter than the [high-risk jurisdiction](/wiki/jurisdiction-exposure) ceiling of 34, because this is a confirmed compromise of the software rather than an exposure to a risk. A package carrying both a malicious report and ordinary CVEs appears only under this finding. Its vulnerabilities are moot. ## Withdrawn artifacts are reported, not scored A registry that removes a malicious package settles the question: nothing installable remains, and a repository that resolves to it is not shipping malware today. Every finding therefore checks whether the registry still serves that **exact resolved version**. Where it does not, the finding stays on the report — the project depends on a name that was compromised, which is worth seeing — but it raises no flag and costs no points. The check deliberately asks about the resolved version rather than the package's latest one. After a takedown npm leaves a placeholder release, marked `-security`, as the package's latest. That protects everyone who resolves a version range, and nobody who pinned the bad version exactly. Reading the latest version would have cleared the first repository this finding ever fired on, which pins the compromised package at the precise version the registry still serves. Where the question cannot be answered — an ecosystem the check does not cover, or a registry that did not respond — the finding is scored as though the package were live. Failing to reach a registry is not evidence that malware was withdrawn. ## Direct and indirect count alike Most of this record's dependency scoring distinguishes a declared direct dependency from one pulled in transitively, because a maintainer chose the first and inherited the second. That distinction does not apply here. A package's install script runs at whatever depth it sits in the resolved graph; a credential stealer four levels down compromises the machine exactly as thoroughly as one named in the manifest. Both are reported, both are scored, and the report states which is which so a reader can see where the package entered. ## What the finding does not claim **It is not an accusation against the maintainers.** The report concerns the package *as published* by whoever published it. A repository resolves to thousands of packages it never inspected; inheriting a compromised one is the normal way this happens, and it says nothing about the intent or competence of the people maintaining the scanned repository. **It is not a claim the code was executed.** The finding says the resolved dependency graph contains the package. Whether anyone installed that exact graph, and what the payload did if they did, is outside what a public record can observe. **It is not our determination.** The classification is the OpenSSF corpus's, reached through its own process and its own sources, and this record reports it rather than reproducing it. A report withdrawn upstream disappears from the next scan. ## How often it fires Rarely — by design and by measurement. Before this metric shipped it was run over a 300-repository sample covering 46,889 resolved dependencies, and it found nothing. That is the expected result, and it is not a sign the check is useless. Registries pull malicious packages within hours to days of discovery, so a lockfile that still resolves to one is unusual. The value of this finding is not that it fires often; it is that when it does fire, it is the single most important fact in the report, and it will no longer be averaged into a vulnerability score. ## When it is not assessed Like [dependency advisories](/wiki/dependency-advisories), this metric is excluded — not scored zero — whenever the dependency graph or the OSV lookup was unavailable. A repository is never penalized for having GitHub's dependency graph switched off; the report says the check did not run instead of implying a clean result. Related: [Security](/wiki/security) · [dependency advisories](/wiki/dependency-advisories) · [security posture](/wiki/security-posture) · [the health index](/wiki/health-index) · [supported ecosystems](/wiki/supported-ecosystems) --- # High-Risk Jurisdiction Exposure > How inspect.software turns public repository-profile evidence into an explainable high-risk jurisdiction exposure signal for repository review. Open source lets an organization inherit extraordinary capability in minutes. It can also create a governance blind spot: a small number of external accounts may shape software that sits deep inside products, infrastructure, and customer environments, while the consuming organization knows little about the repository's operating context. **High-Risk Jurisdiction Exposure** helps close that gap. It is an explainable review signal derived from high-confidence, self-published public profile locations associated with a repository owner, displayed top contributors, and public organizations shown on those contributor profiles. When the evidence matches the current policy scope, the report makes the exposure prominent and adjusts both Security and the overall rating so that strong popularity or engineering practice cannot average it away. The result answers a narrow but useful enterprise question: > **Does this repository present high-risk jurisdiction exposure that > should receive enhanced human review?** It does not answer whether a person is trustworthy. It is not an inference of nationality, citizenship, residence, political belief, malicious intent, or sanctions status. ## Why this belongs in software supply-chain governance Enterprise dependency decisions extend beyond code quality. Procurement, security, legal, resilience, and public-sector teams may need to consider: - sanctions and export-control screening obligations; - government or customer restrictions on software origin and stewardship; - state-linked cyber-threat models and enhanced provenance requirements; - continuity risk if access, payments, hosting, or release infrastructure is disrupted by regional restrictions or disruptions; - concentration risk when a critical dependency relies on a small external stewardship community; and - the need to explain why a package was accepted, monitored, isolated, forked, or replaced. Without a systematic signal, these questions are handled late and inconsistently. A visible, versioned policy result turns them into a repeatable review decision rather than an improvised search during procurement or an incident. ## Current policy scope The policy covers public profile evidence for **Russia, Iran, and North Korea**. Scope membership is not an editorial choice: a country is in scope only when it passes **both** of two institutional tests at once. 1. **Broad, multilateral sanctions and export-control exposure.** The country is subject to country-level restrictive regimes maintained in parallel by the [US Treasury sanctions programs](https://ofac.treasury.gov/sanctions-programs-and-country-information), [EU restrictive measures](https://www.sanctionsmap.eu/), and the [UK sanctions regimes](https://www.gov.uk/government/collections/uk-sanctions-regimes-under-the-sanctions-act) — not merely entity-level designations. Within the scope, North Korea additionally carries [UN Security Council sanctions](https://main.un.org/securitycouncil/en/content/un-sc-consolidated-list), and Iran and North Korea are the two jurisdictions under a standing [FATF call for countermeasures](https://www.fatf-gafi.org/en/countries/black-and-grey-lists.html). 2. **Officially named state cyber-threat activity.** The country is named by Western cyber authorities as a source of state-sponsored operations against technology and supply chains. [CISA's advanced persistent threat program](https://www.cisa.gov/topics/cyber-threats-and-advisories/advanced-persistent-threats) maintains standing nation-state guidance for exactly four states — China, Russia, Iran, and North Korea — and the [ODNI Annual Threat Assessment](https://www.dni.gov/index.php/newsroom/reports-publications) and the [UK NCSC](https://www.ncsc.gov.uk/) name the same four as the principal state cyber actors. The intersection of the two tests is exactly the published scope, and it is what keeps the scope narrow in both directions. A country that passes only one test stays out: China is named on every state cyber-threat list but is not under broad country-level sanctions; Belarus, Cuba, Syria, and Venezuela carry sanctions exposure of varying breadth but are not named by these cyber authorities as sources of state supply-chain operations. Because both tests reference public institutional lists, the scope can be independently re-derived — and it changes only when those lists change, through a versioned methodology update. This is a **versioned supply-chain policy**, not a ranking of nationalities or a claim that every organization faces identical obligations. A country-level location match and an identity-level sanctions match are fundamentally different signals. inspect.software currently implements the former; it does not claim to perform legal sanctions screening. ## What the scanner evaluates The scanner reuses public profile data already collected for: 1. the repository owner account; 2. the displayed top contributors, identified from contribution history—not from private GitHub maintain or admin permissions; and 3. public organization affiliations shown on those contributor profiles. Organization locations are selected inside the same batched GitHub GraphQL request. Classification then runs offline against a compact [GeoNames](https://download.geonames.org/export/dump/) gazetteer. The check adds no GitHub request and no external identity-enrichment service. Only the strongest confirmed evidence determines the multiplier: | Strongest confirmed evidence | Policy multiplier | Interpretation | | --- | ---: | --- | | Repository owner profile | 20% | Direct owner-account exposure; enhanced review has highest priority | | Displayed top-contributor profile | 50% | Material contribution-history exposure; no claim of repository permission | | Contributor's public organization profile | 75% | Public affiliation context; deliberately weaker than a direct profile match | | Assessed locations, no policy match | 100% | No score adjustment | | No assessable public location | excluded | Unknown, never treated as safe or unsafe | A contributor-side match — a displayed top contributor, or a public organization on that contributor's profile — additionally requires the matched contributor to **carry meaningful commit weight**: at least **50 commits**, or at least **10% of the sampled human commits**. The share condition protects small repositories, where a genuine co-maintainer may hold few absolute commits; the absolute condition protects large ones, where a substantial body of work can still be a small percentage. A match below both thresholds is recorded on the report for review, but raises no flag and changes no score: a handful of accepted commits is disclosure, not exposure, and a policy that flagged every incidental contributor would tell a reviewer nothing about stewardship. Owner matches are never gated — the owner controls the repository namespace and release surface at any commit count. A clean result cannot improve weak security hygiene. Missing evidence is never scored as a failure, and multiple matches do not compound into a more severe penalty. ## How it changes the rating The signal is a policy multiplier, not another security-practice checklist: `adjusted Security posture = base Security posture × policy multiplier` A confirmed match also gives the adjusted Security posture an **At Risk ceiling of 34**. The Security category reflects that adjusted posture without applying the multiplier twice. After normal category weighting, the policy multiplier and the same ceiling apply to the **overall repository rating**. This makes the governance decision explicit: a material policy exposure cannot disappear inside an average of popularity, documentation, maintenance, and engineering scores. Every report retains the base value, multiplier, multiplied value, and ceiling. A reviewer can therefore reproduce the result and distinguish technical health from the policy adjustment that changed the published rating. ## How an enterprise should use the signal A policy alert is a route into due diligence—not an automatic accusation or a universal instruction to remove the package. Proportionate responses can include: - **Review:** confirm the upstream public evidence and the dependency's role in the product. - **Verify:** require signed releases, stronger provenance, pinned artifacts, reproducible builds, or additional source review. - **Limit:** keep the dependency away from sensitive data, credentials, build authority, or production environments while review is open. - **Monitor:** watch ownership, contributor concentration, release provenance, and future policy changes. - **Plan continuity:** identify a maintained alternative, internal mirror, or viable fork for a business-critical dependency. - **Document an exception:** record why the exposure is understood and which compensating controls make continued use acceptable. The right response depends on package criticality, execution context, customer commitments, and the organization's own legal and risk framework. The signal creates prioritization and evidence; expert judgement remains responsible for the decision. ## Evidence quality and safeguards High-confidence evidence includes an explicit country name or native spelling, a country flag, an unambiguous administrative region, or a place name unique to or overwhelmingly dominant in a policy country. Conflicting context is **review-only** and never changes a score — another country, a US state, or a named city outside the policy scope, so that a profile reading "Seoul, North Korea" or "London, Munich, St. Petersburg" is treated as ambiguous rather than as a declaration. Internationally recognized Ukrainian territories are excluded from Russia place matching unless the profile explicitly self-declares Russia. A profile that names a country **in order to deny being there** — "not north korea", "Seoul, Korea (not DPRK)" — is likewise review-only. The denial has to sit beside the match to count: "No. 5 Lenin St, Moscow, Russia" declares Russia and retracts nothing. Domains, language, personal names, company text, and inferred identity do not establish location. Public organization membership alone is not a match; the organization must itself publish a matching location. Public reports expose aggregate country-and-role counts, never contributor identities or raw profile locations.
△
This is an explainable governance signal, not a legal or personal judgement. Public location evidence does not establish nationality, residence, sanctions status, malicious intent, repository permissions, or individual trustworthiness. A maintainer can request correction when upstream data or place matching is wrong.
## Why the design serves the public interest Jurisdiction-risk controls are often available only through opaque enterprise databases and private scoring models. inspect.software takes a different approach: the evidence boundary, country scope, multipliers, score ceiling, and limitations are public and versioned. Commercial relationships cannot alter a published result. That transparency protects both sides of the ecosystem. Dependency consumers receive a usable governance signal; maintainers can see exactly what was measured, what was not inferred, and how to challenge incorrect evidence. The objective is disciplined open-source risk review—not suspicion by association. Related: [Security](/wiki/security) · [Security posture](/wiki/security-posture) · [methodology](/methodology) · [signals, not warranties](/wiki/signals-not-warranties) --- # Growth Authenticity > How inspect.software reads a repository's day-by-day star and fork history for growth that organic attention does not produce, and what the Inorganic Growth Policy does about it. A GitHub star is the most widely read trust signal in open source. It is also the only one with no issuer. Stars are sold openly, in bulk, for a few cents each, alongside forks, watchers and followers, and nothing in the number itself distinguishes the bought from the earned. Every assessment that counts stars inherits that problem. **Growth Authenticity** is the part of the methodology that addresses it: the per-day star and fork history collected for each report is read for growth whose *shape* organic attention does not produce, and where such growth is confirmed, the purchasable inputs are discounted rather than believed. The result answers a narrow question: > **Does this repository's popularity history look like something that > happened, or like something that was delivered?** It does not answer who did it, or whether anyone paid for it. Every finding here is a statement about the timing of public events, and nothing more. ## Why the timing gives it away Attention that a project earns arrives through people, and people are irregular. A launch, a Hacker News front page, a conference talk or a newsletter mention produces a spike that is uneven hour to hour, that brings forks along with stars because some readers open the code, and that decays over the following week as the link circulates and then stops. Delivered attention has none of those properties. It arrives on a schedule, from accounts that never look at the repository, and it ends the moment the order is filled. The counter cannot tell the difference. The history can. ## What is measured The report first looks for **spike days** — days on which the repository gained both at least 25 stars and at least twelve times its own median active-day rate. Consecutive spike days are merged into one window. A spike is never a finding on its own. Real projects spike, and a methodology that treated every burst as suspicious would flag every successful launch. A window is confirmed only when **at least two independent signals** corroborate it: | Signal | What it observes | | ------ | ---------------- | | **Star concentration** | The five busiest days hold 80% or more of every star collected. Measured across 502 ordinary repositories, the median puts 6.9% of stars in its five busiest days and none reached 80%. It is a claim about the whole history rather than one burst, so it corroborates every window — and is only available where the whole history was collected. | | **Flat cadence** | Across three or more days, the daily additions barely varied. An audience is uneven; a delivery schedule is not. | | **No fork response** | The window's fork-to-star ratio fell below a quarter of the repository's own long-run ratio — attention that never touched the code. | | **No decay** | The seven days after the burst totalled 5% or less of it. Real spikes have a tail; a filled order stops dead. | | **No released substance** | The project has never published a release at all. Deliberately weak: plenty of legitimate projects publish nothing. An earlier form of this signal treated a burst arriving before a project's *first* release as evidence, and it produced every false positive in the first control measurement — publish, attract attention, release later is how ordinary projects work. | ## The four states | State | Meaning | Effect | | ----- | ------- | ------ | | **Organic** | The history is consistent with organic accretion. | none | | **Unverified** | The collected history cannot answer the question. | none | | **Anomalous** | One confirmed window. | stars and forks discounted 40% | | **Highly anomalous** | Two or more confirmed windows, or one carrying three signals. | stars and forks discounted 70% | The discount applies to the stars and forks components of [popularity](/wiki/popularity) — the two inputs a supplier can sell. Watchers are untouched, because they are not part of what the anomaly evidences, and no other category moves at all. Popularity carries 6.8% of the overall index, so the arithmetic effect is deliberately small. The finding is the product; the adjustment only stops the report from asserting something it has reason to doubt. There is no upward adjustment. A clean history cannot raise a score, exactly as a clean jurisdiction result cannot raise [security posture](/wiki/security-posture). ## What Unverified means, and what it does not A repository reads *unverified* when it has no collected star history, when it holds fewer than 100 stars, or when the collected window spans less than 60 days. It carries no penalty of any kind. This is the common case, and it is a limit of the evidence rather than a verdict. History collection is bounded — the report captures a recent window of star and fork events, not the whole life of a large project — so manipulation older than that window is simply invisible here. *Unverified* means the question was not answerable. It never means the answer was clean. ## Reading the result - **A finding is about a pattern, not a person.** Stars can be bought by a competitor, by a promoter, by a previous owner of the repository, or by someone the maintainers never met. Nothing in this assessment identifies who acted, and nothing in it implies the maintainers did. - **A finding does not make the software bad.** It makes one piece of evidence about the software unreliable. The engineering, governance and security evidence in the rest of the report is unaffected and stands on its own. - **The absence of a finding is not a certificate.** Slow, distributed purchasing across months does not spike, and this assessment will not see it. ## Improving the value Nothing can be done to a repository to improve this result, and that is the point: the assessment reads history that has already happened. A project whose growth was genuine already reads *organic*. Related: [popularity](/wiki/popularity) · [community & adoption](/wiki/community-adoption) · [signals, not warranties](/wiki/signals-not-warranties) --- # Organization assessment > How inspect.software assesses GitHub organizations — portfolio activity, community reach, and profile completeness on the same 1–100 scale and bands. Beyond individual repositories, inspect.software assesses **GitHub organizations** — the entities that steward software portfolios. An organization assessment answers a procurement-grade question: *is this a maintained, accountable, clearly presented steward,* independent of any single repository it owns. Organization values use the same 1–100 scale and the same [rating bands](/wiki/scoring-bands) as repositories, computed under the same versioned methodology. ## Categories and metrics | Category | Weight | Metrics (weight within category) | | -------- | ------ | -------------------------------- | | **Activity & Reach** | 75% | [portfolio activity](/wiki/portfolio-activity) (60%), [community reach](/wiki/community-reach) (40%) | | **Governance & Profile** | 25% | [profile completeness](/wiki/profile-completeness) (100%) | **Activity & Reach** asks whether the repository portfolio is maintained and whether the organization has traction. **Governance & Profile** asks whether the organization is accountable and clearly presented — the same identity evidence that feeds a repository's [stewardship](/wiki/stewardship) metric. ## How portfolio facts are computed Portfolio measurements are computed over a sample of up to **100 public repositories** (the API page cap), ordered by most recent push. For organizations above that size, the sample favors the actively maintained end of the portfolio — stated here because honest methodology includes its sampling rules. ## How organization and repository assessments relate - A repository report embeds its owning account's public profile, which drives the repository's [stewardship](/wiki/stewardship) metric — so organization quality already influences repository values where it should. - An organization assessment is the aggregate view: one number for the steward across everything it maintains. - The same missing-data discipline applies throughout: unavailable facts are excluded and weights renormalized, never counted as zero (see [the health index](/wiki/health-index)). ## Improving an organization's assessment - Keep the portfolio honest: archive repositories that are no longer maintained rather than letting them decay in place — see [portfolio activity](/wiki/portfolio-activity). - Complete the organization profile and verify its domain — see [profile completeness](/wiki/profile-completeness). Related: [stewardship](/wiki/stewardship) · [methodology versions](/wiki/methodology-versions) --- # Portfolio activity > How inspect.software measures an organization's portfolio activity — recently active repos, yearly activity, portfolio size, and original work. 45% of the org index. **Portfolio activity** measures whether an organization's repository portfolio is actually maintained. Organizations accumulate repositories the way attics accumulate boxes; what distinguishes a working steward from a graveyard is the share of the portfolio that still moves. - **Assessment:** [organization](/wiki/organization-assessment), Activity & Reach category (60% within category) - **Weight in organization overall:** 45% - **Metric key:** `portfolio_activity` ## How the value is computed Computed over a sample of up to 100 public repositories, most recently pushed first: | Component | Weight | Criteria | | --------- | ------ | -------- | | Recently active repositories | 50 | share of sampled repositories pushed within the last 90 days | | Yearly active repositories | 25 | share pushed within the last year | | Portfolio size | 15 | log-scaled; ~100 repositories saturates | | Original work | 10 | share of sampled repositories that are not forks | ## Why shares, not counts Ratios make organizations of different sizes comparable: an organization with 8 of 10 repositories active outreads one with 30 of 300. Size still earns its own (smaller, log-scaled) component, because a substantial portfolio is real evidence of capacity — it just cannot compensate for a portfolio that is mostly dormant. The original-work component keeps a wall of forks from impersonating a development organization. ## Reading the result - **Archiving is good hygiene, and the metric rewards it.** GitHub excludes archived repositories from the default listing, so an organization that archives finished work concentrates its sample on what it actively maintains. Honest labeling improves the measurement — by making the measurement more accurate. - The 90-day component dominates: this metric describes the present, with the yearly component as its trailing context. ## Improving the value - Archive repositories that are done or abandoned — the single most effective action, and it also serves the organization's users. - Keep maintained repositories visibly maintained: dependency updates and fixes count as pushes. Related: [community reach](/wiki/community-reach) · [organization assessment](/wiki/organization-assessment) --- # Community reach > How inspect.software measures an organization's community reach — followers and portfolio-wide stars on logarithmic scales. 30% of the organization index. **Community reach** measures an organization's traction: the audience that follows it and the attention its portfolio has earned. Reach matters for the same reason a repository's [popularity](/wiki/popularity) does — widely watched software has more eyes available to notice problems — aggregated to the level of the steward. - **Assessment:** [organization](/wiki/organization-assessment), Activity & Reach category (40% within category) - **Weight in organization overall:** 30% - **Metric key:** `community_reach` ## How the value is computed | Component | Weight | Criteria | | --------- | ------ | -------- | | Followers | 50 | log-scaled; ~1,000 saturates | | Stars across repositories | 50 | summed over the sampled portfolio, log-scaled; ~10,000 saturates | Both components are logarithmic for the same reason popularity is: each order of magnitude counts roughly equally, so the metric differentiates across the whole range instead of only flattering giants. Portfolio stars are computed over the same sample (up to 100 most recently pushed public repositories) as [portfolio activity](/wiki/portfolio-activity). ## Reading the result - **Reach is attention, not use.** It is the weaker cousin of adoption evidence — kept at a moderate weight and paired with activity, which is harder to accumulate passively. - **Followers and stars measure different things.** Followers attach to the organization itself (people watching the steward); stars attach to its work. An organization famous for one repository and followed by no one reads differently from an institution people track as such. - Saturation points mean mega-organizations stop gaining: beyond ~1,000 followers and ~10,000 portfolio stars the question is answered. ## Improving the value There is no direct lever, deliberately. Reach follows the durable levers measured elsewhere: maintained portfolios ([portfolio activity](/wiki/portfolio-activity)), complete public identity ([profile completeness](/wiki/profile-completeness)), and repositories that are easy to adopt ([community health](/wiki/community-health)). Related: [popularity](/wiki/popularity) · [organization assessment](/wiki/organization-assessment) --- # Profile completeness > How inspect.software measures organization profile completeness — verified domain, description, homepage, contact, and identity fields. 25% of the org index. **Profile completeness** measures whether an organization is accountable and clearly presented: a verified real-world identity, a stated purpose, and working ways to reach it. For anyone deciding whether to depend on an organization's software, the profile is the difference between an institution and an anonymous namespace. - **Assessment:** [organization](/wiki/organization-assessment), Governance & Profile category (100% within category) - **Weight in organization overall:** 25% - **Metric key:** `profile_completeness` ## How the value is computed | Component | Weight | Evidence | | --------- | ------ | -------- | | Verified domain | 25 | domain verification completed on GitHub | | Description | 20 | the organization's description field | | Homepage | 15 | a working website URL | | Display name | 10 | a human-readable name beyond the login | | Location | 10 | a stated location | | Contact email | 10 | a public contact address | | Social profile | 10 | at least one linked social account | ## Why a profile is governance evidence - **Domain verification is the anchor — and the heaviest component.** It cryptographically ties the GitHub organization to a real-world domain, which is genuine supply-chain evidence: it forecloses a whole class of namespace-impersonation attacks. The same signal feeds each repository's [stewardship](/wiki/stewardship) metric. - **Description, homepage, and name** establish what the organization is and where its canonical presence lives. - **Location, email, and social links** are accountability surface: routes by which a security researcher, a packager, or a legal team can actually make contact. ## Reading the result - This is the most directly actionable metric in the organization assessment — every component is a settings field, and the whole checklist can be completed in under an hour. - An incomplete profile on an otherwise strong organization usually indicates neglect rather than concealment — but the record can only publish what is visible, and the metric reads accordingly. ## Improving the value - Verify the organization's domain in GitHub settings — the single largest component. - Fill every profile field: description, homepage, display name, location, public email, and at least one social profile. Related: [stewardship](/wiki/stewardship) · [organization assessment](/wiki/organization-assessment)