Prometheus
DE EN

Documentation · 03 / 09

POC specification — Prometheus v2 phase 1

The Phase-1 MVP: registry scraping and the self-instrumentation SDK in parallel, acceptance tests K1–K7.

Status Pivot completed 2026-05-26 · Spec ready for sign-offSource concept/02-poc-spezifikation.mdAudience Engineering · Mirror operators · Maintainer pilot groupReading time ~7 min

Phase-1 MVP: ~10 weeks, two orthogonal capture tracks in parallel, a shared open platform API with one bootstrap mirror in the EU. K1–K7 are the binding acceptance tests.


1. Scope#

In scopeOut of scope (phase 2/3)
Track A — registry scraping (npm, PyPI, Maven Central, crates.io, Go mod) + GitHub manifest crawlEnd-user agent (mode B), hybrid aggregator (mode C)
Track B — self-instrumentation SDK (JavaScript, Python)Further SDK languages (Java, Go, Rust, .NET)
One reference mirror in the EU (single-node ClickHouse + API server + snapshot worker + Rekor client)A second independent mirror, gossip federation
Submission protocol v1.0 (declarative k-anon attestation)ZK-SNARK attestation, threshold consensus
Open Data snapshots (Parquet, CSV.gz), Public Audit LogMix-net submission, threshold decryption
Documentation and federation registry skeletonFinal mirrors.json governance

2. Track A — public registry scraping#

Goal: an immediately visible reach figure from public data, without maintainers or end users having to take part.

2.1 Sources#

RegistryTop list (discovery)Package / dependency sourceFrequency
npmcurated in-tree seed (src/scraper/.../seeds/npm.json)https://registry.npmjs.org/<name>/latestdaily
PyPIhttps://hugovk.dev/top-pypi-packages/top-pypi-packages.min.jsonhttps://pypi.org/pypi/<name>/jsondaily
Maven Centralhttps://search.maven.org/solrsearch/select?q=*:* (Solr caps rows≤200)Dependencies from the POM XML: https://repo1.maven.org/maven2/<g>/<a>/<v>/<a>-<v>.pomdaily
crates.iohttps://crates.io/api/v1/crates?sort=downloadshttps://crates.io/api/v1/crates/<name>daily
Go modulescurated in-tree seed (src/scraper/.../seeds/golang.json)https://proxy.golang.org/<module>/@latestdaily
GitHub manifest crawlTop-N public repository list (public package.json, requirements.txt, pom.xml, Cargo.toml, go.mod)weekly, top 1000 per language

A note on the top lists: npm and Go modules have no maintained, compact "top packages" JSON endpoint (npm: only a 106 MB volume list of all ~4.1 million names; Go: index.golang.org/index is a chronological "recently added" feed, not a usage ranking). Both are therefore fed from a curated, checked-in seed (reviewable, and K1 stays meaningful). Maven Central supplies no dependencies over Solr — those exist only in the POM (XML), which is therefore fetched separately from repo1.maven.org and parsed with defusedxml.

2.2 Aggregate shape (track A)#

{
  "project_id":  "pkg:npm/example-lib",
  "version_id":  "1.4.2",
  "cohort_id":   "dep-edges-from-public-manifests",
  "metric":      "observed_dependency_count",
  "value":       "1247",
  "window_start":"2026-05-26T00:00:00Z",
  "window_end":  "2026-05-27T00:00:00Z",
  "source_mode": "D",
  "provenance":  "registry-scraper@mirror-eu-1"
}

2.3 k-anon in track A#

The data comes from public sources → the k constraint is trivially satisfied. Schema-reject-PII remains in place as defense in depth (for instance no maintainer e-mails in the aggregate, no owner names in the clear from GitHub metadata).


3. Track B — self-instrumentation SDK (JS + Python)#

Goal: the runtime usage-duration view that track A cannot deliver.

3.1 SDK API (abbreviated)#

JavaScript:

import { instrument } from "@prometheus/sdk";

instrument({
  projectId: "pkg:npm/example-lib",
  versionId: "1.4.2",
  cohorts: ["rt-runtime-mins", "install-count"],
  mirror: "https://mirror-eu-1.example",     // Default mirror via the federation registry
  did:    process.env.PROMETHEUS_DID         // optional in phase 1, mandatory from phase 2
});

Python:

from prometheus_sdk import instrument

instrument(
    project_id="pkg:pypi/example-lib",
    version_id="2.0.0",
    cohorts=["rt-runtime-mins", "install-count"],
    mirror="https://mirror-eu-1.example",
)

3.2 Events the SDK emits#

EventTriggerCohort mapping
installModule load for the first time in the processinstall-count
session-startFirst use of a function in the processrt-runtime-mins (counter start)
runtime-tickEvery 5 min, as long as the library is in useUpdates the rt-runtime-mins band
feature-flagOptional custom hook (e.g. prometheus.flag("v2-api-used"))feature-flag-counter

