Repository: stoplightio/spectral
Pull request #285 (2019-07-03 15:18:59)

feat(rulesets): renamed enabled to recommended
### Please check if the PR fulfills these requirements
- [x] Tests for the changes have been added (for bug fixes / features)
- [x] Docs have been added / updated (for bug fixes / features)

### What kind of change does this PR introduce?

This is sort of a feature but not really a useful one just yet.

### If this is a feature change, what is the new behavior?

This change is just to clear the way for more functionality in the near future. We want to support some advanced features on extending rulesets, one of which is taking only the recommended rules, or you can chose to take eeeeverything. Similar to eslint.

### Does this PR introduce a breaking change?

if you were using `enabled: true/false` in your ruleset files, change it to `recommended: true/false`. The defaults have not changed, so if you were not using the keyword the status of that rule has not changed.



Patch:
diff --git a/docs/rulesets.md b/docs/rulesets.md
index 094a0a3e..805c0819 100644
--- a/docs/rulesets.md
+++ b/docs/rulesets.md
@@ -82,7 +82,7 @@ Rules are highly configurable. There are only few required parameters but the op
       <td>Tags attached to the rule, which can be used for organizational purposes</td>
     </tr>
     <tr>
-      <td>enabled</td>
+      <td>recommended</td>
       <td><code>boolean</code></td>
       <td>should the rule be enabled by default?</td>
     </tr>        
diff --git a/src/meta/rule.schema.json b/src/meta/rule.schema.json
index c9a5f869..d4d119de 100644
--- a/src/meta/rule.schema.json
+++ b/src/meta/rule.schema.json
@@ -30,7 +30,7 @@
         "description": {
             "type": "string"
         },
-        "enabled": {
+        "recommended": {
             "type": "boolean"
         },
         "given": {
@@ -95,4 +95,3 @@
     ],
     "type": "object"
 }
