{"record":{"id":"a8d8a6e2ff98c9ec","repo":"nikivdev/code","slug":"commit-blocked-by-required-skill-gate","errorCode":null,"errorMessage":"Commit blocked by required skill gate","messagePattern":"Commit blocked by required skill gate","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/commit.rs","lineNumber":3135,"sourceCode":"            }\n        } else if let Some(version) = skills::read_skill_version_at(repo_root, skill_name)? {\n            report.loaded_versions.insert(skill_name.clone(), version);\n        }\n    }\n\n    report.pass = report.missing_skills.is_empty() && report.version_failures.is_empty();\n    if !report.pass {\n        for missing in &report.missing_skills {\n            eprintln!(\n                \"  skills: required skill '{}' is missing in .ai/skills/\",\n                missing\n            );\n        }\n        for failure in &report.version_failures {\n            eprintln!(\"  skills: {}\", failure);\n        }\n        if policy.mode == \"block\" {\n            bail!(\"Commit blocked by required skill gate\");\n        }\n        eprintln!(\"  skills: warning only (mode=warn)\");\n    }\n\n    Ok(report)\n}\n\nfn build_required_skills_prompt_context(\n    repo_root: &Path,\n    skill_report: &SkillGateReport,\n) -> String {\n    if skill_report.required_skills.is_empty() {\n        return String::new();\n    }\n\n    let mut sections = Vec::new();\n    for skill_name in &skill_report.required_skills {\n        if let Ok(Some(content)) = skills::read_skill_content_at(repo_root, skill_name) {","sourceCodeStart":3117,"sourceCodeEnd":3153,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/commit.rs#L3117-L3153","documentation":"The library enforces a 'required skill gate' before commits: it builds a report of policy/version failures and, when the policy mode is \"block\", any failure aborts the commit. In \"warn\" mode the same failures only print a warning. This lets teams mandate project-defined skills/checks as a precondition to committing.","triggerScenarios":"Committing while the skill gate report contains version_failures (or other failures) and the configured policy mode equals \"block\" (e.g. from project config specifying required skills with mode=block).","commonSituations":"Cloning a project whose config requires skills you have not installed or at versions you do not satisfy; forgetting to run the repo's setup/bootstrap; locally downgrading a required tool; misconfigured skill paths in config.","solutions":["Read the printed `skills: <failure>` lines and install/upgrade the listed required skills to the required versions.","Run the project's setup script to provision missing skills.","Temporarily set the gate policy mode to \"warn\" in project config if the team permits (not recommended for CI-shared config).","Use any documented gate override (e.g. gate_overrides) only if policy allows bypassing."],"exampleFix":"// before (project config)\n{ \"required_skills\": [{ \"name\": \"review\", \"version\": \"2.0\" }], \"mode\": \"block\" }\n// after installing the skill\n$ skills install review@2.0\n$ commit ... // passes gate","handlingStrategy":"try-catch","validationCode":"// Check required skills are present at required versions before committing\n// (using the project's skills CLI)\n// $ skills check --required  # exits non-zero if version_failures exist","typeGuard":null,"tryCatchPattern":"if let Err(e) = commit_flow() {\n    if e.to_string().contains(\"Commit blocked by required skill gate\") {\n        eprintln!(\"install/upgrade the skills listed in the gate output, then retry\");\n    } else { return Err(e.into()); }\n}","preventionTips":["Run the repo's bootstrap/setup script after cloning so required skills are installed.","Pin skill versions in your environment to match project config.","Re-run the skill check after pulling config changes, before committing."],"tags":["git","pre-commit","policy-gate","skills"],"backgroundTag":"commit-blocked-by-gate","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}