Skip to content

Ospobox

OSPO in a Box. Know what is happening across the open source you depend on, ship on, and answer for.

Ospobox collects activity from the forges your projects live on, scores what it finds, applies rules to the scores, and pushes the result somewhere that can act on it. That loop (collect → score → decide → act) runs today, on a schedule, with signed delivery at the far end.

Who it is for

Open Source Program Offices answering "what did we ship, where, and who wrote it". Engineering leaders who need the health of a dependency tree to be a number they can defend. Due-diligence and procurement teams deciding whether a project is safe to adopt. Platform and security teams who want a machine-readable signal that arrives on its own.

What you get

A dashboard that answers the questions you get asked

An overview across every organisation you watch, then a page per organisation and per repository. Two organisations sit side by side in a comparison view, which is the screen for "are we keeping up with them". Global search spans organisations and repositories, so one repository among four hundred is a search box away.

Contributors are classified internal, external or bot from your own domain list, which turns "we have 340 contributors" into a number you can put in a board deck. Dark mode and a mobile layout are there because the questions arrive at awkward times.

Health scores with the arithmetic shown

Every repository carries a score out of 100, built from five weighted factors: activity (30%), responsiveness (25%), community (20%), maintenance (15%), popularity (10%). Each factor states what it counted and in what units, so a score you disagree with can be argued with, factor by factor.

Six alert rules, evaluated for you

Inactivity, a low health score, a sharp health drop against a week-old baseline, a week-over-week activity collapse, a pull-request backlog and an issue backlog. They run after every sync and again every six hours, so a repository that has stopped syncing still trips the inactivity rule. Each finding is filed once and stays filed until somebody acknowledges it, which is what stops an alert channel becoming noise people mute.

Commits, PRs opened, PRs merged, issues opened, issues closed and releases, each against the previous seven days, on the overview, the organisation page and the repository page. Rolling windows rather than calendar weeks, so Monday mornings do not read as a collapse.

Where your people actually are

Repositories group into projects, and each becomes a unit the portfolio reports on: how many distinct people worked on it, how many were internal, how many were coding agents, and what landed. A unit carried by one internal contributor is flagged and the person named, because that is a handover conversation waiting to happen.

Set a loaded cost per person and each project carries what it consumed. Cost is reported per project and never against a name. Ospobox counts participation and volume. It does not measure time, and every figure says which it counted.

How much of this did an agent write?

The share of commits crediting a coding agent, per project, read from co-authorship trailers. It is a floor rather than a total, and it says so. Agent work counts as activity in the health score and is kept out of the community factor, because an agent committing daily makes a repository active without making it a community.

Reports for the people who never log in

Build a report from the sections you want (activity, health, contributors, pull requests, issues, releases), export it as Markdown, HTML or PDF, and save it as a template that emails itself daily, weekly or monthly. With an LLM configured, each report opens with a generated executive summary; without one, that section simply does not appear.

A supply-chain view of what you actually ship

Point it at a CycloneDX SBOM and it scores your dependency exposure against advisories from OSV or AboutCode's VulnerableCode, keyed by package URL. The evidence is append-only and content-addressed, so the basis of a finding stays inspectable after the finding.

Integration that does not need polling

Five webhook event types (sync.completed, sync.failed, alert.created, health.changed, report.generated), signed with HMAC-SHA256, retried with backoff, and recorded in a delivery log. A REST API covers the same ground, documented at /docs and /redoc.

Operations that will not surprise you

Four forges on a six-hourly sync or on demand. A /health endpoint and Prometheus-compatible metrics, structured logs, optional Sentry, and a Docker deployment. JWT sessions, argon2 password hashing, CSRF on every form, per-endpoint rate limiting, login throttling, and OAuth tokens encrypted at rest.

How it works

Collects

Four forges (GitHub, GitLab, Codeberg and SourceHut) through one normalized adapter interface, on a six-hourly schedule or on demand. Commits, pull requests, issues, releases, and the metadata around them.

Beyond forges, anything a plugin can produce: a CycloneDX SBOM becomes components keyed by package URL, an advisory feed becomes advisories against those packages. Evidence is append-only and content-addressed, so collecting the same fact twice adds nothing, and a changed fact keeps its history.

Scores

Repositories get a health score with its reasoning attached: every component of every score carries a one-line explanation, rendered as written. Two scorers ship, a five-factor activity composite and dependency exposure over a repository's declared components.

Decides

Rules turn scores and activity into alerts: inactivity, low health, a sharp health drop, a week-over-week activity collapse, PR and issue backlogs. They evaluate after every sync, deduplicate against what is still open, and never file the same finding twice.

Acts

Alerts leave Ospobox as HMAC-signed webhooks, with retries and a delivery log, so a subscriber can hold a deployment, open a ticket, or refuse to resolve a package. Reports go out as Markdown, HTML or PDF, on a cadence, by email, and everything here is reachable over a REST API too.

What makes it unusual

Every judgement about the domain is a plugin. Evidence sources, scorers and alert rules are interfaces, loadable from a third-party package's entry points. The in-tree implementations load through the same registry, as worked examples with no privileges of their own. Read Extension points and check the claim.

Scores explain themselves. A number between 0 and 100 is not an answer. Every component states what it counted and in what units, so a score can be argued with, which is how one comes to be trusted.

Evidence is kept. Facts are stored with a content hash and a collection time, so the basis of a decision remains inspectable after the decision.

Reading these docs

Everything described in plain prose runs today. Anything not yet built is marked:

Planned

Designed and specified, awaiting implementation. The roadmap says where it sits.

Research

Part of the Software Health Control Plane proposal: funded work with partners, which this repository has not committed to. See Architecture.

Quick start

git clone git@git.sr.ht:~sfermigier/ospobox
cd ospobox

make install          # dependencies, via uv
cp .env.example .env  # then edit it

make migrate          # the app does not create tables
make run              # web + worker

Then open http://localhost:8000.

Development mode

With DEBUG=true you can log in as admin@admin / admin. The backdoor is disabled whenever debug is off.

To see the whole loop run end to end (collect, score, alert, signed delivery, actuation) the demo/ directory has a runbook, a receiver that verifies signatures, and a supply-chain script.

Where to go next

If you want to Read
Run it Installation, then Configuration
Get a first organisation syncing First steps
Do a particular job with it Guides
Understand how it is built Architecture
Integrate or extend it API reference, Extension points
Know what is coming Roadmap

Stack

Component Technology
Web framework Litestar
Database PostgreSQL (prod), SQLite (dev and tests)
ORM SQLAlchemy 2.x, async
Background jobs SAQ
Plugins Pluggy, over two surfaces: forges and chassis extensions
Frontend HTMX + Alpine.js + Tailwind CSS
Optional Any OpenAI-compatible API for summaries, Sentry, WeasyPrint

Built on

Ospobox keys every package fact by package URL, and parses them with packageurl-python, the reference implementation. Both come from AboutCode, whose tools sit on either side of the supply-chain loop:

Project Where it fits Licence
packageurl-python Parsing and normalising purl subjects Apache-2.0
VulnerableCode An advisory evidence source beside OSV Apache-2.0 (software), CC-BY-SA-4.0 (data)
ScanCode.io Resolving a manifest into the SBOM this ingests Apache-2.0

Advisory data carries its own terms: VulnerableCode's is CC-BY-SA-4.0, so anything you redistribute from it needs attribution and the same licence. Ospobox ships none of that data; queries fetch it into your own evidence store.

License

Open source. See the LICENSE file.