Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
4a155c1
feat: add packagist worker
epipav Jul 16, 2026
6394fce
fix: race ipv4/ipv6 on packagist fetch connects
epipav Jul 16, 2026
4cb4528
fix: cap packagist connection pool at crawl concurrency
epipav Jul 16, 2026
0ba8558
fix: strip NUL bytes from packagist registry data
epipav Jul 16, 2026
739cae7
fix: run packagist daily downloads later in UTC day
epipav Jul 16, 2026
1c9596b
fix: pin packagist daily downloads runDate to run cutoff
epipav Jul 16, 2026
634d1f7
docs: note packagist 30d drain month-boundary gap
epipav Jul 16, 2026
f43c903
docs: fix stale packagist daily schedule time, note drift
epipav Jul 16, 2026
188728d
docs: correct packagist rate-limit and 404-retry claims
epipav Jul 16, 2026
73ba79e
docs: simplify packagist drift notes
epipav Jul 16, 2026
f86865f
fix: use public DNS for packagist worker
epipav Jul 16, 2026
685f8b0
docs: correct ADR decider full name
epipav Jul 16, 2026
820e909
docs: spell out full packagist env var names
epipav Jul 16, 2026
b3daa48
docs: renumber packagist ADR to 0009
epipav Jul 16, 2026
4c26f3c
fix: avoid ReDoS in packagist name validation
epipav Jul 16, 2026
ca72dea
fix: guard packagist metadata drain against overlap
epipav Jul 16, 2026
8ffb3cf
fix: preserve full license array per packagist version
epipav Jul 17, 2026
398f4be
fix: bump last_synced_at on packagist 30d mirror
epipav Jul 17, 2026
d0596c8
fix: audit all packagist changed-fields consistently
epipav Jul 17, 2026
d72f110
Merge branch 'main' into feat/packagist-worker
epipav Jul 17, 2026
406ad8f
Merge branch 'main' into feat/packagist-worker
epipav Jul 17, 2026
44dad1b
fix: enforce SCM host allowlist, clear stale repo links
epipav Jul 17, 2026
3405641
fix: reconcile removed packagist dependency edges
epipav Jul 17, 2026
544cbe6
fix: per-item retries and download-lane keyset cursors
epipav Jul 17, 2026
5fedfbc
Merge remote-tracking branch 'origin/feat/packagist-worker' into feat…
epipav Jul 17, 2026
eb7d125
refactor: remove dead purlFromPackagistName helper
epipav Jul 17, 2026
7009d3d
refactor: simplify packagist scan/give-up call sites
epipav Jul 17, 2026
57c33ff
docs: trim overlong packagist comments
epipav Jul 17, 2026
5cd4ea1
fix: bump last_synced_at on packagist version cleanup
epipav Jul 17, 2026
e9cad6d
fix: add retry policy to packagist schedules
epipav Jul 17, 2026
ad5e92e
docs: fix stale packagist 30d pinning note
epipav Jul 17, 2026
3a9d2bc
fix: don't defer packagist refresh on p2-only failure
epipav Jul 17, 2026
77e6b6c
fix: guard packagist watermark against re-processing
epipav Jul 17, 2026
666be44
fix: preserve GitLab subgroup paths in canonicalizeRepoUrl
epipav Jul 17, 2026
91c6edc
fix: prune stale repo links, reconcile maintainers
epipav Jul 17, 2026
6251909
fix: wrap packagist metadata writes in a transaction
epipav Jul 17, 2026
dc14b30
fix: make packagist 30d window insert atomic
epipav Jul 17, 2026
1b51541
fix: handle legacy GitLab deep links with no /-/ marker
epipav Jul 17, 2026
2fa15bf
fix: audit packagist writes inside their own transaction
epipav Jul 17, 2026
fde7e7e
fix: allow double hyphens in Composer project names
epipav Jul 17, 2026
5da5aba
fix: drain packagist response bodies on error paths
epipav Jul 17, 2026
2ba80a6
test: verify packagist 30d insert race against real Postgres
epipav Jul 17, 2026
fce9078
docs: fix stale ADR-0006 references, should be ADR-0009
epipav Jul 17, 2026
5d2d533
Merge branch 'main' into feat/packagist-worker
epipav Jul 17, 2026
6fe45a4
style: fix pre-existing prettier drift in packagist README
epipav Jul 17, 2026
b7f08ba
Merge remote-tracking branch 'origin/feat/packagist-worker' into feat…
epipav Jul 17, 2026
4c55efe
fix: renumber packagist migration version
epipav Jul 17, 2026
6c0c214
fix: validate packagist response shapes
epipav Jul 17, 2026
e90a2b2
fix: stop metadata lane overwriting 30d download mirror
epipav Jul 18, 2026
b1a2ba1
fix: sort packagist license arrays deterministically
epipav Jul 18, 2026
9b0aaf5
fix: never bump metadata watermark on generic give-up
epipav Jul 18, 2026
8c6194b
fix: drain packagist seed response body on error
epipav Jul 18, 2026
66c653e
fix: add packagist-worker to frontend-dev ignore lists
epipav Jul 18, 2026
174140d
fix: expand legacy GitLab route keyword list
epipav Jul 18, 2026
0f183c3
fix: give packagist dev inspector its own port
epipav Jul 18, 2026
6f5d90c
docs: fix stale downloads_last_30d ownership claim
epipav Jul 18, 2026
3e42dbe
Merge branch 'main' into feat/packagist-worker
epipav Jul 18, 2026
5b609ca
fix: anchor packagist metadata due-selection to a fixed cutoff
epipav Jul 18, 2026
9e72e3c
fix: never downgrade repo link provenance from packagist
epipav Jul 18, 2026
5c0e3e2
fix: validate packagist time field is a parseable date
epipav Jul 18, 2026
6b9b5c8
Merge branch 'main' into feat/packagist-worker
epipav Jul 22, 2026
45c0709
fix: drop dead composer alias, export FETCHERS for wiring test
epipav Jul 22, 2026
7637434
fix: audit stale is_latest rows cleared outside the batch
epipav Jul 22, 2026
282c403
Merge branch 'main' into feat/packagist-worker
epipav Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions backend/.env.dist.composed
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,8 @@ CROWD_PACKAGES_DB_USERNAME=postgres
CROWD_PACKAGES_DB_PASSWORD=example
CROWD_PACKAGES_DB_DATABASE=packages-db

