@@ -52,6 +52,16 @@ describe("extractSubmittedSourceUrls", () => {
5252 expect ( urls ) . toHaveLength ( 0 ) ;
5353 } ) ;
5454
55+ it ( "drops a site-relative snake_case download_url the same way as downloadUrl (#7446)" , ( ) => {
56+ // Before #7446, distributionSourceFields was camelCase-only, so download_url:/… stayed in the
57+ // extracted set, was classified as canonical, and produced a spurious invalid_url hard failure.
58+ expect ( extractSubmittedSourceUrls ( mdx ( { download_url : "/downloads/skills/foo.zip" } ) ) ) . toHaveLength ( 0 ) ;
59+ expect ( extractSubmittedSourceUrls ( mdx ( { package_url : "/packages/foo.tgz" } ) ) ) . toHaveLength ( 0 ) ;
60+ for ( const field of [ "download_url" , "package_url" ] ) {
61+ expect ( AWESOME_CLAUDE_CONTENT_SPEC . distributionSourceFields . has ( field ) ) . toBe ( true ) ;
62+ }
63+ } ) ;
64+
5565 it ( "reads snake_case source fields (e.g. the canonical source_url), matching urlFields (#7250)" , ( ) => {
5666 // Before #7250, sourceUrlFields listed only the camelCase names, so a legitimately-aliased snake_case field
5767 // was invisible to the source-evidence gate even though duplicates.ts (which reads urlFields) saw it.
@@ -816,6 +826,25 @@ describe("downgrade rules (hasVerifiableCanonicalSource / isDowngradableInconclu
816826 expect ( primary ?. blocking ) . toBe ( true ) ;
817827 expect ( report . status ) . toBe ( "retryable" ) ;
818828 } ) ;
829+
830+ it ( "does NOT downgrade a snake_case PRIMARY-field retryable either (#7446)" , async ( ) => {
831+ // Before #7446, primaryCanonicalSourceFields was camelCase-only, so a retryable source_url was
832+ // treated as non-primary and silently downgraded whenever another canonical was reachable.
833+ const src = mdx ( {
834+ githubUrl : "https://github.com/acme/anchor" ,
835+ source_url : "https://flaky.example/primary-snake" ,
836+ } ) ;
837+ const report = await checkSubmittedSourceEvidence (
838+ src ,
839+ fakeFetch ( { "https://github.com/acme/anchor" : 200 , "https://flaky.example/primary-snake" : 503 } ) ,
840+ ) ;
841+ const primary = report . urls . find ( ( u ) => u . field === "source_url" ) ;
842+ expect ( primary ?. blocking ) . toBe ( true ) ;
843+ expect ( report . status ) . toBe ( "retryable" ) ;
844+ for ( const field of [ "github_url" , "repo_url" , "repository_url" , "source_url" ] ) {
845+ expect ( AWESOME_CLAUDE_CONTENT_SPEC . primaryCanonicalSourceFields . has ( field ) ) . toBe ( true ) ;
846+ }
847+ } ) ;
819848} ) ;
820849
821850// ── summary / decision string branches ───────────────────────────────────────────────────────────
0 commit comments