@@ -1828,7 +1828,7 @@ describe("httpApiV1 handlers", () => {
18281828 expect ( response . status ) . toBe ( 200 ) ;
18291829 const json = await response . json ( ) ;
18301830 expect ( json . version . security . status ) . toBe ( "pending" ) ;
1831- expect ( json . version . security . scanners . vt . normalizedStatus ) . toBe ( "suspicious " ) ;
1831+ expect ( json . version . security . scanners . vt . normalizedStatus ) . toBe ( "review " ) ;
18321832 expect ( json . version . security . virustotalUrl ) . toContain ( "virustotal.com/gui/file/" ) ;
18331833 } ) ;
18341834
@@ -1880,12 +1880,12 @@ describe("httpApiV1 handlers", () => {
18801880 expect ( json . version . security . status ) . toBe ( "clean" ) ;
18811881 expect ( json . version . security . hasWarnings ) . toBe ( false ) ;
18821882 expect ( json . version . security . hasScanResult ) . toBe ( true ) ;
1883- expect ( json . version . security . scanners . static . normalizedStatus ) . toBe ( "pending " ) ;
1883+ expect ( json . version . security . scanners . static . normalizedStatus ) . toBe ( "review " ) ;
18841884 expect ( json . version . security . scanners . vt . normalizedStatus ) . toBe ( "clean" ) ;
18851885 expect ( json . version . security . scanners . llm . normalizedStatus ) . toBe ( "clean" ) ;
18861886 } ) ;
18871887
1888- it ( "lets static-scan malicious status dominate benign vt and llm results " , async ( ) => {
1888+ it ( "keeps static-scan malicious status advisory when ClawScan is clean " , async ( ) => {
18891889 const runQuery = vi . fn ( async ( _query : unknown , args : Record < string , unknown > ) => {
18901890 if ( "slug" in args ) {
18911891 return {
@@ -1918,6 +1918,8 @@ describe("httpApiV1 handlers", () => {
19181918 verdict : "benign" ,
19191919 checkedAt : 222 ,
19201920 } ,
1921+ clawScanVerdict : "clean" ,
1922+ clawScanState : "complete" ,
19211923 files : [ ] ,
19221924 } ;
19231925 }
@@ -1930,13 +1932,93 @@ describe("httpApiV1 handlers", () => {
19301932 ) ;
19311933 expect ( response . status ) . toBe ( 200 ) ;
19321934 const json = await response . json ( ) ;
1933- expect ( json . version . security . status ) . toBe ( "malicious " ) ;
1934- expect ( json . version . security . hasWarnings ) . toBe ( true ) ;
1935+ expect ( json . version . security . status ) . toBe ( "clean " ) ;
1936+ expect ( json . version . security . hasWarnings ) . toBe ( false ) ;
19351937 expect ( json . version . security . hasScanResult ) . toBe ( true ) ;
19361938 expect ( json . version . security . checkedAt ) . toBe ( 555 ) ;
19371939 expect ( json . version . security . scanners . static . normalizedStatus ) . toBe ( "malicious" ) ;
19381940 } ) ;
19391941
1942+ it ( "reports pending ClawScan state over stale completed scanner details" , async ( ) => {
1943+ const runQuery = vi . fn ( async ( _query : unknown , args : Record < string , unknown > ) => {
1944+ if ( "slug" in args ) {
1945+ return {
1946+ skill : { _id : "skills:1" , slug : "demo" , displayName : "Demo" } ,
1947+ latestVersion : null ,
1948+ owner : { handle : "owner" , displayName : "Owner" , image : null } ,
1949+ } ;
1950+ }
1951+ if ( "skillId" in args && "version" in args ) {
1952+ return {
1953+ version : "1.0.0" ,
1954+ createdAt : 1 ,
1955+ changelog : "c" ,
1956+ changelogSource : "auto" ,
1957+ sha256hash : "a" . repeat ( 64 ) ,
1958+ clawScanVerdict : "clean" ,
1959+ clawScanState : "running" ,
1960+ llmAnalysis : {
1961+ status : "completed" ,
1962+ verdict : "benign" ,
1963+ checkedAt : 222 ,
1964+ } ,
1965+ files : [ ] ,
1966+ } ;
1967+ }
1968+ return null ;
1969+ } ) ;
1970+ const runMutation = vi . fn ( ) . mockResolvedValue ( okRate ( ) ) ;
1971+ const response = await __handlers . skillsGetRouterV1Handler (
1972+ makeCtx ( { runQuery, runMutation } ) ,
1973+ new Request ( "https://example.com/api/v1/skills/demo/versions/1.0.0" ) ,
1974+ ) ;
1975+ expect ( response . status ) . toBe ( 200 ) ;
1976+ const json = await response . json ( ) ;
1977+ expect ( json . version . security . status ) . toBe ( "pending" ) ;
1978+ expect ( json . version . security . hasScanResult ) . toBe ( false ) ;
1979+ expect ( json . version . security . scanners . llm . normalizedStatus ) . toBe ( "clean" ) ;
1980+ } ) ;
1981+
1982+ it ( "keeps malicious ClawScan verdict authoritative during rescans" , async ( ) => {
1983+ const runQuery = vi . fn ( async ( _query : unknown , args : Record < string , unknown > ) => {
1984+ if ( "slug" in args ) {
1985+ return {
1986+ skill : { _id : "skills:1" , slug : "demo" , displayName : "Demo" } ,
1987+ latestVersion : null ,
1988+ owner : { handle : "owner" , displayName : "Owner" , image : null } ,
1989+ } ;
1990+ }
1991+ if ( "skillId" in args && "version" in args ) {
1992+ return {
1993+ version : "1.0.0" ,
1994+ createdAt : 1 ,
1995+ changelog : "c" ,
1996+ changelogSource : "auto" ,
1997+ sha256hash : "a" . repeat ( 64 ) ,
1998+ clawScanVerdict : "malicious" ,
1999+ clawScanState : "running" ,
2000+ llmAnalysis : {
2001+ status : "malicious" ,
2002+ verdict : "malicious" ,
2003+ checkedAt : 222 ,
2004+ } ,
2005+ files : [ ] ,
2006+ } ;
2007+ }
2008+ return null ;
2009+ } ) ;
2010+ const runMutation = vi . fn ( ) . mockResolvedValue ( okRate ( ) ) ;
2011+ const response = await __handlers . skillsGetRouterV1Handler (
2012+ makeCtx ( { runQuery, runMutation } ) ,
2013+ new Request ( "https://example.com/api/v1/skills/demo/versions/1.0.0" ) ,
2014+ ) ;
2015+ expect ( response . status ) . toBe ( 200 ) ;
2016+ const json = await response . json ( ) ;
2017+ expect ( json . version . security . status ) . toBe ( "malicious" ) ;
2018+ expect ( json . version . security . hasWarnings ) . toBe ( true ) ;
2019+ expect ( json . version . security . hasScanResult ) . toBe ( true ) ;
2020+ } ) ;
2021+
19402022 it ( "does not treat a static scan by itself as a definitive scan result" , async ( ) => {
19412023 const runQuery = vi . fn ( async ( _query : unknown , args : Record < string , unknown > ) => {
19422024 if ( "slug" in args ) {
@@ -1975,7 +2057,7 @@ describe("httpApiV1 handlers", () => {
19752057 expect ( json . version . security . hasWarnings ) . toBe ( false ) ;
19762058 expect ( json . version . security . hasScanResult ) . toBe ( false ) ;
19772059 expect ( json . version . security . virustotalUrl ) . toBeNull ( ) ;
1978- expect ( json . version . security . scanners . static . normalizedStatus ) . toBe ( "pending " ) ;
2060+ expect ( json . version . security . scanners . static . normalizedStatus ) . toBe ( "clean " ) ;
19792061 expect ( json . version . security . scanners . vt ) . toBeNull ( ) ;
19802062 expect ( json . version . security . scanners . llm ) . toBeNull ( ) ;
19812063 } ) ;
@@ -2078,7 +2160,7 @@ describe("httpApiV1 handlers", () => {
20782160 ) ;
20792161 expect ( response . status ) . toBe ( 200 ) ;
20802162 const json = await response . json ( ) ;
2081- expect ( json . security . status ) . toBe ( "suspicious " ) ;
2163+ expect ( json . security . status ) . toBe ( "review " ) ;
20822164 expect ( json . security . hasScanResult ) . toBe ( true ) ;
20832165 expect ( json . security . capabilityTags ) . toEqual ( [
20842166 "crypto" ,
@@ -2311,7 +2393,7 @@ describe("httpApiV1 handlers", () => {
23112393 expect ( response . status ) . toBe ( 200 ) ;
23122394 const json = await response . json ( ) ;
23132395 expect ( json . version . version ) . toBe ( "1.0.0" ) ;
2314- expect ( json . security . status ) . toBe ( "suspicious " ) ;
2396+ expect ( json . security . status ) . toBe ( "review " ) ;
23152397 expect ( json . moderation . scope ) . toBe ( "skill" ) ;
23162398 expect ( json . moderation . sourceVersion ) . toEqual ( {
23172399 version : "2.0.0" ,
@@ -5355,6 +5437,8 @@ describe("httpApiV1 handlers", () => {
53555437 {
53565438 name : "malicious" ,
53575439 release : {
5440+ clawScanVerdict : "malicious" ,
5441+ clawScanState : "complete" ,
53585442 staticScan : {
53595443 status : "malicious" ,
53605444 reasonCodes : [ "malicious.test" ] ,
@@ -7156,6 +7240,8 @@ describe("httpApiV1 handlers", () => {
71567240 version : "1.0.0" ,
71577241 createdAt : 1 ,
71587242 changelog : "init" ,
7243+ clawScanVerdict : "malicious" ,
7244+ clawScanState : "complete" ,
71597245 verification : { scanStatus : "malicious" } ,
71607246 files : [
71617247 {
0 commit comments