Skip to content

fix(content-lane): distributionSourceFields and primaryCanonicalSourceFields omit snake_case aliases, causing wrong source-evidence verdicts #7446

Description

@JSONbored

Context

packages/loopover-engine/src/review/content-lane/content-repo-spec.ts defines
distributionSourceFields (line 122, currently ["downloadUrl", "packageUrl"]) and
primaryCanonicalSourceFields (line 139, currently ["githubUrl", "repoUrl", "repositoryUrl", "sourceUrl"]) — both camelCase-only, unlike the sibling urlFields/sourceUrlFields (the latter
fixed in #7250 for this exact reason) which pair every field with its snake_case alias.

src/review/content-lane/source-evidence.ts reads both sets by exact field-name match
(spec.distributionSourceFields.has(item.field) at lines 241/250; spec.primaryCanonicalSourceFields.has(item.field)
at lines 465/470/552). A submission using the snake_case convention for a distribution or primary
canonical field (download_url, package_url, github_url, repo_url, repository_url,
source_url) is invisible to these checks:

  • A snake_case download_url/package_url distribution URL that's site-relative is
    misclassified as a plain "canonical" source instead of "distribution", producing a spurious
    invalid_url hard-failure finding that routes an otherwise-valid submission to manual review.
  • A snake_case github_url/repo_url/repository_url/source_url that transiently fails
    (retryable) is silently downgraded to non-blocking by isDowngradableInconclusiveSource, when
    the identical camelCase-keyed field would correctly stay blocking as a primary canonical source.

Concrete failure scenario 1 (distributionSourceFields): an entry submits
download_url: /downloads/skills/foo.zip — a site-relative build artifact, exactly the case
source-evidence.ts's own surrounding comment calls out ("the build's own generated artifact...
not external provenance and not fetchable as written"). Because
distributionSourceFields.has("download_url") is false, the drop-if-relative filter never fires
for it, and sourceRole() fails to classify it "distribution", falling through to the generic
"canonical" default. The relative path then reaches validateFetchableSourceUrl, new URL()
throws, and it comes back as a "canonical" hard_failure (invalid_url) — a spurious
source-evidence hit that routes a perfectly valid submission to manual review purely because it used
the snake_case field name. The byte-identical submission using downloadUrl: is silently and
correctly dropped with no finding at all.

Concrete failure scenario 2 (primaryCanonicalSourceFields): an entry declares
source_url: https://github.com/acme/x (snake_case — per #7250's own issue text, "the canonical
field name contributors are told to use") and that URL transiently 500s/429s/times out
(status: "retryable"). In isDowngradableInconclusiveSource (source-evidence.ts:470),
!spec.primaryCanonicalSourceFields.has("source_url") is true, so this item silently downgrades
to non-blocking whenever any other canonical source is reachable elsewhere. The equivalent
sourceUrl: (camelCase) submission would not downgrade — it stays blocking, per this field's
intended "primary, never silently waived" status. Same content, different (and less rigorous)
verification outcome, purely based on naming convention. The same gap also makes
hasVerifiableCanonicalSource (:465) require two reachable canonical sources for a
snake_case-keyed submission where one would suffice for its camelCase twin, and affects the
blocking-role check at :552.

Requirements

  • distributionSourceFields must include download_url and package_url alongside the existing
    downloadUrl/packageUrl.
  • primaryCanonicalSourceFields must include github_url, repo_url, repository_url, and
    source_url alongside the existing camelCase members.
  • Do not change source-evidence.ts's consuming logic — this is a data-only addition to the two
    spec constants, matching content-repo-spec's sourceUrlFields omits the snake_case aliases its sibling urlFields already has #7250's scope boundary ("data-fix to the spec constant only, not a
    behavior change to either consumer's logic").
  • The fix must land in packages/loopover-engine/src/review/content-lane/content-repo-spec.ts (the
    real implementation); src/review/content-lane/content-repo-spec.ts is a re-export shim and
    needs no separate edit.

Deliverables

  • distributionSourceFields extended with download_url, package_url
  • primaryCanonicalSourceFields extended with github_url, repo_url, repository_url, source_url
  • Regression test: a manifest entry with a site-relative download_url: value is now classified
    "distribution" and dropped (no finding), matching the equivalent downloadUrl: entry's
    existing behavior
  • Regression test: a manifest entry with a retryable source_url: (snake_case) does NOT get
    silently downgraded by isDowngradableInconclusiveSource when it's the only canonical
    source, matching the equivalent sourceUrl: entry's existing (non-downgraded) behavior

Test Coverage Requirements

This repo's Codecov patch gate is 99%+ hard (branch-counted) on every changed line/branch in
src/**/packages/**. Both regression tests must exercise the real source-evidence.ts functions
(sourceRole/the drop-if-relative filter, and isDowngradableInconclusiveSource) against the fix,
not just assert on the raw Set contents.

Expected Outcome

A submission's distribution/primary-canonical source fields are recognized consistently regardless
of whether they're written in camelCase or the equally-legitimate snake_case convention — no more
naming-convention-dependent source-evidence verdicts.

Links & Resources

packages/loopover-engine/src/review/content-lane/content-repo-spec.ts:122 (distributionSourceFields),
:139 (primaryCanonicalSourceFields), :99 (sourceUrlFields, the already-fixed sibling to
mirror). src/review/content-lane/source-evidence.ts:241,250 (distributionSourceFields consumers),
:465,470,552 (primaryCanonicalSourceFields consumers). Issue #7250 / PR #7269 (the identical
fix already applied to sourceUrlFields).

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions