{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "skillfactor/extract_posting",
  "title": "Job posting extraction record",
  "description": "One record per job ad. Produced by a local LLM (Ollama) from the raw posting text; validated by pipeline/extract_local.py before it enters the evidence store. Normalization rules live in extract_posting.txt and are re-enforced by the validator (lowercasing, dedupe, length caps).",
  "type": "object",
  "additionalProperties": false,
  "required": ["hard_skills", "tools", "methods", "responsibilities",
               "qualifications", "seniority", "soft_skills"],
  "properties": {
    "hard_skills": {
      "description": "Domain-specific abilities the employer asks for (lowercase english, singular, 2-6 words, no tools/products here)",
      "type": "array", "maxItems": 12,
      "items": {"type": "string", "minLength": 3, "maxLength": 60}
    },
    "tools": {
      "description": "Concrete software/hardware/products, canonical product capitalization (e.g. 'LinkedIn Recruiter', 'Microsoft Excel', 'applicant tracking system (ATS)' for the generic category)",
      "type": "array", "maxItems": 12,
      "items": {"type": "string", "minLength": 2, "maxLength": 60}
    },
    "methods": {
      "description": "Named techniques / procedures / frameworks (lowercase english unless proper noun, e.g. 'structured interviews', 'boolean search', 'Scrum')",
      "type": "array", "maxItems": 10,
      "items": {"type": "string", "minLength": 3, "maxLength": 60}
    },
    "responsibilities": {
      "description": "What the role does day-to-day, verb-noun style, lowercase (e.g. 'full-cycle recruiting', 'stakeholder reporting')",
      "type": "array", "maxItems": 10,
      "items": {"type": "string", "minLength": 3, "maxLength": 80}
    },
    "qualifications": {
      "description": "Formal requirements: degrees, licenses, certifications, years of experience (lowercase except acronyms, e.g. \"bachelor's degree in human resources\", '5+ years recruiting experience', 'SHRM-CP certification')",
      "type": "array", "maxItems": 8,
      "items": {"type": "string", "minLength": 3, "maxLength": 80}
    },
    "seniority": {
      "description": "Level of the advertised role, inferred from title and requirements; 'n/a' when the ad gives no signal",
      "type": "string",
      "enum": ["junior", "mid", "senior", "lead", "n/a"]
    },
    "soft_skills": {
      "description": "Interpersonal/behavioural traits explicitly asked for (lowercase english, e.g. 'communication', 'attention to detail')",
      "type": "array", "maxItems": 8,
      "items": {"type": "string", "minLength": 3, "maxLength": 40}
    }
  }
}