# Packagist registry crawler contact email
CROWD_PACKAGES_PACKAGIST_MAILTO=

# security-contacts-worker
SECURITY_CONTACTS_USER_AGENT="lfx-security-contacts-worker"
3 changes: 3 additions & 0 deletions backend/.env.dist.local
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ CROWD_PACKAGES_DB_USERNAME=postgres
CROWD_PACKAGES_DB_PASSWORD=example
CROWD_PACKAGES_DB_DATABASE=packages-db

# Packagist registry crawler contact email
CROWD_PACKAGES_PACKAGIST_MAILTO=

# github-repos-enricher
ENRICHER_GITHUB_TOKENS=
ENRICHER_BATCH_SIZE=100
Expand Down
17 changes: 17 additions & 0 deletions backend/src/osspckgs/migrations/V1784314023__packagist_worker.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

-- Packagist worker: per-lane ingestion state tracking (metadata, downloads-30d, daily downloads)
Comment thread
epipav marked this conversation as resolved.
CREATE TABLE packagist_package_state (
Comment thread
epipav marked this conversation as resolved.
purl text PRIMARY KEY,
first_seen_at timestamptz NOT NULL DEFAULT now(),
metadata_last_run_at timestamptz,
metadata_run_result jsonb, -- { status, attempts, httpStatus?, errorKind?, message? }
metadata_last_modified text, -- Last-Modified from p2 endpoint, replayed as If-Modified-Since
downloads_30d_last_run_at timestamptz,
downloads_30d_run_result jsonb, -- { status, attempts, httpStatus?, errorKind?, message? }
daily_downloads_last_run_at timestamptz,
daily_downloads_run_result jsonb -- { status, attempts, httpStatus?, errorKind?, message? }
);

