{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.invalid/iftypeset/spec/schema/rule.schema.json", "title": "Publication-quality rule record", "type": "object", "additionalProperties": false, "required": [ "id", "title", "source_refs", "category", "severity", "applies_to", "rule_text", "rationale", "enforcement", "autofix", "autofix_notes", "tags", "keywords", "dependencies", "exceptions", "status" ], "properties": { "id": { "type": "string", "description": "Stable rule identifier. Prefix must be one of CMOS, BRING, HOUSE.", "minLength": 6, "maxLength": 120, "pattern": "^(CMOS|BRING|HOUSE)\\.[A-Z0-9_]+(?:\\.[A-Z0-9_]+)*$" }, "title": { "type": "string", "description": "Short human-readable rule title.", "minLength": 4, "maxLength": 160 }, "source_refs": { "type": "array", "description": "Pointers back to sources (not quotes). Prefer: CMOS18 §X.Y pN / BRING §X.Y pN / HOUSE §X.Y pN.", "minItems": 1, "items": { "type": "string", "minLength": 8, "maxLength": 120, "pattern": "^(CMOS18|BRING|HOUSE)\\s§[0-9A-Za-z][0-9A-Za-z._\\-]*\\s+p[0-9ivxlcdmIVXLCDM]+(?:-[0-9ivxlcdmIVXLCDM]+)?(?:\\s\\(scan p[0-9]+\\))?$" } }, "category": { "type": "string", "description": "Primary taxonomy bucket.", "enum": [ "editorial", "typography", "layout", "headings", "citations", "numbers", "punctuation", "abbreviations", "links", "tables", "figures", "code", "frontmatter", "backmatter", "accessibility", "i18n" ] }, "severity": { "type": "string", "description": "Normativity level. MUST blocks release unless downgraded by profile.", "enum": ["must", "should", "warn"] }, "applies_to": { "type": "string", "description": "Which pipeline stage(s) the rule targets.", "enum": ["md", "html", "pdf", "all"] }, "rule_text": { "type": "string", "description": "Paraphrased rule statement (no long quotes). If exact wording matters, note: Exact wording required—refer to pointer.", "minLength": 10, "maxLength": 800 }, "rationale": { "type": "string", "description": "One-line rationale.", "minLength": 5, "maxLength": 200 }, "enforcement": { "type": "string", "description": "Primary enforcement mechanism.", "enum": ["lint", "typeset", "postrender", "manual"] }, "autofix": { "type": "string", "description": "Autofix capability, if any.", "enum": ["none", "rewrite", "reflow", "suggest"] }, "autofix_notes": { "type": "string", "description": "Notes describing what can be fixed and how/when. Keep short; never include book quotes.", "maxLength": 400 }, "tags": { "type": "array", "description": "Compact labels for routing/search/overrides (e.g. manual_checklist=true, widows_orphans, hyphenation).", "items": { "type": "string", "minLength": 1, "maxLength": 48, "pattern": "^[a-z0-9][a-z0-9_.:\\-/]*(?:=[a-z0-9_.:\\-/]+)?$" }, "maxItems": 64 }, "keywords": { "type": "array", "description": "Search keywords (human-oriented; not necessarily normalized).", "items": { "type": "string", "minLength": 2, "maxLength": 48 }, "maxItems": 64 }, "dependencies": { "type": "array", "description": "Rule IDs that should be applied/understood first.", "items": { "type": "string", "pattern": "^(CMOS|BRING|HOUSE)\\.[A-Z0-9_]+(?:\\.[A-Z0-9_]+)*$" }, "maxItems": 32 }, "exceptions": { "type": "array", "description": "Free-text exceptions/caveats. Keep concise.", "items": { "type": "string", "minLength": 3, "maxLength": 240 }, "maxItems": 32 }, "examples_ref": { "type": "array", "description": "Optional references to separately stored examples (see spec/examples/README.md).", "items": { "type": "string", "minLength": 6, "maxLength": 80, "pattern": "^EX\\.[A-Z0-9_]+\\.[A-Z0-9_]+\\.[0-9]{3,}$" }, "maxItems": 64 }, "implementation_notes": { "type": "string", "description": "Optional short notes for implementers (no quotes).", "minLength": 3, "maxLength": 600 }, "status": { "type": "string", "description": "Lifecycle state.", "enum": ["draft", "active", "deprecated"] } }, "allOf": [ { "if": { "properties": { "autofix": { "enum": ["rewrite", "reflow", "suggest"] } }, "required": ["autofix"] }, "then": { "properties": { "autofix_notes": { "minLength": 1 } } } } ] }