3.3 Aggregate shape (track B)#

{
  "project_id":  "pkg:npm/example-lib",
  "version_id":  "1.4.2",
  "cohort_id":   "rt-runtime-mins",
  "metric":      "runtime_minutes_band",
  "value":       "30-60",
  "k_effective": 23,
  "k_min":       5,
  "window_start":"2026-05-26T12:00:00Z",
  "window_end":  "2026-05-26T13:00:00Z",
  "source_mode": "A"
}

3.4 Banding (prevents PII inference)#

Numeric values are mapped onto bands, never carried as a number in the clear:

BandMeaning
0-5, 5-15, 15-30, 30-60, 60-180, 180-1440, 1440+ (in minutes)Runtime bands
1, 2-5, 5-25, 25-100, 100-1000, 1000+Install count bands
Custom bands per cohort_id definitionPublished in the federation standard

4. Bootstrap mirror#

Phase-1 configuration: single node, EU-hosted, Apache-2.0 open-source stack.

ComponentStack
Aggregate storeClickHouse 24+ single node (or a TimescaleDB equivalent)
Submission APIRust/Go/Python — FastAPI or axum recommended
Public Audit LogSigstore Rekor (self-hosted instance)
Snapshot generatorDaily Parquet and CSV.gz generation at 00:00 UTC
Open Data APIREST + GraphQL, no auth
Federation registry entryAn entry in mirrors.json (the central bootstrap repository)
Local compose variantdocker compose up for reproducible research setups

5. Success criteria K1–K7#

IDCriterionMeasurement
K1Reach discovery: the top 1000 OSS packages per registry are captured in track A at ≥ 95 %Daily sampling check against the npm/PyPI/Maven lists
K2False-positive rate <unclassified>: ≤ 5 % of the captured dep edges remain without a project_id resolution (PURL match)Validator against the PURL standard
K3Schema-reject PII: track A and track B produce 0 submissions with PII fields. The backend schema actively rejects attemptsNegative test with deliberate PII payloads, a mirror reject is expected
K4k-anon effect in track B: no cohort_id with unique_sessions < 5 (default) in the Open Data snapshotSample audit after snapshot generation
K5Availability & resilience: a 30-minute mirror outage → 0 data loss (the SDK buffers locally and retransmits; the scraper is idempotent)Chaos test in staging
K6Open Data usability: a researcher answers the question "which top-10 OSS packages have doubled their reach in the last 12 months?" over the Open Data dump in under 2 minutes (no login needed)User test with a research persona who has not been briefed
K7SDK footprint: the track-B SDK consumes < 5 ms CPU/h and < 2 MB RAM in steady state in a Node.js or Python processProfiler run per CI build

6. Sprint plan (10 weeks, provisional)#

SprintWeeksFocus
11–2Federation registry skeleton (mirrors.json with one entry), submission protocol spec, reference mirror stub
23–4Track A: scraper cores (npm + PyPI), aggregate store, a first snapshot
35–6Track A: Maven + crates + Go, GitHub manifest crawl, K1 check
47–8Track B: JS SDK, Python SDK, banding, submission roundtrip, K4 check
59–10Open Data API, Sigstore Rekor integration (K3 + K5), Public Audit Log, K6 researcher test, K7 footprint profile

7. Out of scope for phase 1 (explicitly)#

  • End-user agent (mode B as a daemon variant outside the library)
  • Hybrid aggregator daemon (mode C)
  • ZK-SNARK attestation (05-zero-knowledge-vorschlag.md, building block B)
  • Cross-mirror gossip (arrives with mirror #2 in phase 2)
  • Threshold consensus (phase 3)
  • SDK languages other than JS and Python
  • Build-tool plugins (Maven/Gradle/cargo hooks)
  • Dashboards with live visualisation (streaming charts, real-time updates, server-side rendering) — research and vendors build their own. This does not mean the static dashboard: that is mandatory deliverable no. 9 (07-prototyp-requirements.md §2 / §7) and carries the K6 evidence. Phase 1 therefore delivers API + Open Data dumps plus a static frontend served by the mirror without a build step.

8. Cross-references#

  • 01-konzept.md — the overall v2 concept
  • 03-risikoprofil.md — phase-1-relevant risks (D-2-1, M-2-1, M-2-2 prioritised)
  • 04-executive-summary.md — stakeholder brief
  • 05-zero-knowledge-vorschlag.md — ZK building blocks (phase 2+)
  • 06-offene-punkte.md — phase-1 blockers (mirror discovery, licence, anti-Sybil, GDPR per mirror)
  • ADRs: ADR-v2-0001 (federation), ADR-v2-0002 (four modes), ADR-v2-0003 (aggregate key), ADR-v2-0004 (licence + audit log)