CREATE INDEX ON packagist_package_state (metadata_last_run_at);
CREATE INDEX ON packagist_package_state (downloads_30d_last_run_at);
CREATE INDEX ON packagist_package_state (daily_downloads_last_run_at);
2 changes: 1 addition & 1 deletion docs/adr/0005-pypi-downloads-bigquery-merge-scoping.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**Date**: 2026-07-01
**Status**: accepted
**Deciders**: Anil B
**Deciders**: Anil Bostanci

_Consolidated ADR for the PyPI downloads worker — record further PyPI-worker download decisions here rather than opening new ADRs._

Expand Down
200 changes: 200 additions & 0 deletions docs/adr/0009-packagist-worker-design-decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# ADR-0009: Packagist worker — design decisions (living)
Comment thread
joanagmaia marked this conversation as resolved.

**Date**: 2026-07-13
**Status**: accepted
**Deciders**: Anil Bostanci

_Living, consolidated record for the Packagist (PHP/Composer) worker. Record further
Packagist-worker decisions here as new `### subsections` under Decisions rather than opening a
new ADR per decision — mirrors ADR-0001 (oss-packages living ADR) and the ADR-0005 consolidation
note. Each entry is stamped with its own `**Decided**` date; the Changelog at the bottom tracks
when entries are added or revised._

## Context

Packagist is the primary registry for PHP/Composer. Unlike npm/maven/pypi/etc., it is **not
covered by deps.dev** — there is no `PACKAGIST` system in `bigquery-public-data.deps_dev_v1` — so we
cannot seed it from BigQuery the way ADR-0001's universe ingest does for other ecosystems. We crawl
Packagist directly instead (list.json seed → dynamic stats endpoint → static p2 metadata endpoint).
A consequence that shapes several decisions: Packagist hands us **per-package Composer manifests**
(the raw `require` / `require-dev` maps a package declared), **not a pre-resolved dependency graph**
like the one deps.dev exposes in BigQuery.

## Scope and current status

| Decision area | Status |
| --------------- | ------- |
| Dependency model | decided |
| Metadata enrichment scope | decided |
| Lane architecture & cadence | decided |

---

## Decisions
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.

### Dependency model: direct edges + declared constraints, resolved at query time
Comment thread
joanagmaia marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.
Comment thread
epipav marked this conversation as resolved.

We store, in `package_dependencies`, **only the direct dependency edges a version declares** — one
row per `(version_id, depends_on_id, dependency_kind)` — and we **resolve concrete versions and
transitive closure at query time**, never at ingest.

Per stored edge (for **all** packages — dependency edges ride the same p2 metadata fetch as
versions; see the Metadata enrichment scope decision):

- `require` → `dependency_kind = 'direct'`, `require-dev` → `dependency_kind = 'dev'`.
- `version_constraint` = the **declared** constraint string verbatim (e.g. `^3.0 || ^2.0`).
- `depends_on_id` = the depended-on **package** row (resolved by name; edges whose target isn't a
known packages row are counted and skipped, not errored).
- `depends_on_version_id` = **NULL** — we do not resolve the concrete satisfying version at ingest.
- Platform requirements (`php`, `hhvm`, `ext-*`, `lib-*`, `composer-*` — anything with no `/`) are
excluded; they aren't packages.

**Provenance.** The query-time transitive model is a **stated requirement**, quoted verbatim from
the Packagist change brief:

