181 lines
5 KiB
JSON
181 lines
5 KiB
JSON
{
|
|
"$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 } } }
|
|
}
|
|
]
|
|
}
|