feat: package-repo ownership-evidence signal (CM-1394) - #4576
Conversation
PR SummaryHigh Risk Overview Database: New Ingestion: Shared Platform: DAL claim params, conflict updates, and Tinybird Reviewed by Cursor Bugbot for commit 6e2f354. Bugbot is set up for automated code reviews on this repo. Configure here. |
Introduces the ownership_match column on package_repos and folds it into package_repo_confidence scoring: unmatched maintainer/namespace evidence on a declared link drops confidence by 0.25, missing evidence by 0.10, on top of the existing secondary-signal penalty. Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
Shared matchOwnership()/repoOwnerFromCanonical() helpers used by every ecosystem writer to compare a package's namespace/maintainers against the linked repo's owner and classify the result as matched, unmatched, or no_evidence. Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
…-1394) Every ecosystem's declared-repo-link write (cargo, deps.dev, go, maven, npm, nuget, packagist, pypi) now computes ownershipMatch via the shared matchOwnership() util and persists it alongside the link, feeding the new package_repo_confidence penalty. Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
…CM-1394) Parse the authors field already present in the RubyGems gem response instead of adding a second fetchOwners call to the core loop, which runs over every rubygems package. Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
This PR extends the packages ingestion + scoring pipeline to compute and persist an ownership-evidence signal (matched / unmatched / no_evidence) for package→repo links, and to apply the corresponding declared-link score penalties via a widened package_repo_confidence() function. It also adds per-batch ingest counters and documents the design in ADR-0022.
Changes:
- Add
ownership_matchhandling end-to-end: writer computation inpackages_worker, persistence inpackage_repos, and conflict-resolution support in the DAL. - Update confidence scoring: new
package_repo_confidence()signature includes ownership evidence and applies declared-only penalties; deps.dev ingestion adds a rescore pass for cross-chunk competing-GitHub cases. - Add tests (Vitest for matcher + DAL scoring/integration updates) and document the decision (ADR-0022).
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| services/libs/data-access-layer/src/packages/repos.ts | Upserts now persist ownership_match and score via updated confidence call. |
| services/libs/data-access-layer/src/packages/repoConfidenceScoring.integration.test.ts | Updates integration scoring tests for new function signature and ownership penalties. |
| services/libs/data-access-layer/src/packages/repoConfidence.ts | Adds PackageRepoOwnershipMatch, parameter plumbing, and conflict-update handling. |
| services/libs/data-access-layer/src/packages/repoConfidence.test.ts | Updates unit tests for new claim defaults and SQL call generation. |
| services/libs/data-access-layer/src/osspckgs/types.ts | Adds note pointing to the new claim/scoring types location. |
| services/libs/data-access-layer/src/osspckgs/sqlFragments.ts | Updates best-repo-link ordering comment for confidence offset provenance. |
| services/apps/packages_worker/src/utils/ownershipMatch.ts | Implements ownership matching + counters and repo-owner extraction. |
| services/apps/packages_worker/src/utils/tests/ownershipMatch.test.ts | Adds unit tests for ownership matching and repo-owner extraction. |
| services/apps/packages_worker/src/rubygems/types.ts | Extends batch result shape to include declared ownership counters; adds authors field. |
| services/apps/packages_worker/src/rubygems/runRubyGemsCriticalLoop.ts | Initializes batch counters for RubyGems critical loop results. |
| services/apps/packages_worker/src/rubygems/runRubyGemsCoreLoop.ts | Computes ownership match from authors + repo owner; bumps counters per processed package. |
| services/apps/packages_worker/src/rubygems/normalize.ts | Parses authors into a normalized string array for ownership evidence. |
| services/apps/packages_worker/src/pypi/upsertProject.ts | Computes ownership match from maintainers vs repo owner and persists it on link upsert. |
| services/apps/packages_worker/src/pypi/activities.ts | Returns ownership match from ingest and logs per-batch counters. |
| services/apps/packages_worker/src/packagist/upsertPackageInfo.ts | Computes ownership match (vendor/maintainers vs repo owner) and persists it. |
| services/apps/packages_worker/src/packagist/activities.ts | Threads ownership match through ingest path and logs per-batch counters. |
| services/apps/packages_worker/src/packagist/tests/persistPackageInfo.test.ts | Updates unit tests to expect ownershipMatch persisted on repo link upserts. |
| services/apps/packages_worker/src/packagist/tests/ingest.test.ts | Updates mocks/expectations for new return shape including ownership match. |
| services/apps/packages_worker/src/nuget/types.ts | Extends NuGet batch result to include declared ownership counters. |
| services/apps/packages_worker/src/nuget/runNuGetEnrichmentLoop.ts | Computes ownership match (owners/authors vs repo owner), persists it, bumps counters. |
| services/apps/packages_worker/src/npm/upsertPackage.ts | Computes ownership match (scope/maintainers vs repo owner) and persists it. |
| services/apps/packages_worker/src/npm/activities.ts | Returns ownership match from ingest and logs per-batch counters. |
| services/apps/packages_worker/src/maven/runMavenEnrichmentLoop.ts | Computes ownership match from groupId + dev usernames, persists it, aggregates counters. |
| services/apps/packages_worker/src/go/activities.ts | Adds Go-specific owner extraction (module-path host gate + repo-owner fallback) and counters. |
| services/apps/packages_worker/src/deps-dev/workflows/ingestRepos.ts | Adds final-chunk rescore of non-GitHub links once competing GitHub repos exist. |
| services/apps/packages_worker/src/cargo/types.ts | Extends Cargo enrichment result to include declared ownership counters. |
| services/apps/packages_worker/src/cargo/normalizeRepos.ts | Carries repo owner in staging to support SQL-side matcher. |
| services/apps/packages_worker/src/cargo/enrich.ts | Uses SQL matcher to set ownership_match, returns ownership counts. |
| docs/adr/README.md | Adds ADR-0022 to the index table. |
| docs/adr/0022-package-repo-ownership-evidence.md | Documents the ownership-evidence design, normalization rules, and per-ecosystem evidence. |
| backend/src/osspckgs/migrations/V1788393600__package_repo_owner_match.sql | Adds ownership_match column and SQL normalizer/matcher functions for Cargo pipeline parity. |
| backend/src/osspckgs/migrations/V1788393601__no_evidence_ownership_penalty.sql | Widens package_repo_confidence() to include ownership evidence and updates rescore procedure. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…osystems (CM-1394) Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
fb76cd7 to
6f6a6db
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6f6a6db. Configure here.
Fixes the DROP FUNCTION dependency failure (9-arg compat overload from V1788307300 still referenced the 10-arg signature), restores a rolling-deploy compat overload for the dropped 10-arg signature, restores the verified_at monotonic bump in both rescore paths so Tinybird's ReplacingMergeTree doesn't drop concurrent updates, adds ownership_match to the Tinybird packageRepos datasource and to the upsertPackageRepo audit diff, stops RubyGems from feeding free-text author names into ownership matching (ADR-0022 says that loop stays no_evidence), and fixes a stale migration reference in a comment. Also fixes prettier formatting drift in npm/pypi/packagist writers and a forbidden non-null assertion in ownershipMatch.ts that were failing the lint-format-services CI check. Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
Previously missed (3) — in code that hasn't changed since the last review.
services/apps/packages_worker/src/maven/runMavenEnrichmentLoop.ts:30
OwnershipEvidenceis a type-only symbol, but it’s imported via a value import. If the TS build preserves value imports, this can trigger a runtime ESM error (missing named export). Split this into animport typeforOwnershipEvidenceand a value import for the functions.
services/apps/packages_worker/src/nuget/types.ts:2- These imports are only used as types (interface extension and type annotations). Using value imports can cause runtime ESM errors if the compiler preserves them (e.g. “module ... does not provide an export named ...”). Switch to
import typefor both.
services/apps/packages_worker/src/rubygems/types.ts:2 - These imports are only used as types (interface extension and type annotations). Using value imports can cause runtime ESM errors if the compiler preserves them (e.g. “module ... does not provide an export named ...”). Switch to
import typefor both.
|
|
||
| describe('packageRepoLinkClaimParams', () => { | ||
| it('defaults provenance and signal for claims that carry neither', () => { | ||
| it('defaults the signals CM-1393 and CM-1394 have not started writing yet', () => { |

Summary
Stacked on #4570 (CM-1393) — review only the CM-1394 commits on top.