> We store only direct dependencies (the requirements declared in each version's composer.json) and
> walk the tree at query time when transitive resolution is needed. We do not need to compute or
> store the resolved graph at ingest.

Leaving `depends_on_version_id` NULL is the column-level **implementation** of that last sentence —
the resolved concrete version *is* part of "the resolved graph" — locked at the plan-approval gate
and consistent with the pre-existing schema comment (`depends_on_version_id bigint, -- resolved
version; NULL if unknown`). Storing the declared `version_constraint` but not a pinned version means
the two derived views — *which version a constraint resolves to* and *the full transitive tree* —
are both computed on read.

**Why not pin `depends_on_version_id` at ingest (as deps.dev does):** a resolved version is *derived
and volatile*. `^3.0` resolves to whatever `psr/log` patch is newest this week; a stored pin goes
stale the moment a patch ships and would need continuous rewriting. deps.dev's own worker documents
exactly this churn — re-resolving `^4.17.0` every snapshot is what produced its ~555M-row edge
exports and forced a snapshot-diff to suppress it. We sidestep it entirely by storing the immutable
declared constraint and resolving on demand. deps.dev pins because it *already* has a fully-resolved
graph in BigQuery for free; we only get manifests, so resolving eagerly would mean building and
continuously re-running a Composer resolver for no durable benefit.

**Why store `dev` edges when deps.dev doesn't:** deps.dev's resolved graph is runtime-only — every
edge lands as `'direct'`, it has no dev/peer notion. Because we read the raw manifest we can split
`require-dev` into `'dev'`, so Packagist edges are *richer per-edge* (dev deps + declared
constraints) even though they are *shallower* (no resolved target version) than deps.dev's.

**Consequences.**

_Positive:_

- Write path is small and touches only immutable declared facts — no re-resolution churn, no
billion-row resolved-graph materialization for Packagist.
- Query-time resolution and transitive walks always reflect current data (new patches, newly-added
deep dependencies) with no re-ingest.
- Captures dev-dependencies (`kind='dev'`), a dimension deps.dev-seeded ecosystems lack.
- Schema-compatible with the deps.dev-populated `package_dependencies`: same table, same unique key
`(version_id, depends_on_id, dependency_kind)`; the `depends_on_id` HASH-partitioning (ADR-0001)
keeps the upstream "who depends on X?" hot path fast for Packagist edges too.

_Negative / trade-offs:_

- `depends_on_version_id` is NULL for every Packagist edge — a consumer that wants the exact version
a dependency pulls in must resolve the constraint itself; there is no per-edge pinned version the
way there is for npm/maven/pypi/cargo seeded from deps.dev.
- Transitive questions ("everything X depends on") pay a recursive walk over direct edges at read
time rather than a single indexed lookup.

_Risks:_

- If an LFX product later needs per-edge **resolved** versions for Packagist, that is a
**requirements change** — it reopens the "do not store the resolved graph at ingest" decision and
would require standing up a Composer-style resolver (and accepting the re-resolution churn deps.dev
fights). Flagged here so the trade-off is revisited deliberately, not silently.

**Decided**: 2026-07-13

---

### Metadata enrichment scope: all packages, not the critical slice

The metadata lane (p2 manifests → `versions`, `package_dependencies` edges, and the package-level
aggregates `licenses` / `latest_version` / `versions_count` / `first_release_at` /
`latest_release_at` / `homepage`) runs for **all ~500K Packagist packages**, not only the critical
slice: `CROWD_PACKAGES_PACKAGIST_RUN_ONLY_FOR_CRITICAL` defaults to `false` (setting it `true`
narrows back to the critical slice). The same lane additionally links `repos` /
`package_repos` rows for all packages (`'declared'` @ `0.8`, the manifest-declared convention
shared with npm/pypi/maven/cargo), so the shared github-repos-enricher picks Packagist repos up.

**Provenance.** Requested in the deps.dev-parity review (Joana): deps.dev has zero Packagist data,
so unlike every other ecosystem there is no external source backfilling the non-critical majority —
the tiering left most of the catalog thin for no data-availability reason. The goal is best-effort
parity with what deps.dev populates for its ecosystems.

**Why this deliberately diverges from pypi:** the pypi sibling documents critical-only as the
"intended steady state" with all-packages as a temporary bootstrap mode. That design assumes
deps.dev provides package-level data for the whole ecosystem, so per-package registry enrichment
only needs to deepen the critical slice. Packagist has no such backstop; the registry crawl *is*
the universe source. The p2 endpoint is a static, CDN-served file designed to be mirrored (it is
how Composer clients resolve), with `If-Modified-Since`/304 replay — so the steady-state weekly
cost after the first full pass is dominated by 304s, not re-parses.

**What stays critical-only (deliberate, not parity gaps):** `downloads_daily` and
maintainers. deps.dev carries no downloads at all, and npm/pypi both scope daily downloads and
maintainer enrichment to the critical slice; ungating maintainers would also cost ~3–4M per-row
DB round-trips per weekly cycle (`upsertPackageMaintainers` is 2M+2 queries per package) — a
batching rewrite is a prerequisite before that scope can ever widen.

**Consequences.**

_Positive:_ versions, direct dependency edges, licenses/latest-version/release-date aggregates,
homepage, and repo links exist for the whole catalog — matching deps.dev's coverage shape; ranking
inputs and downstream consumers see a fully-populated ecosystem rather than a thin one.

_Negative / trade-offs:_ the weekly metadata drain walks ~500K purls (~10k keyset batches, ~500
continueAsNew generations) instead of ~56K; `versions` grows by an estimated 5–10M rows and
`package_dependencies` by ~20–40M edges (both well within the tables' 90M+/1.15B+ design points);
the two packagist workers now default to opposite scopes, mitigated by explicit comments at both
flip points.

_Risks:_ the all-packages due-selection abandons the partial `is_critical` index and rides the
`purl` btree keyset walk — late-cycle batches skip progressively more already-scanned rows; if the
tail slows measurably, revisit with an `EXPLAIN` (flagged in the rollout checklist).

**Decided**: 2026-07-16

---

### Lane architecture: seed → chained enrichment, downloads as dedicated lanes

Four workflows instead of the earlier seed/stats/metadata split (the `ingestPackagistStats`
workflow, whose name and mixed responsibilities were unclear, was removed):

1. **`seedPackagistPackages`** — weekly cron. Discovery only; on completion **chain-starts the
enrichment drain as a child workflow** (`ParentClosePolicy.ABANDON`) instead of a second cron,
so "after seed" is an event, not a clock offset (same idiom as `bootstrapOsspckgs`).
2. **`ingestPackagistMetadata`** — the merged enrichment lane: per package it fetches **both**
registry endpoints — dynamic (package info, counters, repo link, maintainers) and p2 (versions,
dependencies, aggregates, homepage) — under one `metadata_last_run_at` watermark.
3. **`ingestPackagistDownloads30d`** — monthly cron **on the 1st**: captures the observed rolling
30d value as the month's `downloads_last_30d` window row (mirrored to the packages column),
npm's breadth pattern (run-scoped cutoff, per-purl watermark). Running on the boundary replaces
the earlier "first scan on/after the 1st" heuristic. No history/backfill lane — Packagist keeps
no historical series, so a missed month is unrecoverable by design.
4. **`ingestPackagistDownloadsDaily`** — daily cron, critical slice only.

Each lane owns its own watermark + run result in `packagist_package_state`
(`metadata_* / downloads_30d_* / daily_downloads_*`; the ambiguous `p2_last_modified` renamed to
`metadata_last_modified`). Trade-offs: the enrichment lane makes two HTTP calls per package
(bounded by the dynamic endpoint's 10-concurrency), the dynamic endpoint is fetched by three lanes
at different cadences (~500K extra fetches/month for the 30d lane), and a hard seed failure skips
that week's enrichment (recoverable via the manual trigger).

**Decided**: 2026-07-16

---

## Changelog

- **2026-07-13** — ADR created. First entry: _Dependency model: direct edges + declared constraints,
resolved at query time_.
- **2026-07-16** — Added _Metadata enrichment scope: all packages, not the critical slice_ (also
covers repo linking for all packages and the deliberate critical-only carve-outs).
- **2026-07-16** — Added _Lane architecture: seed → chained enrichment, downloads as dedicated
lanes_ (removes the stats lane; renames `p2_last_modified` → `metadata_last_modified`).
- **2026-07-17** — Corrected stale "critical slice only" wording left over in the _Dependency
model_ entry from before the _Metadata enrichment scope_ decision widened it to all packages;
set `Status` to `accepted` (matching ADR-0005's precedent for a living/consolidated doc).
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Use the `/adr` skill in Claude Code to record new ADRs or query past decisions.
| [ADR-0006](./0006-database-schema-types-as-source-of-truth.md) | Database schema types as the source of truth | accepted | 2026-07-09 |
| [ADR-0007](./0007-test-factory-primitives-and-defaults.md) | Test factory primitives and defaults | accepted | 2026-07-10 |
| [ADR-0008](./0008-how-we-write-unit-tests.md) | How we write unit tests | accepted | 2026-07-13 |
| [ADR-0009](./0009-packagist-worker-design-decisions.md) | Packagist worker — design decisions | accepted | 2026-07-13 |

## Why ADRs?

Expand Down
2 changes: 1 addition & 1 deletion scripts/builders/packages.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DOCKERFILE="./services/docker/Dockerfile.packages"
CONTEXT="../"
REPO="sjc.ocir.io/axbydjxa5zuh/packages"
SERVICES="github-repos-enricher bq-dataset-ingest npm-worker pypi-worker maven-worker osv-worker dockerhub-sync cargo-worker go-worker nuget-worker security-contacts-worker rubygems-worker blast-radius-worker"
SERVICES="github-repos-enricher bq-dataset-ingest npm-worker pypi-worker maven-worker osv-worker dockerhub-sync cargo-worker go-worker nuget-worker security-contacts-worker rubygems-worker blast-radius-worker packagist-worker"
4 changes: 2 additions & 2 deletions scripts/cli
Original file line number Diff line number Diff line change
Expand Up @@ -1182,14 +1182,14 @@ while test $# -gt 0; do
exit
;;
service-restart-fe-dev)
IGNORED_SERVICES=("frontend" "python-worker" "job-generator" "webhook-api" "profiles-worker" "organizations-enrichment-worker" "merge-suggestions-worker" "members-enrichment-worker" "exports-worker" "entity-merging-worker" "automatic-projects-discovery-worker" "pcc-sync-worker" "projects-evaluation-worker" "bq-dataset-ingest" "cargo-worker" "dockerhub-sync" "github-repos-enricher" "go-worker" "maven-worker" "npm-worker" "nuget-worker" "osv-worker" "pypi-worker" "rubygems-worker" "security-contacts-worker")
IGNORED_SERVICES=("frontend" "python-worker" "job-generator" "webhook-api" "profiles-worker" "organizations-enrichment-worker" "merge-suggestions-worker" "members-enrichment-worker" "exports-worker" "entity-merging-worker" "automatic-projects-discovery-worker" "pcc-sync-worker" "projects-evaluation-worker" "bq-dataset-ingest" "cargo-worker" "dockerhub-sync" "github-repos-enricher" "go-worker" "maven-worker" "npm-worker" "nuget-worker" "osv-worker" "packagist-worker" "pypi-worker" "rubygems-worker" "security-contacts-worker")
DEV=1
kill_all_containers
service_start
exit
;;
clean-start-fe-dev)
IGNORED_SERVICES=("frontend" "python-worker" "job-generator" "webhook-api" "profiles-worker" "organizations-enrichment-worker" "merge-suggestions-worker" "members-enrichment-worker" "exports-worker" "entity-merging-worker" "cache-worker" "categorization-worker" "cron-service" "data-sink-worker" "git-integration" "integration-run-worker" "integration-stream-worker" "nango-webhook-api" "nango-worker" "script-executor-worker" "search-sync-api" "search-sync-worker" "security-best-practices-worker" "snowflake-connectors-worker" "automatic-projects-discovery-worker" "pcc-sync-worker" "projects-evaluation-worker" "bq-dataset-ingest" "cargo-worker" "dockerhub-sync" "github-repos-enricher" "go-worker" "maven-worker" "npm-worker" "nuget-worker" "osv-worker" "pypi-worker" "rubygems-worker" "security-contacts-worker")
IGNORED_SERVICES=("frontend" "python-worker" "job-generator" "webhook-api" "profiles-worker" "organizations-enrichment-worker" "merge-suggestions-worker" "members-enrichment-worker" "exports-worker" "entity-merging-worker" "cache-worker" "categorization-worker" "cron-service" "data-sink-worker" "git-integration" "integration-run-worker" "integration-stream-worker" "nango-webhook-api" "nango-worker" "script-executor-worker" "search-sync-api" "search-sync-worker" "security-best-practices-worker" "snowflake-connectors-worker" "automatic-projects-discovery-worker" "pcc-sync-worker" "projects-evaluation-worker" "bq-dataset-ingest" "cargo-worker" "dockerhub-sync" "github-repos-enricher" "go-worker" "maven-worker" "npm-worker" "nuget-worker" "osv-worker" "packagist-worker" "pypi-worker" "rubygems-worker" "security-contacts-worker")
CLEAN_START=1
DEV=1
start
Expand Down
Loading
Loading