{
  "$schema": "https://rytm.org/schema/conventions-v1.json",
  "version": "1.0.0",
  "rules": [
    {
      "id": "use-printAttrValue",
      "title": "Output an attribute value with printAttrValue()",
      "severity": "error",
      "files": ["public/local/views/**/*.php"],
      "detect": [
        { "type": "regex", "pattern": "htmlspecialchars\\([^)]*->getAttr\\(" }
      ],
      "suggest": "Replace with $item->printAttrValue('attr', 'classes') — it handles empty check, sieroty, and wrapping.",
      "reference": "docs/shared/view-development.md#printattrvalue"
    },
    {
      "id": "use-braces",
      "title": "Control structures use { }, never endif;",
      "severity": "error",
      "files": ["public/local/**/*.php"],
      "detect": [
        { "type": "regex", "pattern": "(endif|endforeach|endwhile|endfor);" },
        { "type": "regex", "pattern": "\\b(if|elseif|else|foreach|while|for)\\s*\\([^)]*\\)\\s*:\\s*(\\?>)?" }
      ],
      "suggest": "Use { ... } syntax. Alternative-syntax is forbidden in this project.",
      "reference": "docs/shared/code-style.md#control-structures"
    },
    {
      "id": "use-sieroty",
      "title": "Wrap user-visible strings in Strings::sieroty()",
      "severity": "advisory",
      "files": ["public/local/views/**/*.php"],
      "detect": [
        {
          "type": "regex",
          "pattern": "<\\?= *\\$[a-zA-Z_][a-zA-Z0-9_]*\\s*\\?>",
          "skipIfContext": ["sr-only", "linkText", "printAttrValue", "htmlspecialchars"]
        }
      ],
      "suggest": "Wrap in Strings::sieroty() for typographic widow handling. Skip for sr-only blocks and linkText/printAttrValue output.",
      "reference": "docs/shared/view-development.md#sieroty"
    },
    {
      "id": "early-return-empty",
      "title": "Partial views early-return when content would be empty",
      "severity": "advisory",
      "files": ["public/local/views/**/*.php"],
      "detect": [
        { "type": "manual", "note": "AST-level check; needs R7 to implement." }
      ],
      "suggest": "Return at the top of the view before printing the wrapper if required content would be empty.",
      "reference": "docs/shared/view-development.md#early-return-empty"
    }
  ]
}