-
diff --git a/src/rulesets/oas/ruleset.json b/src/rulesets/oas/ruleset.json
index 35cdb72a..af35c1c1 100644
--- a/src/rulesets/oas/ruleset.json
+++ b/src/rulesets/oas/ruleset.json
@@ -2,6 +2,7 @@
   "rules": {
     "operation-2xx-response": {
       "summary": "Operation must have at least one `2xx` response.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -14,6 +15,7 @@
     },
     "operation-formData-consume-check": {
       "summary": "Operations with an `in: formData` parameter must include `application/x-www-form-urlencoded` or `multipart/form-data` in their `consumes` property.",
+      "recommended": true,
       "type": "validation",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -25,6 +27,7 @@
     },
     "operation-operationId-unique": {
       "summary": "Every operation must have a unique `operationId`.",
+      "recommended": true,
       "type": "validation",
       "severity": 0,
       "given": "$",
@@ -37,6 +40,7 @@
     },
     "operation-parameters": {
       "summary": "Operation parameters are unique and non-repeating.",
+      "recommended": true,
       "type": "validation",
       "given": "$",
       "then": {
@@ -51,6 +55,7 @@
       "message": "{{error}}",
       "type": "validation",
       "severity": 0,
+      "recommended": true,
       "given": "$",
       "then": {
         "function": "oasPathParam"
@@ -60,8 +65,8 @@
       ]
     },
     "contact-properties": {
-      "enabled": false,
       "summary": "Contact object should have `name`, `url` and `email`.",
+      "recommended": false,
       "type": "style",
       "given": "$.info.contact",
       "then": [
@@ -83,8 +88,8 @@
       ]
     },
     "example-value-or-externalValue": {
-      "enabled": false,
       "summary": "Example should have either a `value` or `externalValue` field.",
+      "recommended": false,
       "type": "style",
       "given": "$..example",
       "then": {
@@ -99,6 +104,7 @@
     },
     "info-contact": {
       "summary": "Info object should contain `contact` object.",
+      "recommended": true,
       "type": "style",
       "given": "$",
       "then": {
@@ -111,6 +117,7 @@
     },
     "info-description": {
       "summary": "OpenAPI object info `description` must be present and non-empty string.",
+      "recommended": true,
       "type": "style",
       "given": "$",
       "then": {
@@ -122,8 +129,8 @@
       ]
     },
     "info-license": {
-      "enabled": false,
       "summary": "OpenAPI object info `license` must be present and non-empty string.",
+      "recommended": false,
       "type": "style",
       "given": "$",
       "then": {
@@ -135,8 +142,8 @@
       ]
     },
     "license-url": {
-      "enabled": false,
       "summary": "License object should include `url`.",
+      "recommended": false,
       "type": "style",
       "given": "$",
       "then": {
@@ -148,8 +155,8 @@
       ]
     },
     "no-eval-in-markdown": {
-      "enabled": false,
       "summary": "Markdown descriptions should not contain `eval(`.",
+      "recommended": false,
       "type": "style",
       "given": "$..*",
       "then": [
@@ -171,6 +178,7 @@
     },
     "no-script-tags-in-markdown": {
       "summary": "Markdown descriptions should not contain `<script>` tags.",
+      "recommended": true,
       "type": "style",
       "given": "$..*",
       "then": [
@@ -191,8 +199,8 @@
       ]
     },
     "only-local-references": {
-      "enabled": false,
       "summary": "References should start with `#/`.",
+      "recommended": false,
       "type": "style",
       "given": "$..['$ref']",
       "then": {
@@ -206,8 +214,8 @@
       ]
     },
     "openapi-tags-alphabetical": {
-      "enabled": false,
       "summary": "OpenAPI object should have alphabetical `tags`.",
+      "recommended": false,
       "type": "style",
       "given": "$",
       "then": {
@@ -222,8 +230,8 @@
       ]
     },
     "openapi-tags": {
-      "enabled": false,
       "summary": "OpenAPI object should have non-empty `tags` array.",
+      "recommended": false,
       "type": "style",
       "given": "$",
       "then": {
@@ -235,8 +243,8 @@
       ]
     },
     "operation-default-response": {
-      "enabled": false,
       "summary": "Operations must have a default response.",
+      "recommended": false,
       "type": "style",
       "given": "$..paths.*.*.responses",
       "then": {
@@ -249,6 +257,7 @@
     },
     "operation-description": {
       "summary": "Operation `description` must be present and non-empty string.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -261,6 +270,7 @@
     },
     "operation-operationId": {
       "summary": "Operation should have an `operationId`.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -273,6 +283,7 @@
     },
     "operation-operationId-valid-in-url": {
       "summary": "operationId may only use characters that are valid when used in a URL.",
+      "recommended": true,
       "type": "validation",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -287,8 +298,8 @@
       ]
     },
     "operation-singular-tag": {
-      "enabled": false,
       "summary": "Operation may only have one tag.",
+      "recommended": false,
       "type": "style",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -303,8 +314,8 @@
       ]
     },
     "operation-summary-formatted": {
-      "enabled": false,
       "summary": "Operation `summary` should start with upper case and end with a dot.",
+      "recommended": false,
       "type": "style",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -320,6 +331,7 @@
     },
     "operation-tags": {
       "summary": "Operation should have non-empty `tags` array.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths.*[?( @property === 'get' || @property === 'put' || @property === 'post' || @property === 'delete' || @property === 'options' || @property === 'head' || @property === 'patch' || @property === 'trace' )]",
       "then": {
@@ -331,8 +343,8 @@
       ]
     },
     "parameter-description": {
-      "enabled": false,
       "summary": "Parameter objects should have a `description`.",
+      "recommended": false,
       "type": "style",
       "given": "$..parameters[*]",
       "when": {
@@ -349,6 +361,7 @@
     },
     "path-declarations-must-exist": {
       "summary": "given declarations cannot be empty, ex.`/given/{}` is invalid.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths",
       "then": {
@@ -364,6 +377,7 @@
     },
     "path-keys-no-trailing-slash": {
       "summary": "given keys should not end with a slash.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths",
       "then": {
@@ -379,6 +393,7 @@
     },
     "path-not-include-query": {
       "summary": "given keys should not include a query string.",
+      "recommended": true,
       "type": "style",
       "given": "$..paths",
       "then": {
@@ -393,8 +408,8 @@
       ]
     },
     "tag-description": {
-      "enabled": false,
       "summary": "Tag object should have a `description`.",
+      "recommended": false,
       "type": "style",
       "given": "$.tags[*]",
       "then": {
diff --git a/src/rulesets/oas2/ruleset.json b/src/rulesets/oas2/ruleset.json
index 417d151b..4bd9527e 100644
--- a/src/rulesets/oas2/ruleset.json
+++ b/src/rulesets/oas2/ruleset.json
@@ -8,6 +8,7 @@
       "message": "{{error}}",
       "type": "validation",
       "severity": 0,
+      "recommended": true,
       "given": "$",
       "then": {
         "function": "schema",
@@ -1641,6 +1642,7 @@
     },
     "api-host": {
       "summary": "OpenAPI `host` must be present and non-empty string.",
+      "recommended": true,
       "type": "style",
       "given": "$",
       "then": {
@@ -1653,6 +1655,7 @@
     },
     "api-schemes": {
       "summary": "OpenAPI host `schemes` must be present and non-empty array.",
+      "recommended": true,
       "type": "style",
       "given": "$",
       "then": {
@@ -1673,8 +1676,8 @@
       ]
     },
     "host-not-example": {
-      "enabled": false,
       "summary": "Server URL should not point at `example.com`.",
+      "recommended": false,
       "type": "style",
       "given": "$",
       "then": {
@@ -1687,6 +1690,7 @@
     },
     "host-trailing-slash": {
       "summary": "Server URL should not have a trailing slash.",
+      "recommended": true,
       "type": "style",
       "given": "$",
       "then": {
@@ -1698,8 +1702,8 @@
       }
     },
     "model-description": {
-      "enabled": false,
       "summary": "Definition `description` must be present and non-empty string.",
+      "recommended": false,
       "type": "style",
       "given": "$..definitions[*]",
       "then": {
@@ -1709,6 +1713,7 @@
     },
     "operation-security-defined": {
       "summary": "Operation `security` values must match a scheme defined in the `securityDefinitions` object.",
+      "recommended": true,
       "type": "validation",
       "given": "$",
       "then": {
@@ -1726,6 +1731,7 @@
     "valid-example": {
       "summary": "Examples must be valid against their defined schema.",
       "message": "\"{{property}}\" property {{error}}",
+      "recommended": true,
       "type": "validation",
       "given": "$..[?(@.example)]",
       "then": {
diff --git a/src/rulesets/oas3/ruleset.json b/src/rulesets/oas3/ruleset.json
index ceeb9f7c..26020ffc 100644
--- a/src/rulesets/oas3/ruleset.json
+++ b/src/rulesets/oas3/ruleset.json
@@ -8,6 +8,7 @@
       "message": "{{error}}",
       "type": "validation",
       "severity": 0,
+      "recommended": true,
       "given": "$",
       "then": {
         "function": "schema",
@@ -2317,6 +2318,7 @@
     },
     "api-servers": {
       "summary": "OpenAPI `servers` must be present and non-empty array.",
+      "recommended": true,
       "type": "style",
       "given": "$",
       "then": {
@@ -2337,8 +2339,8 @@
       ]
     },
     "model-description": {
-      "enabled": false,
       "summary": "Model `description` must be present and non-empty string.",
+      "recommended": false,
       "type": "style",
       "given": "$.components.schemas[*]",
       "then": {
@@ -2348,6 +2350,7 @@
     },
     "operation-security-defined": {
       "summary": "Operation `security` values must match a scheme defined in the `components.securitySchemes` object.",
+      "recommended": true,
       "type": "validation",
       "given": "$",
       "then": {
@@ -2364,8 +2367,8 @@
       ]
     },
     "server-not-example.com": {
-      "enabled": false,
       "summary": "Server URL should not point at `example.com`.",
+      "recommended": false,
       "type": "style",
       "given": "$.servers[*]",
       "then": {
@@ -2378,6 +2381,7 @@
     },
     "server-trailing-slash": {
       "summary": "Server URL should not have a trailing slash.",
+      "recommended": true,
       "type": "style",
       "given": "$.servers[*]",
       "then": {
@@ -2391,6 +2395,7 @@
     "valid-example": {
       "summary": "Examples must be valid against their defined schema.",
       "message": "\"{{property}}\" property {{error}}",
+      "recommended": true,
       "type": "validation",
       "given": "$..[?(@.example)]",
       "then": {
diff --git a/src/runner.ts b/src/runner.ts
index 0a4f48d8..8b974e22 100644
--- a/src/runner.ts
+++ b/src/runner.ts
@@ -18,7 +18,7 @@ export const runRules = (
     const rule = rules[name];
     if (!rule) continue;
 
-    if (rule.hasOwnProperty('enabled') && !rule.enabled) {
+    if (rule.hasOwnProperty('recommended') && !rule.recommended) {
       continue;
     }
 
diff --git a/src/spectral.ts b/src/spectral.ts
index 6b7dbe05..5068aece 100644
--- a/src/spectral.ts
+++ b/src/spectral.ts
@@ -155,7 +155,7 @@ export class Spectral {
       const rule = this.rules[ruleName];
       if (rule) {
         if (typeof declaration === 'boolean') {
-          this._rules[ruleName].enabled = declaration;
+          this._rules[ruleName].recommended = declaration;
         }
       }
     }
diff --git a/src/types/rule.ts b/src/types/rule.ts
index d031c019..4638f7eb 100644
--- a/src/types/rule.ts
+++ b/src/types/rule.ts
@@ -21,8 +21,8 @@ export interface IRule<T = string, O = any> {
   // Tags attached to the rule, which can be used for organizational purposes
   tags?: string[];
 
-  // should the rule be enabled by default?
-  enabled?: boolean;
+  // some rules are more important than others, recommended rules will be enabled by default
+  recommended?: boolean;
 
   // Filter the target down to a subset[] with a JSON path
   given: string;


Test patch:
diff --git a/src/__tests__/spectral.test.ts b/src/__tests__/spectral.test.ts
index 6d923529..6dc346e2 100644
--- a/src/__tests__/spectral.test.ts
+++ b/src/__tests__/spectral.test.ts
@@ -72,7 +72,7 @@ describe('spectral', () => {
 
   describe('addRuleDeclarations', () => {
     describe('boolean value', () => {
-      test('should update the name rule enabled property', () => {
+      test('should update the name rule recommended property', () => {
         const s = new Spectral();
 
         s.addRules({
@@ -80,7 +80,7 @@ describe('spectral', () => {
           rule1: {
             summary: '',
             given: '$',
-            enabled: false,
+            recommended: false,
             then: {
               function: RuleFunction.TRUTHY,
             },
@@ -92,7 +92,7 @@ describe('spectral', () => {
         });
 
         expect(Object.keys(s.rules)).toEqual(['rule1']);
-        expect(s.rules.rule1.enabled).toBe(true);
+        expect(s.rules.rule1.recommended).toBe(true);
       });
     });
   });
diff --git a/src/rulesets/__tests__/reader.unit.ts b/src/rulesets/__tests__/reader.unit.ts
index afd9b8f8..98c5319b 100644
--- a/src/rulesets/__tests__/reader.unit.ts
+++ b/src/rulesets/__tests__/reader.unit.ts
@@ -19,7 +19,7 @@ const validateRulesetMock: jest.Mock = validateRuleset as jest.Mock;
 const resolvePathMock: jest.Mock = resolvePath as jest.Mock;
 
 const simpleRule: IRule = {
-  enabled: false,
+  recommended: false,
   given: 'abc',
   then: {
     function: 'f',
@@ -42,7 +42,7 @@ describe('reader', () => {
     });
 
     expect(await readRulesFromRulesets('flat-ruleset.yaml')).toEqual({
-      'rule-1': { given: 'abc', then: { function: 'f' }, enabled: false },
+      'rule-1': { given: 'abc', then: { function: 'f' }, recommended: false },
     });
   });
 
@@ -62,8 +62,8 @@ describe('reader', () => {
     });
 
     expect(await readRulesFromRulesets('flat-ruleset-a.yaml', 'flat-ruleset-b.yaml')).toEqual({
-      'rule-1': { given: 'abc', then: { function: 'f' }, enabled: false },
-      'rule-2': { given: 'abc', then: { function: 'f' }, enabled: false },
+      'rule-1': { given: 'abc', then: { function: 'f' }, recommended: false },
+      'rule-2': { given: 'abc', then: { function: 'f' }, recommended: false },
     });
   });
 
@@ -81,14 +81,14 @@ describe('reader', () => {
           'rule-1': {
             ...simpleRule,
             // note that i'm enabling the rule here
-            enabled: true,
+            recommended: true,
           },
         },
       },
     });
 
     expect(await readRulesFromRulesets('oneParentRuleset')).toEqual({
-      'rule-1': { given: 'abc', then: { function: 'f' }, enabled: true },
+      'rule-1': { given: 'abc', then: { function: 'f' }, recommended: true },
     });
   });
 
@@ -114,7 +114,7 @@ describe('reader', () => {
     });
 
     expect(await readRulesFromRulesets('oneParentRuleset')).toEqual({
-      'rule-1': { given: 'abc', then: { function: 'f' }, enabled: false },
+      'rule-1': { given: 'abc', then: { function: 'f' }, recommended: false },
       'rule-2': { given: 'another given', then: { function: 'b' } },
     });
   });
@@ -163,7 +163,7 @@ describe('reader', () => {
     });
 
     expect(await readRulesFromRulesets('oneParentRuleset')).toEqual({
-      'rule-1': { given: 'abc', then: { function: 'f' }, enabled: false },
+      'rule-1': { given: 'abc', then: { function: 'f' }, recommended: false },
       'rule-a': { given: 'given-a', then: { function: 'a' } },
       'rule-b': { given: 'given-b', then: { function: 'b' } },
       'common-rule': { given: 'common', then: { function: 'cb' } },
diff --git a/src/rulesets/oas/__tests__/contact-properties.ts b/src/rulesets/oas/__tests__/contact-properties.ts
index f8bef913..32b5736a 100644
--- a/src/rulesets/oas/__tests__/contact-properties.ts
+++ b/src/rulesets/oas/__tests__/contact-properties.ts
@@ -5,7 +5,7 @@ describe('contact-properties', () => {
   const s = new Spectral();
   s.addRules({
     'contact-properties': Object.assign(ruleset.rules['contact-properties'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['contact-properties'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/example-value-or-externalValue.ts b/src/rulesets/oas/__tests__/example-value-or-externalValue.ts
index 286f9673..54422296 100644
--- a/src/rulesets/oas/__tests__/example-value-or-externalValue.ts
+++ b/src/rulesets/oas/__tests__/example-value-or-externalValue.ts
@@ -5,7 +5,7 @@ describe('example-value-or-externalValue', () => {
   const s = new Spectral();
   s.addRules({
     'example-value-or-externalValue': Object.assign(ruleset.rules['example-value-or-externalValue'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['example-value-or-externalValue'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/info-contact.ts b/src/rulesets/oas/__tests__/info-contact.ts
index b73e75a8..7ff35f6c 100644
--- a/src/rulesets/oas/__tests__/info-contact.ts
+++ b/src/rulesets/oas/__tests__/info-contact.ts
@@ -5,7 +5,7 @@ describe('info-contact', () => {
   const s = new Spectral();
   s.addRules({
     'info-contact': Object.assign(ruleset.rules['info-contact'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['info-contact'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/info-description.ts b/src/rulesets/oas/__tests__/info-description.ts
index 67190b59..bf7769d0 100644
--- a/src/rulesets/oas/__tests__/info-description.ts
+++ b/src/rulesets/oas/__tests__/info-description.ts
@@ -5,7 +5,7 @@ describe('info-description', () => {
   const s = new Spectral();
   s.addRules({
     'info-description': Object.assign(ruleset.rules['info-description'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['info-description'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/info-license.ts b/src/rulesets/oas/__tests__/info-license.ts
index 20ce47c6..78dc3b96 100644
--- a/src/rulesets/oas/__tests__/info-license.ts
+++ b/src/rulesets/oas/__tests__/info-license.ts
@@ -5,7 +5,7 @@ describe('info-license', () => {
   const s = new Spectral();
   s.addRules({
     'info-license': Object.assign(ruleset.rules['info-license'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['info-license'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/license-url.ts b/src/rulesets/oas/__tests__/license-url.ts
index b055fffc..73cf84bf 100644
--- a/src/rulesets/oas/__tests__/license-url.ts
+++ b/src/rulesets/oas/__tests__/license-url.ts
@@ -5,7 +5,7 @@ describe('license-url', () => {
   const s = new Spectral();
   s.addRules({
     'license-url': Object.assign(ruleset.rules['license-url'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['license-url'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/no-eval-in-markdown.ts b/src/rulesets/oas/__tests__/no-eval-in-markdown.ts
index ca142d05..2036caa9 100644
--- a/src/rulesets/oas/__tests__/no-eval-in-markdown.ts
+++ b/src/rulesets/oas/__tests__/no-eval-in-markdown.ts
@@ -5,7 +5,7 @@ describe('no-eval-in-markdown', () => {
   const s = new Spectral();
   s.addRules({
     'no-eval-in-markdown': Object.assign(ruleset.rules['no-eval-in-markdown'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['no-eval-in-markdown'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/no-script-tags-in-markdown.ts b/src/rulesets/oas/__tests__/no-script-tags-in-markdown.ts
index 3e949fac..2c79d9ad 100644
--- a/src/rulesets/oas/__tests__/no-script-tags-in-markdown.ts
+++ b/src/rulesets/oas/__tests__/no-script-tags-in-markdown.ts
@@ -5,7 +5,7 @@ describe('no-script-tags-in-markdown', () => {
   const s = new Spectral();
   s.addRules({
     'no-script-tags-in-markdown': Object.assign(ruleset.rules['no-script-tags-in-markdown'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['no-script-tags-in-markdown'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/only-local-references.ts b/src/rulesets/oas/__tests__/only-local-references.ts
index 89c242db..53c0d617 100644
--- a/src/rulesets/oas/__tests__/only-local-references.ts
+++ b/src/rulesets/oas/__tests__/only-local-references.ts
@@ -6,7 +6,7 @@ describe('only-local-references', () => {
   const s = new Spectral();
   s.addRules({
     'only-local-references': Object.assign(ruleset.rules['only-local-references'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['only-local-references'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/openapi-tags-alphabetical.ts b/src/rulesets/oas/__tests__/openapi-tags-alphabetical.ts
index 4c043ea7..1ff3e3e2 100644
--- a/src/rulesets/oas/__tests__/openapi-tags-alphabetical.ts
+++ b/src/rulesets/oas/__tests__/openapi-tags-alphabetical.ts
@@ -5,7 +5,7 @@ describe('openapi-tags-alphabetical', () => {
   const s = new Spectral();
   s.addRules({
     'openapi-tags-alphabetical': Object.assign(ruleset.rules['openapi-tags-alphabetical'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['openapi-tags-alphabetical'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/openapi-tags.ts b/src/rulesets/oas/__tests__/openapi-tags.ts
index c6c2c55e..8d1de5f9 100644
--- a/src/rulesets/oas/__tests__/openapi-tags.ts
+++ b/src/rulesets/oas/__tests__/openapi-tags.ts
@@ -5,7 +5,7 @@ describe('openapi-tags', () => {
   const s = new Spectral();
   s.addRules({
     'openapi-tags': Object.assign(ruleset.rules['openapi-tags'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['openapi-tags'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-default-response.ts b/src/rulesets/oas/__tests__/operation-default-response.ts
index 2a3ee5d0..7eefb02c 100644
--- a/src/rulesets/oas/__tests__/operation-default-response.ts
+++ b/src/rulesets/oas/__tests__/operation-default-response.ts
@@ -5,7 +5,7 @@ describe('operation-default-response', () => {
   const s = new Spectral();
   s.addRules({
     'operation-default-response': Object.assign(ruleset.rules['operation-default-response'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-default-response'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-description.ts b/src/rulesets/oas/__tests__/operation-description.ts
index b69932cc..ac3f1093 100644
--- a/src/rulesets/oas/__tests__/operation-description.ts
+++ b/src/rulesets/oas/__tests__/operation-description.ts
@@ -5,7 +5,7 @@ describe('operation-description', () => {
   const s = new Spectral();
   s.addRules({
     'operation-description': Object.assign(ruleset.rules['operation-description'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-description'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-operationId-valid-in-url.ts b/src/rulesets/oas/__tests__/operation-operationId-valid-in-url.ts
index 04a7653a..a535d147 100644
--- a/src/rulesets/oas/__tests__/operation-operationId-valid-in-url.ts
+++ b/src/rulesets/oas/__tests__/operation-operationId-valid-in-url.ts
@@ -5,7 +5,7 @@ describe('operation-operationId-valid-in-url', () => {
   const s = new Spectral();
   s.addRules({
     'operation-operationId-valid-in-url': Object.assign(ruleset.rules['operation-operationId-valid-in-url'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-operationId-valid-in-url'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-operationId.ts b/src/rulesets/oas/__tests__/operation-operationId.ts
index f8b75d98..5661b425 100644
--- a/src/rulesets/oas/__tests__/operation-operationId.ts
+++ b/src/rulesets/oas/__tests__/operation-operationId.ts
@@ -5,7 +5,7 @@ describe('operation-operationId', () => {
   const s = new Spectral();
   s.addRules({
     'operation-operationId': Object.assign(ruleset.rules['operation-operationId'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-operationId'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-singular-tag.ts b/src/rulesets/oas/__tests__/operation-singular-tag.ts
index ac560df7..049a4ab6 100644
--- a/src/rulesets/oas/__tests__/operation-singular-tag.ts
+++ b/src/rulesets/oas/__tests__/operation-singular-tag.ts
@@ -5,7 +5,7 @@ describe('operation-singular-tag', () => {
   const s = new Spectral();
   s.addRules({
     'operation-singular-tag': Object.assign(ruleset.rules['operation-singular-tag'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-singular-tag'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-summary-formatted.ts b/src/rulesets/oas/__tests__/operation-summary-formatted.ts
index 33de106c..1e256959 100644
--- a/src/rulesets/oas/__tests__/operation-summary-formatted.ts
+++ b/src/rulesets/oas/__tests__/operation-summary-formatted.ts
@@ -5,7 +5,7 @@ describe('operation-summary-formatted', () => {
   const s = new Spectral();
   s.addRules({
     'operation-summary-formatted': Object.assign(ruleset.rules['operation-summary-formatted'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-summary-formatted'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/operation-tags.ts b/src/rulesets/oas/__tests__/operation-tags.ts
index bfaabfc1..d191908a 100644
--- a/src/rulesets/oas/__tests__/operation-tags.ts
+++ b/src/rulesets/oas/__tests__/operation-tags.ts
@@ -5,7 +5,7 @@ describe('operation-tags', () => {
   const s = new Spectral();
   s.addRules({
     'operation-tags': Object.assign(ruleset.rules['operation-tags'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-tags'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/parameter-description.ts b/src/rulesets/oas/__tests__/parameter-description.ts
index 477c3b91..3bc13ade 100644
--- a/src/rulesets/oas/__tests__/parameter-description.ts
+++ b/src/rulesets/oas/__tests__/parameter-description.ts
@@ -6,7 +6,7 @@ describe('parameter-description', () => {
 
   s.addRules({
     'parameter-description': Object.assign(ruleset.rules['parameter-description'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['parameter-description'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/path-declarations-must-exist.ts b/src/rulesets/oas/__tests__/path-declarations-must-exist.ts
index bef8dc99..6fa9d790 100644
--- a/src/rulesets/oas/__tests__/path-declarations-must-exist.ts
+++ b/src/rulesets/oas/__tests__/path-declarations-must-exist.ts
@@ -5,7 +5,7 @@ describe('path-declarations-must-exist', () => {
   const s = new Spectral();
   s.addRules({
     'path-declarations-must-exist': Object.assign(ruleset.rules['path-declarations-must-exist'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['path-declarations-must-exist'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/path-keys-no-trailing-slash.ts b/src/rulesets/oas/__tests__/path-keys-no-trailing-slash.ts
index f1841fdc..5a77df89 100644
--- a/src/rulesets/oas/__tests__/path-keys-no-trailing-slash.ts
+++ b/src/rulesets/oas/__tests__/path-keys-no-trailing-slash.ts
@@ -5,7 +5,7 @@ describe('path-keys-no-trailing-slash', () => {
   const s = new Spectral();
   s.addRules({
     'path-keys-no-trailing-slash': Object.assign(ruleset.rules['path-keys-no-trailing-slash'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['path-keys-no-trailing-slash'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/path-not-include-query.ts b/src/rulesets/oas/__tests__/path-not-include-query.ts
index 229a9baf..7647a717 100644
--- a/src/rulesets/oas/__tests__/path-not-include-query.ts
+++ b/src/rulesets/oas/__tests__/path-not-include-query.ts
@@ -5,7 +5,7 @@ describe('path-not-include-query', () => {
   const s = new Spectral();
   s.addRules({
     'path-not-include-query': Object.assign(ruleset.rules['path-not-include-query'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['path-not-include-query'].type],
     }),
   });
diff --git a/src/rulesets/oas/__tests__/tag-description.ts b/src/rulesets/oas/__tests__/tag-description.ts
index 06b9c643..c31ab349 100644
--- a/src/rulesets/oas/__tests__/tag-description.ts
+++ b/src/rulesets/oas/__tests__/tag-description.ts
@@ -5,7 +5,7 @@ describe('tag-description', () => {
   const s = new Spectral();
   s.addRules({
     'tag-description': Object.assign(ruleset.rules['tag-description'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['tag-description'].type],
     }),
   });
diff --git a/src/rulesets/oas/functions/oasOp2xxResponse/__tests__/index.ts b/src/rulesets/oas/functions/oasOp2xxResponse/__tests__/index.ts
index dc13d251..78029620 100644
--- a/src/rulesets/oas/functions/oasOp2xxResponse/__tests__/index.ts
+++ b/src/rulesets/oas/functions/oasOp2xxResponse/__tests__/index.ts
@@ -8,7 +8,7 @@ describe('oasOp2xxResponse', () => {
   s.addFunctions(ruleset.functions || {});
   s.addRules({
     'operation-2xx-response': Object.assign(ruleset.rules['operation-2xx-response'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-2xx-response'].type],
     }),
   });
diff --git a/src/rulesets/oas/functions/oasOpFormDataConsumeCheck/__tests__/index.ts b/src/rulesets/oas/functions/oasOpFormDataConsumeCheck/__tests__/index.ts
index fbc75be9..b5d811a1 100644
--- a/src/rulesets/oas/functions/oasOpFormDataConsumeCheck/__tests__/index.ts
+++ b/src/rulesets/oas/functions/oasOpFormDataConsumeCheck/__tests__/index.ts
@@ -10,7 +10,7 @@ describe('oasOpFormDataConsumeCheck', () => {
   s.addFunctions(ruleset.functions || {});
   s.addRules({
     'operation-formData-consume-check': Object.assign(ruleset.rules['operation-formData-consume-check'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-formData-consume-check'].type],
     }),
   });
diff --git a/src/rulesets/oas/functions/oasOpIdUnique/__tests__/index.ts b/src/rulesets/oas/functions/oasOpIdUnique/__tests__/index.ts
index e43ca071..bf501a03 100644
--- a/src/rulesets/oas/functions/oasOpIdUnique/__tests__/index.ts
+++ b/src/rulesets/oas/functions/oasOpIdUnique/__tests__/index.ts
@@ -11,7 +11,7 @@ describe('oasOpIdUnique', () => {
   s.addFunctions(ruleset.functions || {});
   s.addRules({
     'operation-operationId-unique': Object.assign(ruleset.rules['operation-operationId-unique'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-operationId-unique'].type],
     }),
   });
diff --git a/src/rulesets/oas/functions/oasOpParams/__tests__/index.test.ts b/src/rulesets/oas/functions/oasOpParams/__tests__/index.test.ts
index c5b0e7f2..59ded664 100644
--- a/src/rulesets/oas/functions/oasOpParams/__tests__/index.test.ts
+++ b/src/rulesets/oas/functions/oasOpParams/__tests__/index.test.ts
@@ -10,7 +10,7 @@ describe('oasOpParams', () => {
   s.addFunctions(ruleset.functions || {});
   s.addRules({
     'operation-parameters': Object.assign(ruleset.rules['operation-parameters'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['operation-parameters'].type],
     }),
   });
diff --git a/src/rulesets/oas/functions/oasOpSecurityDefined/__tests__/index.ts b/src/rulesets/oas/functions/oasOpSecurityDefined/__tests__/index.ts
index 32fca8d6..cd0c2891 100644
--- a/src/rulesets/oas/functions/oasOpSecurityDefined/__tests__/index.ts
+++ b/src/rulesets/oas/functions/oasOpSecurityDefined/__tests__/index.ts
@@ -13,7 +13,7 @@ describe('oasOpSecurityDefined', () => {
     s.addFunctions(oas2Ruleset.functions || {});
     s.addRules({
       'operation-security-defined': Object.assign(oas2Ruleset.rules['operation-security-defined'], {
-        enabled: true,
+        recommended: true,
         type: RuleType[oas2Ruleset.rules['operation-security-defined'].type],
       }),
     });
@@ -63,7 +63,7 @@ describe('oasOpSecurityDefined', () => {
     s.addFunctions(oas3Ruleset.functions || {});
     s.addRules({
       'operation-security-defined': Object.assign(oas3Ruleset.rules['operation-security-defined'], {
-        enabled: true,
+        recommended: true,
         type: RuleType[oas3Ruleset.rules['operation-security-defined'].type],
       }),
     });
diff --git a/src/rulesets/oas/functions/oasPathParam/__tests__/index.test.ts b/src/rulesets/oas/functions/oasPathParam/__tests__/index.test.ts
index 69304ce3..e7eff9ce 100644
--- a/src/rulesets/oas/functions/oasPathParam/__tests__/index.test.ts
+++ b/src/rulesets/oas/functions/oasPathParam/__tests__/index.test.ts
@@ -10,7 +10,7 @@ describe('oasPathParam', () => {
   s.addFunctions(ruleset.functions || {});
   s.addRules({
     'path-params': Object.assign(ruleset.rules['path-params'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['path-params'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/api-host.ts b/src/rulesets/oas2/__tests__/api-host.ts
index 4b559d4a..a0f9ff7b 100644
--- a/src/rulesets/oas2/__tests__/api-host.ts
+++ b/src/rulesets/oas2/__tests__/api-host.ts
@@ -5,7 +5,7 @@ describe('api-host', () => {
   const s = new Spectral();
   s.addRules({
     'api-host': Object.assign(ruleset.rules['api-host'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['api-host'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/api-schemes.ts b/src/rulesets/oas2/__tests__/api-schemes.ts
index 28b01f9c..2c9be1c7 100644
--- a/src/rulesets/oas2/__tests__/api-schemes.ts
+++ b/src/rulesets/oas2/__tests__/api-schemes.ts
@@ -5,7 +5,7 @@ describe('api-schemes', () => {
   const s = new Spectral();
   s.addRules({
     'api-schemes': Object.assign(ruleset.rules['api-schemes'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['api-schemes'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/host-not-example.ts b/src/rulesets/oas2/__tests__/host-not-example.ts
index 4146a56d..80149bbc 100644
--- a/src/rulesets/oas2/__tests__/host-not-example.ts
+++ b/src/rulesets/oas2/__tests__/host-not-example.ts
@@ -5,7 +5,7 @@ describe('host-not-example', () => {
   const s = new Spectral();
   s.addRules({
     'host-not-example': Object.assign(ruleset.rules['host-not-example'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['host-not-example'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/host-trailing-slash.ts b/src/rulesets/oas2/__tests__/host-trailing-slash.ts
index 08840ec4..8d3e6c5a 100644
--- a/src/rulesets/oas2/__tests__/host-trailing-slash.ts
+++ b/src/rulesets/oas2/__tests__/host-trailing-slash.ts
@@ -5,7 +5,7 @@ describe('host-trailing-slash', () => {
   const s = new Spectral();
   s.addRules({
     'host-trailing-slash': Object.assign(ruleset.rules['host-trailing-slash'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['host-trailing-slash'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/model-description.ts b/src/rulesets/oas2/__tests__/model-description.ts
index 3a43912a..c71b30af 100644
--- a/src/rulesets/oas2/__tests__/model-description.ts
+++ b/src/rulesets/oas2/__tests__/model-description.ts
@@ -5,7 +5,7 @@ describe('model-description', () => {
   const s = new Spectral();
   s.addRules({
     'model-description': Object.assign(ruleset.rules['model-description'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['model-description'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/oas2-schema.ts b/src/rulesets/oas2/__tests__/oas2-schema.ts
index d05b698a..6d08f965 100644
--- a/src/rulesets/oas2/__tests__/oas2-schema.ts
+++ b/src/rulesets/oas2/__tests__/oas2-schema.ts
@@ -5,7 +5,7 @@ describe('oas2-schema', () => {
   const s = new Spectral();
   s.addRules({
     'oas2-schema': Object.assign(ruleset.rules['oas2-schema'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['oas2-schema'].type],
     }),
   });
diff --git a/src/rulesets/oas2/__tests__/valid-example.ts b/src/rulesets/oas2/__tests__/valid-example.ts
index 161cf097..18483098 100644
--- a/src/rulesets/oas2/__tests__/valid-example.ts
+++ b/src/rulesets/oas2/__tests__/valid-example.ts
@@ -5,7 +5,7 @@ describe('valid-example', () => {
   const s = new Spectral();
   s.addRules({
     'valid-example': Object.assign(ruleset.rules['valid-example'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['valid-example'].type],
     }),
   });
diff --git a/src/rulesets/oas3/__tests__/api-servers.ts b/src/rulesets/oas3/__tests__/api-servers.ts
index 4a734537..f210015c 100644
--- a/src/rulesets/oas3/__tests__/api-servers.ts
+++ b/src/rulesets/oas3/__tests__/api-servers.ts
@@ -5,7 +5,7 @@ describe('api-servers', () => {
   const s = new Spectral();
   s.addRules({
     'api-servers': Object.assign(ruleset.rules['api-servers'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['api-servers'].type],
     }),
   });
diff --git a/src/rulesets/oas3/__tests__/model-description.ts b/src/rulesets/oas3/__tests__/model-description.ts
index 08bd4517..8e5df413 100644
--- a/src/rulesets/oas3/__tests__/model-description.ts
+++ b/src/rulesets/oas3/__tests__/model-description.ts
@@ -5,7 +5,7 @@ describe('model-description', () => {
   const s = new Spectral();
   s.addRules({
     'model-description': Object.assign(ruleset.rules['model-description'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['model-description'].type],
     }),
   });
diff --git a/src/rulesets/oas3/__tests__/server-not-example.ts b/src/rulesets/oas3/__tests__/server-not-example.ts
index 92a7601b..2ecdb5ed 100644
--- a/src/rulesets/oas3/__tests__/server-not-example.ts
+++ b/src/rulesets/oas3/__tests__/server-not-example.ts
@@ -5,7 +5,7 @@ describe('server-not-example.com', () => {
   const s = new Spectral();
   s.addRules({
     'server-not-example.com': Object.assign(ruleset.rules['server-not-example.com'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['server-not-example.com'].type],
     }),
   });
diff --git a/src/rulesets/oas3/__tests__/server-trailing-slash.ts b/src/rulesets/oas3/__tests__/server-trailing-slash.ts
index 312991f5..4f683118 100644
--- a/src/rulesets/oas3/__tests__/server-trailing-slash.ts
+++ b/src/rulesets/oas3/__tests__/server-trailing-slash.ts
@@ -5,7 +5,7 @@ describe('server-trailing-slash', () => {
   const s = new Spectral();
   s.addRules({
     'server-trailing-slash': Object.assign(ruleset.rules['server-trailing-slash'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['server-trailing-slash'].type],
     }),
   });
diff --git a/src/rulesets/oas3/__tests__/valid-example.ts b/src/rulesets/oas3/__tests__/valid-example.ts
index 3402e8e0..9fa0b5b6 100644
--- a/src/rulesets/oas3/__tests__/valid-example.ts
+++ b/src/rulesets/oas3/__tests__/valid-example.ts
@@ -9,7 +9,7 @@ describe('valid-example', () => {
   const s = new Spectral();
   s.addRules({
     'valid-example': Object.assign(ruleset.rules['valid-example'], {
-      enabled: true,
+      recommended: true,
       type: RuleType[ruleset.rules['valid-example'].type],
     }),
   });