{"record":{"id":"0975839f5635cf49","repo":"affaan-m/ECC","slug":"missing-scoring-section-in-compliance-spec","errorCode":null,"errorMessage":"Missing 'scoring' section in compliance spec","messagePattern":"Missing 'scoring' section in compliance spec","errorType":"validation","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"skills/skill-comply/scripts/parser.py","lineNumber":98,"sourceCode":"        raise FileNotFoundError(f\"Spec file not found: {path}\")\n    raw = yaml.safe_load(path.read_text())\n\n    steps: list[Step] = []\n    for s in raw[\"steps\"]:\n        d = s[\"detector\"]\n        steps.append(Step(\n            id=s[\"id\"],\n            description=s[\"description\"],\n            required=s[\"required\"],\n            detector=Detector(\n                description=d[\"description\"],\n                after_step=d.get(\"after_step\"),\n                before_step=d.get(\"before_step\"),\n            ),\n        ))\n\n    if \"scoring\" not in raw:\n        raise KeyError(\"Missing 'scoring' section in compliance spec\")\n\n    return ComplianceSpec(\n        id=raw[\"id\"],\n        name=raw[\"name\"],\n        source_rule=raw[\"source_rule\"],\n        version=raw[\"version\"],\n        steps=tuple(steps),\n        threshold_promote_to_hook=raw[\"scoring\"][\"threshold_promote_to_hook\"],\n    )\n","sourceCodeStart":80,"sourceCodeEnd":108,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/skills/skill-comply/scripts/parser.py#L80-L108","documentation":"After parsing the steps list, parse_spec() requires a top-level 'scoring' map and reads raw['scoring']['threshold_promote_to_hook']. If 'scoring' is absent it raises KeyError with this message; if 'scoring' exists but lacks 'threshold_promote_to_hook' the subsequent subscript raises a plain KeyError instead. This message specifically means the entire scoring block is missing from the YAML.","triggerScenarios":"An LLM-generated spec (from spec_generator) omitted the scoring block; a hand-edited spec deleted the section; the key was misspelled (e.g. 'score' or 'Score').","commonSituations":"spec_generator retries failed and the final attempt still produced incomplete YAML; a spec template was copied without the scoring section; YAML indentation put scoring under another key.","solutions":["Open the spec and add a top-level 'scoring:' block with 'threshold_promote_to_hook: <float>'.","If using spec_generator, raise max_retries or switch to a stronger model so the produced YAML is complete.","Validate the spec against a schema/example before passing it to parse_spec.","Check YAML indentation — scoring must be a sibling of 'steps', not nested under it."],"exampleFix":"# before\nid: skill-x\nname: Skill X\nsteps:\n  - id: s1\n    description: ...\n    required: true\n    detector:\n      description: ...\n\n# after\nid: skill-x\nname: Skill X\nsteps:\n  - id: s1\n    description: ...\n    required: true\n    detector:\n      description: ...\nscoring:\n  threshold_promote_to_hook: 0.8","handlingStrategy":"validation","validationCode":"import yaml\nfrom pathlib import Path\n\ndef validate_spec_has_scoring(path: Path) -> None:\n    raw = yaml.safe_load(path.read_text())\n    if 'scoring' not in raw or 'threshold_promote_to_hook' not in raw['scoring']:\n        raise SystemExit('spec missing scoring.threshold_promote_to_hook')","typeGuard":null,"tryCatchPattern":"from scripts.parser import parse_spec\ntry:\n    spec = parse_spec(path)\nexcept KeyError as e:\n    if 'scoring' in str(e):\n        raise SystemExit('add a scoring.threshold_promote_to_hook block to the spec') from e\n    raise","preventionTips":["Keep a canonical example spec next to the parser and diff new specs against it.","When using spec_generator, log the produced YAML so missing sections are visible before parse_spec runs.","Write a jsonschema/pydantic model for ComplianceSpec and validate raw YAML before parse_spec."],"tags":["yaml","spec","validation","skill-comply","schema"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}