{"id":50547356,"url":"https://github.com/amiable-dev/llm-council","last_synced_at":"2026-06-04T00:01:38.525Z","repository":{"id":326763780,"uuid":"1106436009","full_name":"amiable-dev/llm-council","owner":"amiable-dev","description":"The LLM Council works together to answer your hardest questions","archived":false,"fork":false,"pushed_at":"2026-05-26T22:40:08.000Z","size":2191,"stargazers_count":26,"open_issues_count":12,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-05-27T00:14:52.550Z","etag":null,"topics":["llm-agents","llm-as-a-judge","llm-council","llm-tools","mcp","mcp-server"],"latest_commit_sha":null,"homepage":"https://llm-council.dev/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"karpathy/llm-council","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amiable-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["amiable-dev"],"custom":null}},"created_at":"2025-11-29T08:40:17.000Z","updated_at":"2026-05-26T22:39:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/amiable-dev/llm-council","commit_stats":null,"previous_names":["amiable-dev/llm-council-mcp"],"tags_count":65,"template":false,"template_full_name":null,"purl":"pkg:github/amiable-dev/llm-council","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amiable-dev%2Fllm-council","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amiable-dev%2Fllm-council/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amiable-dev%2Fllm-council/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amiable-dev%2Fllm-council/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amiable-dev","download_url":"https://codeload.github.com/amiable-dev/llm-council/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amiable-dev%2Fllm-council/sbom","scorecard":{"id":1241815,"data":{"date":"2026-01-16T10:46:28Z","repo":{"name":"github.com/amiable-dev/llm-council","commit":"d196f82cb14111c8796b6620a245491e5ad0b72b"},"scorecard":{"version":"v5.0.0","commit":"ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4"},"score":5.4,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":10,"reason":"2 out of 2 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#ci-tests"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#code-review"}},{"name":"Contributors","score":0,"reason":"project has 0 contributing companies or organizations -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#contributors"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dependency-update-tool"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#license"}},{"name":"Maintained","score":0,"reason":"project was created in last 90 days. please review its contents carefully","details":["Warn: Repository was created in last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#maintained"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish.yml:58"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/council-gate.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/council-gate.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/council-gate.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/council-gate.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/council-gate.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/council-gate.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/docs.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docs.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-security.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-security.yml:69: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-security.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-security.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-security.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-security.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-security.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/release-security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/scorecard.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/scorecard.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/scorecard.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/scorecard.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/scorecard.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:85: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:88: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:103: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:106: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:115: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:125: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:130: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:139: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:142: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:147: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:158: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:170: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:173: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:178: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:190: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:44: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/security.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sync-action.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/sync-action.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate-templates.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/validate-templates.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate-templates.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/validate-templates.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/validate-templates.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/validate-templates.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/validate-templates.yml:74: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/validate-templates.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate-templates.yml:91: update your workflow using https://app.stepsecurity.io/secureworkflow/amiable-dev/llm-council/validate-templates.yml/master?enable=pin","Warn: containerImage not pinned by hash: deploy/railway/Dockerfile:7: pin your Docker image by updating python:3.11-slim to python:3.11-slim@sha256:c24e9effa2821a6885165d930d939fec2af0dcf819276138f11dd45e200bd032","Warn: pipCommand not pinned by hash: deploy/railway/Dockerfile:26","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:55","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:72","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:73","Warn: pipCommand not pinned by hash: .github/workflows/release-security.yml:40","Warn: pipCommand not pinned by hash: .github/workflows/security.yml:186","Info:   0 out of  47 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  17 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   1 out of   7 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":10,"reason":"SAST tool detected","details":["Info: SAST configuration detected: CodeQL","Info: SAST configuration detected: Snyk","Info: all commits (2) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#sast"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.24.8 not signed: https://api.github.com/repos/amiable-dev/llm-council/releases/274172691","Warn: release artifact v0.24.7 not signed: https://api.github.com/repos/amiable-dev/llm-council/releases/274168416","Warn: release artifact v0.24.6 not signed: https://api.github.com/repos/amiable-dev/llm-council/releases/274167305","Warn: release artifact v0.24.5 not signed: https://api.github.com/repos/amiable-dev/llm-council/releases/273982256","Warn: release artifact v0.24.4 not signed: https://api.github.com/repos/amiable-dev/llm-council/releases/273981009","Warn: release artifact v0.24.8 does not have provenance: https://api.github.com/repos/amiable-dev/llm-council/releases/274172691","Warn: release artifact v0.24.7 does not have provenance: https://api.github.com/repos/amiable-dev/llm-council/releases/274168416","Warn: release artifact v0.24.6 does not have provenance: https://api.github.com/repos/amiable-dev/llm-council/releases/274167305","Warn: release artifact v0.24.5 does not have provenance: https://api.github.com/repos/amiable-dev/llm-council/releases/273982256","Warn: release artifact v0.24.4 does not have provenance: https://api.github.com/repos/amiable-dev/llm-council/releases/273981009"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#signed-releases"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/council-gate.yml:31","Info: jobLevel 'contents' permission set to 'read': .github/workflows/sync-action.yml:20","Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/council-gate.yml:1","Info: topLevel 'contents' permission set to 'read': .github/workflows/docs.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/publish.yml:10","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release-security.yml:12","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:18","Info: topLevel 'contents' permission set to 'read': .github/workflows/security.yml:17","Warn: topLevel 'security-events' permission set to 'write': .github/workflows/security.yml:18","Info: topLevel 'actions' permission set to 'read': .github/workflows/security.yml:19","Info: topLevel 'pull-requests' permission set to 'read': .github/workflows/security.yml:20","Warn: no topLevel permission defined: .github/workflows/sync-action.yml:1","Warn: no topLevel permission defined: .github/workflows/validate-templates.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2026-01-16T23:55:37.824Z","repository_id":326763780,"created_at":"2026-01-16T23:55:37.824Z","updated_at":"2026-01-16T23:55:37.824Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33884734,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["llm-agents","llm-as-a-judge","llm-council","llm-tools","mcp","mcp-server"],"created_at":"2026-06-04T00:01:37.491Z","updated_at":"2026-06-04T00:01:38.510Z","avatar_url":"https://github.com/amiable-dev.png","language":"Python","funding_links":["https://github.com/sponsors/amiable-dev"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://amiable-dev.github.io/llm-council\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/amiable-dev/llm-council/master/docs/img/logo.svg\" alt=\"LLM Council Logo\" width=\"200\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eLLM Council Core\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/amiable-dev/llm-council/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/amiable-dev/llm-council/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/amiable-dev/llm-council/actions/workflows/security.yml\"\u003e\u003cimg src=\"https://github.com/amiable-dev/llm-council/actions/workflows/security.yml/badge.svg\" alt=\"Security Scanning\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://scorecard.dev/viewer/?uri=github.com/amiable-dev/llm-council\"\u003e\u003cimg src=\"https://api.scorecard.dev/projects/github.com/amiable-dev/llm-council/badge\" alt=\"OpenSSF Scorecard\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/llm-council-core/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/llm-council-core.svg\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.python.org/downloads/\"\u003e\u003cimg src=\"https://img.shields.io/badge/python-3.11+-blue.svg\" alt=\"Python 3.11+\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://llm-council.dev\"\u003e\u003cimg src=\"https://img.shields.io/badge/docs-llm--council.dev-blue\" alt=\"Documentation\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://discord.gg/y467DGHF\"\u003e\u003cimg src=\"https://img.shields.io/badge/Discord-Join%20Chat-7289da?logo=discord\u0026logoColor=white\" alt=\"Discord\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/users/amiable-dev/projects/1\"\u003e\u003cimg src=\"https://img.shields.io/badge/roadmap-project%20board-blue?logo=github\" alt=\"Roadmap\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eA multi-LLM deliberation system where multiple LLMs collaboratively answer questions through peer review and synthesis. Available as a Python library, MCP server, or HTTP API.\u003c/em\u003e\n\u003c/p\u003e\n\n## What is This?\n\nInstead of asking a single LLM for answers, this MCP server:\n1. **Stage 1**: Sends your question to multiple LLMs in parallel (GPT, Claude, Gemini, Grok, etc.)\n2. **Stage 2**: Each LLM reviews and ranks the other responses (anonymized to prevent bias)\n3. **Stage 3**: A Chairman LLM synthesizes all responses into a final, high-quality answer\n\n## Quick Deploy\n\nDeploy your own LLM Council instance:\n\n| Platform | Deploy | Best For |\n|----------|--------|----------|\n| **Railway** | [![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/llm-council?referralCode=K9dsYj) | Production, webhooks |\n| **Render** | [![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/amiable-dev/llm-council) | Evaluation, free tier |\n\n**Required Environment Variables:**\n- `OPENROUTER_API_KEY` - Your [OpenRouter](https://openrouter.ai) API key\n- `LLM_COUNCIL_API_TOKEN` - A secure token for API authentication (generate with `openssl rand -hex 16`)\n\n\u003e **Note**: Railway is recommended for [n8n integration](https://llm-council.dev/integrations/n8n/) (no cold-start). Render Free tier spins down after 15 minutes which may cause webhook timeouts.\n\nFor detailed deployment instructions, see the [Deployment Guide](https://llm-council.dev/deployment/).\n\n\n## Credits \u0026 Attribution\n\nThis project is a derivative work based on the original [llm-council](https://github.com/karpathy/llm-council) by Andrej Karpathy.\n\nKarpathy's original README stated:\n\u003e \"I'm not going to support it in any way, it's provided here as is for other people's inspiration and I don't intend to improve it. Code is ephemeral now and libraries are over, ask your LLM to change it in whatever way you like.\"\n\n...the irony of producing a derivative work that packages the core concept for broader use via the Model Context Protocol!\n\n## Installation\n\n```bash\npip install \"llm-council-core[mcp]\"\n```\n\nFor core library only (no MCP server):\n```bash\npip install llm-council-core\n```\n\n## Setup\n\n### 1. Choose Your Gateway\n\nThe council supports three gateway options for accessing LLMs:\n\n| Gateway | Best For | API Keys Needed |\n|---------|----------|-----------------|\n| **OpenRouter** (default) | Easiest setup, 100+ models via single key | `OPENROUTER_API_KEY` |\n| **Requesty** | BYOK mode, analytics, cost tracking | `REQUESTY_API_KEY` + provider keys |\n| **Direct** | Maximum control, direct provider APIs | Provider keys (Anthropic, OpenAI, Google) |\n\n**Quick Start (OpenRouter):**\n```bash\n# Sign up at openrouter.ai and get your API key\nexport OPENROUTER_API_KEY=\"sk-or-v1-...\"\n```\n\n**Direct Provider Access:**\n```bash\n# Use your existing provider API keys directly\nexport ANTHROPIC_API_KEY=\"sk-ant-...\"\nexport OPENAI_API_KEY=\"sk-...\"\nexport GOOGLE_API_KEY=\"...\"\nexport LLM_COUNCIL_DEFAULT_GATEWAY=direct\n```\n\n**Requesty with BYOK:**\n```bash\nexport REQUESTY_API_KEY=\"...\"\nexport ANTHROPIC_API_KEY=\"sk-ant-...\"  # Your own key, routed through Requesty\nexport LLM_COUNCIL_DEFAULT_GATEWAY=requesty\n```\n\n### 2. Store Your API Keys Securely\n\nChoose one of these options (in order of recommendation):\n\n#### Option A: System Keychain (Most Secure)\n\nStore keys encrypted in your OS keychain:\n\n```bash\n# Install with keychain support\npip install \"llm-council-core[mcp,secure]\"\n\n# Store key securely (prompts for key, no echo)\nllm-council setup-key\n\n# For CI/CD automation, pipe from stdin:\necho \"$OPENROUTER_API_KEY\" | llm-council setup-key --stdin\n```\n\n#### Option B: Environment Variables\n\nSet in your shell profile (`~/.zshrc`, `~/.bashrc`):\n\n```bash\n# OpenRouter (default gateway)\nexport OPENROUTER_API_KEY=\"sk-or-v1-...\"\n\n# Or use direct provider APIs\nexport ANTHROPIC_API_KEY=\"sk-ant-...\"\nexport OPENAI_API_KEY=\"sk-...\"\nexport GOOGLE_API_KEY=\"...\"\n```\n\n#### Option C: Environment File\n\nCreate a `.env` file (ensure it's in `.gitignore`):\n\n```bash\n# For OpenRouter\necho \"OPENROUTER_API_KEY=sk-or-v1-...\" \u003e .env\n\n# Or for direct APIs\ncat \u003e .env \u003c\u003c 'EOF'\nANTHROPIC_API_KEY=sk-ant-...\nOPENAI_API_KEY=sk-...\nGOOGLE_API_KEY=...\nLLM_COUNCIL_DEFAULT_GATEWAY=direct\nEOF\n```\n\n\u003e **Security Note**: Never put API keys in command-line arguments or JSON config files that might be committed to version control.\n\n### 3. Customize Models (Optional)\n\nYou can customize which models participate in the council using three methods (in priority order):\n\n#### Option 1: Environment Variables (Recommended)\n\n```bash\n# Comma-separated list of council models\nexport LLM_COUNCIL_MODELS=\"openai/gpt-4,anthropic/claude-3-opus,google/gemini-pro\"\n\n# Chairman model (synthesizes final response)\nexport LLM_COUNCIL_CHAIRMAN=\"anthropic/claude-3-opus\"\n```\n\n#### Option 2: YAML Configuration (Recommended)\n\nCreate `llm_council.yaml` in your project root or `~/.config/llm-council/llm_council.yaml`:\n\n```yaml\ncouncil:\n  # Tier configuration (ADR-022)\n  tiers:\n    default: high\n    pools:\n      quick:\n        models:\n          - openai/gpt-4o-mini\n          - anthropic/claude-3-5-haiku-20241022\n        timeout_seconds: 30\n      balanced:\n        models:\n          - openai/gpt-4o\n          - anthropic/claude-3-5-sonnet-20241022\n        timeout_seconds: 90\n      high:\n        models:\n          - openai/gpt-4o\n          - anthropic/claude-opus-4-7\n          - google/gemini-3-pro\n        timeout_seconds: 180\n\n  # Triage configuration (ADR-020)\n  triage:\n    enabled: false\n    wildcard:\n      enabled: true\n    prompt_optimization:\n      enabled: true\n\n  # Gateway configuration (ADR-023, ADR-025a)\n  gateways:\n    default: openrouter\n    fallback:\n      enabled: true\n      chain: [openrouter, ollama]  # Can use Ollama as fallback\n\n    # Provider-specific configuration\n    providers:\n      ollama:\n        enabled: true\n        base_url: http://localhost:11434\n        timeout_seconds: 120.0\n        hardware_profile: recommended  # minimum|recommended|professional|enterprise\n\n      openrouter:\n        enabled: true\n        base_url: https://openrouter.ai/api/v1/chat/completions\n\n  # Webhook notifications (ADR-025a)\n  webhooks:\n    enabled: false  # Opt-in\n    timeout_seconds: 5.0\n    max_retries: 3\n    https_only: true\n    default_events:\n      - council.complete\n      - council.error\n\n  observability:\n    log_escalations: true\n```\n\n**Priority**: YAML config \u003e Environment variables \u003e Defaults\n\n#### Option 3: JSON Configuration (Legacy)\n\nCreate `~/.config/llm-council/config.json`:\n\n```json\n{\n  \"council_models\": [\n    \"openai/gpt-4-turbo\",\n    \"anthropic/claude-3-opus\",\n    \"google/gemini-pro\",\n    \"meta-llama/llama-3-70b-instruct\"\n  ],\n  \"chairman_model\": \"anthropic/claude-3-opus\",\n  \"synthesis_mode\": \"consensus\",\n  \"exclude_self_votes\": true,\n  \"style_normalization\": false,\n  \"max_reviewers\": null\n}\n```\n\n#### Option 4: Use Defaults\n\nIf you don't configure anything, these defaults are used:\n- Council: GPT-5.1, Gemini 3 Pro, Claude Sonnet 4.5, Grok 4\n- Chairman: Gemini 3 Pro\n- Mode: consensus\n- Self-vote exclusion: enabled\n\n**Finding Models**:\n- OpenRouter: [openrouter.ai/models](https://openrouter.ai/models)\n- Anthropic: [docs.anthropic.com/models](https://docs.anthropic.com/en/docs/about-claude/models)\n- OpenAI: [platform.openai.com/docs/models](https://platform.openai.com/docs/models)\n- Google: [ai.google.dev/gemini-api/docs/models](https://ai.google.dev/gemini-api/docs/models/gemini)\n\n## Usage\n\n### With Claude Code\n\n```bash\n# First, store your API key securely (one-time setup)\nllm-council setup-key\n\n# Then add the MCP server (key is read from keychain or environment)\nclaude mcp add --transport stdio llm-council --scope user -- llm-council\n```\n\nThen in Claude Code:\n```\nConsult the LLM council about best practices for error handling\n```\n\n### With Claude Desktop\n\nFirst ensure your API key is available (via keychain, environment variable, or `.env` file).\n\nAdd to `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"llm-council\": {\n      \"command\": \"llm-council\"\n    }\n  }\n}\n```\n\n\u003e **Note**: No `env` block needed—the key is resolved from your system keychain or environment automatically.\n\n### With Other MCP Clients\n\nAny MCP client can use the server by running:\n```bash\nllm-council\n```\n\n## Available Tools\n\n### `consult_council`\n\nAsk the LLM council a question and get synthesized guidance.\n\n**Arguments:**\n- `query` (string, required): The question to ask the council\n- `confidence` (string, optional): Response quality level (default: \"high\")\n  - `\"quick\"`: Fast models (mini/flash/haiku), ~30 seconds - fast responses for simple questions\n  - `\"balanced\"`: Mid-tier models (GPT-4o, Sonnet), ~90 seconds - good balance of speed and quality\n  - `\"high\"`: Full council (Opus, GPT-4o), ~180 seconds - comprehensive deliberation\n  - `\"reasoning\"`: Deep thinking models (GPT-5.2, o1, DeepSeek-R1), ~600 seconds - complex reasoning\n- `include_details` (boolean, optional): Include individual model responses and rankings (default: false)\n- `verdict_type` (string, optional): Type of verdict to render (default: \"synthesis\")\n  - `\"synthesis\"`: Free-form natural language synthesis\n  - `\"binary\"`: Go/no-go decision (approved/rejected) with confidence score\n  - `\"tie_breaker\"`: Chairman resolves deadlocked decisions\n- `include_dissent` (boolean, optional): Extract minority opinions from Stage 2 (default: false)\n\n**Example:**\n```\nUse consult_council to ask: \"What are the trade-offs between microservices and monolithic architecture?\"\n```\n\n**Example with confidence level:**\n```\nUse consult_council with confidence=\"quick\" to ask: \"What's the syntax for a Python list comprehension?\"\n```\n\n**Example with Jury Mode (binary verdict):**\n```\nUse consult_council with verdict_type=\"binary\" and include_dissent=true to ask: \"Should we approve this PR that adds caching?\"\n```\n\n### `council_health_check`\n\nVerify the council is working before expensive operations. Returns API connectivity status, configured models, and estimated response times.\n\n**Arguments:** None\n\n**Returns:**\n- `api_key_configured`: Whether an API key was found\n- `key_source`: Where the key came from (\"environment\", \"keychain\", or \"config_file\")\n- `council_size`: Number of models in the council\n- `estimated_duration`: Expected response times for each confidence level\n- `ready`: Whether the council is ready to accept queries\n\n**Example:**\n```\nRun council_health_check to verify the LLM council is working\n```\n\n## How It Works\n\nThe council uses a multi-stage process inspired by ensemble methods and peer review:\n\n```\nUser Query\n    ↓\n┌─────────────────────────────────────────────┐\n│ STAGE 1: Independent Responses              │\n│ • All council models queried in parallel    │\n│ • No knowledge of other responses           │\n│ • Graceful degradation if some fail         │\n└─────────────────────────────────────────────┘\n    ↓\n┌─────────────────────────────────────────────┐\n│ STAGE 1.5: Style Normalization (optional)   │\n│ • Rewrites responses in neutral style       │\n│ • Removes AI preambles and fingerprints     │\n│ • Strengthens anonymization                 │\n└─────────────────────────────────────────────┘\n    ↓\n┌─────────────────────────────────────────────┐\n│ STAGE 2: Anonymous Peer Review              │\n│ • Responses labeled A, B, C (randomized)    │\n│ • XML sandboxing prevents prompt injection  │\n│ • JSON-structured rankings with scores      │\n│ • Self-votes excluded from aggregation      │\n└─────────────────────────────────────────────┘\n    ↓\n┌─────────────────────────────────────────────┐\n│ STAGE 3: Chairman Synthesis                 │\n│ • Receives all responses + rankings         │\n│ • Consensus mode: single best answer        │\n│ • Debate mode: highlights disagreements     │\n└─────────────────────────────────────────────┘\n    ↓\nFinal Response + Metadata\n```\n\nThis approach helps surface diverse perspectives, identify consensus, and produce more balanced, well-reasoned answers.\n\n## Advanced Features\n\n### Self-Vote Exclusion\n\nBy default, each model's vote for its own response is excluded from the aggregate rankings. This prevents self-preference bias.\n\n```bash\nexport LLM_COUNCIL_EXCLUDE_SELF_VOTES=true  # default\n```\n\n### Synthesis Modes\n\n**Consensus Mode** (default): Chairman synthesizes a single best answer.\n\n**Debate Mode**: Chairman highlights areas of agreement, key disagreements, and trade-offs between perspectives.\n\n```bash\nexport LLM_COUNCIL_MODE=debate\n```\n\n### Style Normalization (Stage 1.5)\n\nOptional preprocessing that rewrites all responses in a neutral style before peer review. This strengthens anonymization by removing stylistic \"fingerprints\" that might allow models to recognize each other.\n\n```bash\nexport LLM_COUNCIL_STYLE_NORMALIZATION=true\nexport LLM_COUNCIL_NORMALIZER_MODEL=google/gemini-2.0-flash-001  # fast/cheap\n```\n\n### Stratified Sampling (Large Councils)\n\nFor councils with more than 5 models, you can limit the number of reviewers per response to reduce API costs (O(N²) → O(N×k)):\n\n```bash\nexport LLM_COUNCIL_MAX_REVIEWERS=3\n```\n\n### Reliability Features\n\nThe council includes built-in reliability features for long-running operations:\n\n**Tiered Timeouts**: Graceful degradation under time pressure:\n- Per-model soft deadline: 15s (start planning fallback)\n- Per-model hard deadline: 25s (abandon slow model)\n- Global synthesis trigger: 40s (must start synthesis)\n- Response deadline: 50s (must return something)\n\n**Partial Results**: If some models timeout, the council returns results from the models that responded, with a clear warning indicating which models were excluded.\n\n**Confidence Levels**: Use the `confidence` parameter to trade off speed vs. thoroughness:\n- `quick`: ~20-30 seconds (fastest models)\n- `balanced`: ~45-60 seconds (most models)\n- `high`: ~60-90 seconds (full council, default)\n\n**Progress Feedback**: During deliberation, progress updates show which models have responded and which are still pending:\n```\n✓ claude-opus-4.7 (1/4) | waiting: gpt-5.1, gemini-3-pro, grok-4\n✓ gemini-3-pro (2/4) | waiting: gpt-5.1, grok-4\n```\n\n### Jury Mode (ADR-025b)\n\nTransform the council from a \"summary generator\" to a \"decision engine\" with structured verdicts.\n\n**Verdict Types:**\n\n| Mode | Output | Use Case |\n|------|--------|----------|\n| `synthesis` (default) | Free-form synthesis | General questions, exploration |\n| `binary` | approved/rejected + confidence | CI/CD gates, PR reviews, policy checks |\n| `tie_breaker` | Chairman decides on deadlock | Contentious decisions |\n\n**Binary Verdict Mode:**\n\nReturns structured go/no-go decisions with confidence scores:\n\n```python\n# MCP Tool\nresult = await consult_council(\n    query=\"Should we approve this architectural change?\",\n    verdict_type=\"binary\"\n)\n\n# Returns:\n{\n  \"verdict\": \"approved\",      # or \"rejected\"\n  \"confidence\": 0.75,         # 0.0-1.0 based on council agreement\n  \"rationale\": \"Council agreed the change improves modularity...\"\n}\n```\n\n**Tie-Breaker Mode:**\n\nWhen the council is deadlocked (top scores within 0.1 of each other), the chairman casts the deciding vote:\n\n```python\nresult = await consult_council(\n    query=\"Option A vs Option B for caching strategy?\",\n    verdict_type=\"binary\"\n)\n\n# If deadlocked, returns:\n{\n  \"verdict\": \"approved\",\n  \"confidence\": 0.60,\n  \"rationale\": \"Chairman resolved deadlock based on...\",\n  \"deadlocked\": true  # Flag indicates tie-breaker was needed\n}\n```\n\n**Constructive Dissent:**\n\nExtract minority opinions from Stage 2 peer reviews:\n\n```python\nresult = await consult_council(\n    query=\"Should we migrate to microservices?\",\n    verdict_type=\"binary\",\n    include_dissent=True\n)\n\n# Returns:\n{\n  \"verdict\": \"approved\",\n  \"confidence\": 0.70,\n  \"rationale\": \"Majority supports migration...\",\n  \"dissent\": \"Minority perspective: One reviewer noted scalability concerns with current team size.\"\n}\n```\n\n**Dissent Algorithm:**\n1. Collect all scores from Stage 2 peer reviews\n2. Calculate median and standard deviation per response\n3. Identify outliers (score \u003c median - 1.5 × std)\n4. Extract evaluation text from outliers\n5. Format as minority perspective\n\n**Example: CI/CD Gate Integration:**\n\n```python\nimport asyncio\nfrom llm_council.council import run_full_council\nfrom llm_council.verdict import VerdictType\n\nasync def review_pull_request(pr_diff: str, pr_description: str):\n    \"\"\"Use LLM Council as a PR review gate.\"\"\"\n    query = f\"\"\"\n    Review this pull request and determine if it should be approved.\n\n    Description: {pr_description}\n\n    Changes:\n    {pr_diff}\n    \"\"\"\n\n    stage1, stage2, stage3, metadata = await run_full_council(\n        query,\n        verdict_type=VerdictType.BINARY,\n        include_dissent=True\n    )\n\n    verdict = metadata.get(\"verdict\", {})\n\n    if verdict.get(\"verdict\") == \"approved\" and verdict.get(\"confidence\", 0) \u003e= 0.7:\n        return True, verdict.get(\"rationale\")\n    else:\n        return False, f\"{verdict.get('rationale')}\\n\\nDissent: {verdict.get('dissent', 'None')}\"\n```\n\n**Environment Variables:**\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `LLM_COUNCIL_VERDICT_TYPE` | Default verdict type | synthesis |\n| `LLM_COUNCIL_DEADLOCK_THRESHOLD` | Borda score difference for deadlock | 0.1 |\n| `LLM_COUNCIL_DISSENT_THRESHOLD` | Std deviations below median for outlier | 1.5 |\n| `LLM_COUNCIL_MIN_BORDA_SPREAD` | Minimum spread to surface dissent | 0.0 |\n\n### Structured Rubric Scoring (ADR-016)\n\nBy default, reviewers provide a single 1-10 holistic score. With rubric scoring enabled, reviewers score each response on five dimensions:\n\n| Dimension | Weight | Description |\n|-----------|--------|-------------|\n| **Accuracy** | 35% | Factual correctness, no hallucinations |\n| **Relevance** | 10% | Addresses the actual question asked |\n| **Completeness** | 20% | Covers all aspects of the question |\n| **Conciseness** | 15% | Efficient communication, no padding |\n| **Clarity** | 20% | Well-organized, easy to understand |\n\n**Accuracy Ceiling**: When enabled (default), accuracy acts as a ceiling on the overall score:\n- Accuracy \u003c 5: Score caps at 4.0 (40%) — \"significant errors or worse\"\n- Accuracy 5-6: Score caps at 7.0 (70%) — \"mixed accuracy\"\n- Accuracy ≥ 7: No ceiling — \"mostly accurate or better\"\n\nThis prevents well-written hallucinations from ranking well.\n\n**Scoring Anchors**: Each score level has defined behavioral meaning (see [ADR-016](docs/adr/ADR-016-structured-rubric-scoring.md)):\n- 9-10: Excellent (completely accurate, comprehensive, crystal clear)\n- 7-8: Good (mostly accurate, covers main points)\n- 5-6: Mixed (some errors or gaps)\n- 3-4: Poor (significant issues)\n- 1-2: Failing (fundamentally flawed)\n\n```bash\n# Enable rubric scoring\nexport LLM_COUNCIL_RUBRIC_SCORING=true\n\n# Customize weights (must sum to 1.0)\nexport LLM_COUNCIL_WEIGHT_ACCURACY=0.40\nexport LLM_COUNCIL_WEIGHT_RELEVANCE=0.10\nexport LLM_COUNCIL_WEIGHT_COMPLETENESS=0.20\nexport LLM_COUNCIL_WEIGHT_CONCISENESS=0.10\nexport LLM_COUNCIL_WEIGHT_CLARITY=0.20\n```\n\n### Safety Gate (ADR-016)\n\nWhen enabled, a pass/fail safety check runs before rubric scoring to filter harmful content:\n\n| Pattern | Description |\n|---------|-------------|\n| **dangerous_instructions** | Weapons, explosives, harmful devices |\n| **weapon_making** | Firearm/weapon construction |\n| **malware_hacking** | Unauthorized access, malware |\n| **self_harm** | Self-harm encouragement |\n| **pii_exposure** | Personal information leakage |\n\nResponses that fail safety checks are capped at score 0 regardless of other dimension scores. Educational/defensive content is context-aware and allowed.\n\n```bash\n# Enable safety gate\nexport LLM_COUNCIL_SAFETY_GATE=true\n\n# Customize score cap (default: 0)\nexport LLM_COUNCIL_SAFETY_SCORE_CAP=0.0\n```\n\n### Bias Auditing (ADR-015)\n\nWhen enabled, the council reports per-session bias indicators from peer review scoring:\n\n| Bias Type | Description | Detection Threshold |\n|-----------|-------------|---------------------|\n| **Length-Score Correlation** | Do longer responses score higher? | \\|r\\| \u003e 0.3 |\n| **Reviewer Calibration** | Are some reviewers harsh/generous relative to peers? | Mean ± 1 std from median |\n| **Position Bias** | Does presentation order affect scores? | Variance \u003e 0.5 |\n\n**Output**: The metadata includes a `bias_audit` object with:\n- `length_score_correlation`: Pearson correlation coefficient\n- `length_bias_detected`: Boolean flag\n- `position_score_variance`: Variance of mean scores by presentation position\n- `position_bias_detected`: Boolean flag (derived from anonymization labels A, B, C...)\n- `harsh_reviewers` / `generous_reviewers`: Lists of biased reviewers\n- `overall_bias_risk`: \"low\", \"medium\", or \"high\"\n\n**Important Limitations**: With only 4-5 models per session, these metrics have limited statistical power:\n- Length correlation with n=5 data points can only detect *extreme* biases\n- Position bias from a single ordering cannot distinguish position effects from quality differences\n- Reviewer calibration is relative to the current session only\n\nThese are **per-session indicators** (red flags for extreme anomalies), not statistically robust proof of systematic bias. Interpret with appropriate caution.\n\n```bash\n# Enable bias auditing\nexport LLM_COUNCIL_BIAS_AUDIT=true\n\n# Customize thresholds (optional)\nexport LLM_COUNCIL_LENGTH_CORRELATION_THRESHOLD=0.3\nexport LLM_COUNCIL_POSITION_VARIANCE_THRESHOLD=0.5\n```\n\n### Cross-Session Bias Aggregation (ADR-018)\n\nFor statistically meaningful bias detection across multiple sessions, enable bias persistence:\n\n```bash\n# Enable bias persistence (stores metrics locally)\nexport LLM_COUNCIL_BIAS_PERSISTENCE=true\n\n# Consent level: 0=off, 1=local only (default), 2=anonymous, 3=enhanced, 4=research\nexport LLM_COUNCIL_BIAS_CONSENT=1\n\n# Store path (default: ~/.llm-council/bias_metrics.jsonl)\nexport LLM_COUNCIL_BIAS_STORE=~/.llm-council/bias_metrics.jsonl\n```\n\n**Generate cross-session bias reports:**\n\n```bash\n# Text report (default)\nllm-council bias-report\n\n# JSON output\nllm-council bias-report --format json\n\n# Include detailed reviewer profiles\nllm-council bias-report --verbose\n\n# Limit to last 50 sessions\nllm-council bias-report --sessions 50\n```\n\n**Statistical confidence tiers:**\n\n| Sessions | Confidence | UI Treatment |\n|----------|------------|--------------|\n| N \u003c 10 | Insufficient | \"Collecting data...\" |\n| 10-19 | Preliminary | Warning shown |\n| 20-49 | Moderate | CIs displayed |\n| N \u003e= 50 | High | Full analysis |\n\n### Output Quality Metrics (ADR-036)\n\nQuantify the reliability and quality of council outputs with three core metrics:\n\n| Metric | Range | Description |\n|--------|-------|-------------|\n| **Consensus Strength Score (CSS)** | 0.0-1.0 | Agreement among council members in Stage 2 rankings |\n| **Deliberation Depth Index (DDI)** | 0.0-1.0 | Thoroughness of the deliberation process |\n| **Synthesis Attribution Score (SAS)** | 0.0-1.0 | How well synthesis traces back to source responses |\n\n**CSS Interpretation:**\n\n| Score | Interpretation | Action |\n|-------|---------------|--------|\n| 0.85+ | Strong consensus | High confidence in synthesis |\n| 0.70-0.84 | Moderate consensus | Note minority views |\n| 0.50-0.69 | Weak consensus | Consider `include_dissent=true` |\n| \u003c0.50 | Significant disagreement | Use debate mode |\n\n**SAS Components:**\n- `winner_alignment`: Similarity to top-ranked responses\n- `max_source_alignment`: Best match to any response\n- `hallucination_risk`: 1 - max_source_alignment\n- `grounded`: True if synthesis traces to sources (threshold: 0.6)\n\n**Usage:**\n\nQuality metrics are automatically included in metadata:\n\n```python\nstage1, stage2, stage3, metadata = await run_full_council(query)\n\nquality = metadata.get(\"quality_metrics\", {})\ncore = quality.get(\"core\", {})\n\nprint(f\"Consensus: {core['consensus_strength']:.2f}\")\nprint(f\"Depth: {core['deliberation_depth']:.2f}\")\nprint(f\"Grounded: {core['synthesis_attribution']['grounded']}\")\n```\n\n**MCP Tool Output:**\n\nThe `consult_council` MCP tool displays quality metrics with visual bars:\n\n```\n### Quality Metrics\n- **Consensus Strength**: 0.82 [████████░░]\n- **Deliberation Depth**: 0.74 [███████░░░]\n- **Synthesis Grounded**: ✓ (alignment: 0.89)\n```\n\n**Environment Variables:**\n\n```bash\n# Enable/disable quality metrics (default: true)\nexport LLM_COUNCIL_QUALITY_METRICS=true\n\n# Quality tier: core (OSS), standard, enterprise\nexport LLM_COUNCIL_QUALITY_TIER=core\n```\n\n### Gateway Layer (ADR-023)\n\nThe gateway layer provides an abstraction over LLM API requests with multiple gateway options:\n\n**Available Gateways:**\n| Gateway | Description | Key Features |\n|---------|-------------|--------------|\n| `OpenRouterGateway` | Routes through OpenRouter | 100+ models, single API key |\n| `RequestyGateway` | Routes through Requesty | BYOK support, analytics |\n| `DirectGateway` | Direct provider APIs | Anthropic, OpenAI, Google |\n| `OllamaGateway` | Local LLMs via Ollama | Air-gapped, cost-free, privacy-first |\n\n**Core Features:**\n- **Circuit Breaker**: Prevents cascading failures (CLOSED → OPEN → HALF_OPEN → CLOSED)\n- **Fallback Chains**: Automatic retry with secondary gateways on failure\n- **Per-Gateway Metrics**: Track failure counts, latency, and health status\n- **BYOK Support**: Bring Your Own Key for Requesty and Direct gateways\n\n**Basic Usage:**\n\n```python\nfrom llm_council.gateway import (\n    GatewayRouter, GatewayRequest, CanonicalMessage, ContentBlock,\n    OpenRouterGateway, RequestyGateway, DirectGateway\n)\n\n# Single gateway (OpenRouter)\nrouter = GatewayRouter()\n\n# Multi-gateway with fallback\nrouter = GatewayRouter(\n    gateways={\n        \"openrouter\": OpenRouterGateway(),\n        \"requesty\": RequestyGateway(byok_enabled=True, byok_keys={\"anthropic\": \"sk-ant-...\"}),\n        \"direct\": DirectGateway(provider_keys={\"openai\": \"sk-...\"}),\n    },\n    default_gateway=\"openrouter\",\n    fallback_chains={\"openrouter\": [\"requesty\", \"direct\"]}\n)\n\nrequest = GatewayRequest(\n    model=\"openai/gpt-4o\",\n    messages=[CanonicalMessage(role=\"user\", content=[ContentBlock(type=\"text\", text=\"Hello\")])]\n)\nresponse = await router.complete(request)\n```\n\n**Enable the gateway layer:**\n\n```bash\nexport LLM_COUNCIL_USE_GATEWAY=true\n\n# Optional: Configure specific gateways\nexport REQUESTY_API_KEY=your-requesty-key    # For Requesty\nexport ANTHROPIC_API_KEY=sk-ant-...           # For Direct (Anthropic)\nexport OPENAI_API_KEY=sk-...                  # For Direct (OpenAI)\nexport GOOGLE_API_KEY=...                     # For Direct (Google)\n```\n\n**Circuit Breaker Behavior:**\n- Default: 5 failures to trip the circuit\n- Recovery timeout: 60 seconds\n- Half-open state allows test requests to check recovery\n- Open circuits are skipped in fallback chain\n\nThe gateway layer is currently **opt-in** (default: disabled) for backward compatibility.\n\n### Triage Layer (ADR-020)\n\nThe triage layer provides query classification, model selection optimizations, and confidence-gated routing:\n\n- **Confidence-Gated Fast Path**: Routes simple queries to a single model, escalating to full council when confidence is low\n- **Shadow Council Sampling**: Random 5% sampling validates fast path quality against full council\n- **Rollback Monitoring**: Automatic rollback when disagreement/escalation rates breach thresholds\n- **Wildcard Selection**: Adds domain-specialized models to the council based on query classification\n- **Prompt Optimization**: Per-model prompt adaptation (Claude gets XML, OpenAI gets Markdown)\n- **Complexity Classification**: Heuristic-based with optional Not Diamond API integration\n\n**Domain Categories:**\n| Domain | Description | Specialist Models |\n|--------|-------------|-------------------|\n| CODE | Programming, debugging, algorithms | DeepSeek, Codestral |\n| REASONING | Math, logic, proofs | o1-preview, DeepSeek-R1 |\n| CREATIVE | Stories, poems, fiction | Claude Opus, Command-R+ |\n| MULTILINGUAL | Translation, language | GPT-4o, Command-R+ |\n| GENERAL | General knowledge | Llama 3 (fallback) |\n\n**Enable wildcard selection:**\n\n```bash\nexport LLM_COUNCIL_WILDCARD_ENABLED=true\n```\n\nThis automatically adds a domain specialist to the council based on query classification. For example, a Python coding question will add a DeepSeek model alongside the default council.\n\n**Enable prompt optimization:**\n\n```bash\nexport LLM_COUNCIL_PROMPT_OPTIMIZATION_ENABLED=true\n```\n\nThis applies per-model prompt formatting. Claude receives XML-structured prompts, while other providers receive their preferred format.\n\n**Enable confidence-gated fast path:**\n\n```bash\nexport LLM_COUNCIL_FAST_PATH_ENABLED=true\nexport LLM_COUNCIL_FAST_PATH_CONFIDENCE_THRESHOLD=0.92  # default\n```\n\nWhen enabled, simple queries are routed to a single model. If the model's confidence is below the threshold, the query automatically escalates to the full council. This can reduce costs by 45-55% on simple queries while maintaining quality.\n\n**Fast Path Quality Monitoring:**\n\nThe fast path includes built-in quality monitoring:\n\n| Metric | Threshold | Action |\n|--------|-----------|--------|\n| Shadow disagreement rate | \u003e 8% | Automatic rollback |\n| User escalation rate | \u003e 15% | Automatic rollback |\n| Error rate | \u003e 1.5x baseline | Automatic rollback |\n\nConfigure monitoring:\n\n```bash\nexport LLM_COUNCIL_SHADOW_SAMPLE_RATE=0.05  # 5% shadow sampling\nexport LLM_COUNCIL_ROLLBACK_ENABLED=true\nexport LLM_COUNCIL_ROLLBACK_WINDOW=100  # rolling window size\n```\n\n**Optional Not Diamond Integration:**\n\nFor advanced model routing, integrate with [Not Diamond](https://notdiamond.ai):\n\n```bash\nexport NOT_DIAMOND_API_KEY=\"your-key\"\nexport LLM_COUNCIL_USE_NOT_DIAMOND=true\n```\n\nWhen Not Diamond is unavailable, the system gracefully falls back to heuristic-based classification.\n\nThe triage layer is currently **opt-in** (default: disabled) for backward compatibility.\n\n### Local LLM Support (ADR-025)\n\nRun council deliberations entirely on local hardware using Ollama:\n\n```bash\n# Install with Ollama support\npip install \"llm-council-core[ollama]\"\n\n# Start Ollama (if not already running)\nollama serve\n\n# Pull a model\nollama pull llama3.2\n```\n\n**Use local models in your council:**\n\n```bash\n# Mix local and cloud models\nexport LLM_COUNCIL_MODELS=\"ollama/llama3.2,openai/gpt-4o,anthropic/claude-3-5-sonnet\"\n\n# Or use only local models (air-gapped mode)\nexport LLM_COUNCIL_MODELS=\"ollama/llama3.2,ollama/mistral,ollama/codellama\"\nexport LLM_COUNCIL_CHAIRMAN=\"ollama/llama3.2\"\n```\n\n**Hardware Requirements:**\n\n| Profile | Hardware | Models | Use Case |\n|---------|----------|--------|----------|\n| Minimum | 8+ core CPU, 16GB RAM | 7B quantized | Dev/testing |\n| Recommended | M-series Pro, 32GB unified | 7B-13B | Small council |\n| Professional | 2x RTX 4090, 64GB+ | 70B quantized | Production |\n| Enterprise | Mac Studio 64GB+ | Multiple 70B | Air-gapped |\n\n**Quality Degradation Notice**: Local models typically have reduced capabilities compared to cloud-hosted frontier models. The gateway includes quality notices in responses to inform users when local models are used.\n\n**Configuration:**\n\n```bash\n# Ollama endpoint (default: http://localhost:11434)\nexport LLM_COUNCIL_OLLAMA_BASE_URL=http://localhost:11434\n\n# Timeout for local models (default: 120s - first load can be slow)\nexport LLM_COUNCIL_OLLAMA_TIMEOUT=120.0\n```\n\n### Webhook Notifications (ADR-025)\n\nReceive real-time notifications as the council deliberates:\n\n```python\nfrom llm_council.webhooks import WebhookConfig, WebhookDispatcher, WebhookPayload\n\n# Configure webhook endpoint\nconfig = WebhookConfig(\n    url=\"https://your-server.com/webhook\",\n    events=[\"council.complete\", \"council.error\"],\n    secret=\"your-hmac-secret\"  # Optional, for signature verification\n)\n\n# Dispatch events (used internally by council)\ndispatcher = WebhookDispatcher()\nresult = await dispatcher.dispatch(config, payload)\n```\n\n**Event Types:**\n\n| Event | Description | Payload |\n|-------|-------------|---------|\n| `council.deliberation_start` | Council begins | request_id, models |\n| `council.stage1.complete` | All initial responses received | response_count |\n| `model.vote_cast` | A model submitted rankings | voter, ranking |\n| `council.stage2.complete` | All rankings complete | aggregate_rankings |\n| `council.complete` | Final answer ready | stage3_response, duration_ms |\n| `council.error` | Error occurred | error, partial_results |\n\n**HMAC Signature Verification:**\n\nWebhooks are signed using HMAC-SHA256 for security:\n\n```python\nfrom llm_council.webhooks import verify_webhook_request\n\n# Verify incoming webhook (in your server)\nis_valid = verify_webhook_request(\n    payload=request.body,\n    headers=request.headers,\n    secret=\"your-hmac-secret\"\n)\n```\n\nHeaders included:\n- `X-Council-Signature`: `sha256=\u003chex-digest\u003e`\n- `X-Council-Timestamp`: Unix timestamp\n- `X-Council-Version`: `1.0`\n\n**Configuration:**\n\n```bash\n# Webhook timeout (default: 5s)\nexport LLM_COUNCIL_WEBHOOK_TIMEOUT=5.0\n\n# Max retry attempts (default: 3)\nexport LLM_COUNCIL_WEBHOOK_RETRIES=3\n\n# Require HTTPS (except localhost) - default: true\nexport LLM_COUNCIL_WEBHOOK_HTTPS_ONLY=true\n```\n\n### SSE Streaming (ADR-025)\n\nStream council events in real-time using Server-Sent Events.\n\n**Built-in HTTP Server:**\n\nThe library includes a built-in HTTP server with SSE streaming:\n\n```bash\n# Install with HTTP server support\npip install \"llm-council-core[http]\"\n\n# Start the server\nllm-council serve\n```\n\nThe SSE endpoint is available at `GET /v1/council/stream`:\n\n```bash\n# Stream council deliberation\ncurl -N \"http://localhost:8000/v1/council/stream?prompt=What+is+AI\"\n```\n\n**Custom Integration:**\n\nFor custom FastAPI/Starlette applications:\n\n```python\nfrom llm_council.webhooks import (\n    council_event_generator,\n    SSE_CONTENT_TYPE,\n    get_sse_headers\n)\n\n# In your FastAPI/Starlette endpoint\n@app.get(\"/v1/council/stream\")\nasync def stream_council(prompt: str):\n    return StreamingResponse(\n        council_event_generator(prompt, models=None, api_key=None),\n        media_type=SSE_CONTENT_TYPE,\n        headers=get_sse_headers()\n    )\n```\n\n**Client-side (JavaScript):**\n\n```javascript\nconst source = new EventSource('/v1/council/stream?prompt=...');\n\nsource.addEventListener('council.deliberation_start', (e) =\u003e {\n  console.log('Started:', JSON.parse(e.data));\n});\n\nsource.addEventListener('council.complete', (e) =\u003e {\n  const result = JSON.parse(e.data);\n  console.log('Final answer:', result.stage3_response);\n  source.close();\n});\n```\n\n### Offline Mode (ADR-026)\n\nRun LLM Council without any external metadata calls using the bundled model registry:\n\n```bash\n# Enable offline mode\nexport LLM_COUNCIL_OFFLINE=true\n```\n\nWhen offline mode is enabled:\n- Uses `StaticRegistryProvider` exclusively with 31 bundled models\n- No external API calls for metadata (context windows, pricing, capabilities)\n- All core council operations continue to work\n- Unknown models use safe defaults (4096 context window)\n\nThis implements the \"Sovereign Orchestrator\" philosophy: the system must function as a complete, independent utility without external dependencies.\n\n**Bundled Models (31 total):**\n\n| Provider | Count | Examples |\n|----------|-------|----------|\n| OpenAI | 9 | gpt-4o, gpt-4o-mini, gpt-5.2, gpt-5-mini, o1, o1-preview, o1-mini, o3-mini |\n| Anthropic | 6 | claude-opus-4.7, claude-opus-4.6, claude-sonnet-4.6, claude-haiku-4.5 |\n| Google | 5 | gemini-3-pro, gemini-2.5-pro, gemini-2.0-flash, gemini-1.5-pro |\n| xAI | 2 | grok-4, grok-4.1-fast |\n| DeepSeek | 2 | deepseek-r1, deepseek-chat |\n| Meta | 2 | llama-3.3-70b, llama-3.1-405b |\n| Mistral | 2 | mistral-large-2411, mistral-medium |\n| Ollama | 6 | llama3.2, mistral, qwen2.5:14b, codellama, phi3 |\n\n**Model Metadata API:**\n\n```python\nfrom llm_council.metadata import get_provider\n\n# Get the metadata provider\nprovider = get_provider()\n\n# Query model information\ninfo = provider.get_model_info(\"openai/gpt-4o\")\nprint(f\"Context window: {info.context_window}\")  # 128000\nprint(f\"Quality tier: {info.quality_tier}\")      # frontier\n\n# Check capabilities\nwindow = provider.get_context_window(\"anthropic/claude-opus-4.7\")  # 1000000\nsupports = provider.supports_reasoning(\"openai/o1\")  # True\n\n# List all available models\nmodels = provider.list_available_models()  # 31 models\n```\n\n### Agent Skills (ADR-034)\n\nLLM Council includes agent skills for AI-assisted code verification, review, and CI/CD quality gates. Skills use progressive disclosure to minimize token usage while providing detailed scoring rubrics when needed.\n\n**Available Skills:**\n\n| Skill | Category | Use Case |\n|-------|----------|----------|\n| `council-verify` | verification | General work verification with multi-dimensional scoring |\n| `council-review` | code-review | PR reviews with security, performance, and testing focus |\n| `council-gate` | ci-cd | Quality gates for pipelines with exit codes (0=PASS, 1=FAIL, 2=UNCLEAR) |\n\n**Exit Codes for CI/CD:**\n\n```bash\n# In GitHub Actions or any CI pipeline\nllm-council gate --snapshot $GITHUB_SHA --rubric-focus Security\n\n# Exit codes:\n# 0 = PASS (confidence \u003e= threshold, no blocking issues)\n# 1 = FAIL (blocking issues present)\n# 2 = UNCLEAR (needs human review)\n```\n\n**Skills are located in `.github/skills/`** and work with Claude Code, VS Code Copilot, Cursor, and other MCP-compatible clients.\n\nFor detailed documentation, see the [Skills Guide](https://llm-council.dev/guides/skills/).\n\n### All Environment Variables\n\n#### Gateway Configuration (ADR-023)\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `OPENROUTER_API_KEY` | OpenRouter API key | Required for OpenRouter gateway |\n| `REQUESTY_API_KEY` | Requesty API key | Required for Requesty gateway |\n| `ANTHROPIC_API_KEY` | Anthropic API key | Required for Direct gateway (Anthropic) |\n| `OPENAI_API_KEY` | OpenAI API key | Required for Direct gateway (OpenAI) |\n| `GOOGLE_API_KEY` | Google API key | Required for Direct gateway (Google) |\n| `LLM_COUNCIL_DEFAULT_GATEWAY` | Default gateway (openrouter/requesty/direct) | openrouter |\n| `LLM_COUNCIL_USE_GATEWAY` | Enable gateway layer with circuit breaker | false |\n\n#### Ollama Configuration (ADR-025)\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `LLM_COUNCIL_OLLAMA_BASE_URL` | Ollama API endpoint | http://localhost:11434 |\n| `LLM_COUNCIL_OLLAMA_TIMEOUT` | Timeout for Ollama requests (seconds) | 120.0 |\n| `LLM_COUNCIL_USE_LITELLM` | Enable LiteLLM wrapper for Ollama | true |\n\n#### Webhook Configuration (ADR-025)\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `LLM_COUNCIL_WEBHOOK_TIMEOUT` | Webhook POST timeout (seconds) | 5.0 |\n| `LLM_COUNCIL_WEBHOOK_RETRIES` | Max retry attempts | 3 |\n| `LLM_COUNCIL_WEBHOOK_HTTPS_ONLY` | Require HTTPS (except localhost) | true |\n\n#### Council Configuration\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `LLM_COUNCIL_MODELS` | Comma-separated model list | GPT-5.1, Gemini 3 Pro, Claude 4.5, Grok 4 |\n| `LLM_COUNCIL_CHAIRMAN` | Chairman model | google/gemini-3-pro-preview |\n| `LLM_COUNCIL_MODE` | `consensus` or `debate` | consensus |\n| `LLM_COUNCIL_EXCLUDE_SELF_VOTES` | Exclude self-votes | true |\n| `LLM_COUNCIL_STYLE_NORMALIZATION` | Enable style normalization | false |\n| `LLM_COUNCIL_NORMALIZER_MODEL` | Model for normalization | google/gemini-2.0-flash-001 |\n| `LLM_COUNCIL_MAX_REVIEWERS` | Max reviewers per response | null (all) |\n| `LLM_COUNCIL_RUBRIC_SCORING` | Enable multi-dimensional rubric scoring | false |\n| `LLM_COUNCIL_ACCURACY_CEILING` | Use accuracy as score ceiling | true |\n| `LLM_COUNCIL_WEIGHT_*` | Rubric dimension weights (ACCURACY, RELEVANCE, COMPLETENESS, CONCISENESS, CLARITY) | See above |\n| `LLM_COUNCIL_SAFETY_GATE` | Enable safety pre-check gate | false |\n| `LLM_COUNCIL_SAFETY_SCORE_CAP` | Score cap for failed safety checks | 0.0 |\n| `LLM_COUNCIL_BIAS_AUDIT` | Enable bias auditing (ADR-015) | false |\n| `LLM_COUNCIL_LENGTH_CORRELATION_THRESHOLD` | Length-score correlation threshold for bias detection | 0.3 |\n| `LLM_COUNCIL_POSITION_VARIANCE_THRESHOLD` | Position variance threshold for bias detection | 0.5 |\n| `LLM_COUNCIL_BIAS_PERSISTENCE` | Enable cross-session bias storage (ADR-018) | false |\n| `LLM_COUNCIL_BIAS_STORE` | Path to bias metrics JSONL file | ~/.llm-council/bias_metrics.jsonl |\n| `LLM_COUNCIL_BIAS_CONSENT` | Consent level: 0=off, 1=local, 2=anonymous, 3=enhanced, 4=research | 1 |\n| `LLM_COUNCIL_BIAS_WINDOW_SESSIONS` | Rolling window: max sessions for aggregation | 100 |\n| `LLM_COUNCIL_BIAS_WINDOW_DAYS` | Rolling window: max days for aggregation | 30 |\n| `LLM_COUNCIL_MIN_BIAS_SESSIONS` | Minimum sessions for aggregation analysis | 20 |\n| `LLM_COUNCIL_HASH_SECRET` | Secret for query hashing (RESEARCH consent only) | dev-secret |\n| `LLM_COUNCIL_SUPPRESS_WARNINGS` | Suppress security warnings | false |\n| `LLM_COUNCIL_MODELS_QUICK` | Models for quick tier (ADR-022) | gpt-4o-mini, haiku, gemini-flash |\n| `LLM_COUNCIL_MODELS_BALANCED` | Models for balanced tier (ADR-022) | gpt-4o, sonnet, gemini-pro |\n| `LLM_COUNCIL_MODELS_HIGH` | Models for high tier (ADR-022) | gpt-4o, opus, gemini-3-pro, grok-4 |\n| `LLM_COUNCIL_MODELS_REASONING` | Models for reasoning tier (ADR-022) | gpt-5.2, opus, o1-preview, deepseek-r1 |\n| `LLM_COUNCIL_WILDCARD_ENABLED` | Enable wildcard specialist selection (ADR-020) | false |\n| `LLM_COUNCIL_PROMPT_OPTIMIZATION_ENABLED` | Enable per-model prompt optimization (ADR-020) | false |\n| `LLM_COUNCIL_FAST_PATH_ENABLED` | Enable confidence-gated fast path (ADR-020) | false |\n| `LLM_COUNCIL_FAST_PATH_CONFIDENCE_THRESHOLD` | Confidence threshold for fast path (0.0-1.0) | 0.92 |\n| `LLM_COUNCIL_FAST_PATH_MODEL` | Model for fast path routing | auto |\n| `LLM_COUNCIL_SHADOW_SAMPLE_RATE` | Shadow sampling rate (0.0-1.0) | 0.05 |\n| `LLM_COUNCIL_SHADOW_DISAGREEMENT_THRESHOLD` | Disagreement threshold for shadow samples | 0.08 |\n| `LLM_COUNCIL_ROLLBACK_ENABLED` | Enable rollback metric tracking | true |\n| `LLM_COUNCIL_ROLLBACK_WINDOW` | Rolling window size for metrics | 100 |\n| `LLM_COUNCIL_ROLLBACK_DISAGREEMENT_THRESHOLD` | Shadow disagreement rollback threshold | 0.08 |\n| `LLM_COUNCIL_ROLLBACK_ESCALATION_THRESHOLD` | User escalation rollback threshold | 0.15 |\n| `NOT_DIAMOND_API_KEY` | Not Diamond API key (optional) | - |\n| `LLM_COUNCIL_USE_NOT_DIAMOND` | Enable Not Diamond API integration | false |\n| `LLM_COUNCIL_NOT_DIAMOND_TIMEOUT` | Not Diamond API timeout in seconds | 5.0 |\n| `LLM_COUNCIL_NOT_DIAMOND_CACHE_TTL` | Not Diamond response cache TTL in seconds | 300 |\n\n## Credits \u0026 Attribution Continued\n\nThis project is a derivative work based on the original [llm-council](https://github.com/karpathy/llm-council) by Andrej Karpathy.\n\n**Original Work:**\n- Concept and 3-stage council orchestration: Andrej Karpathy\n- Core council logic (Stage 1-3 process)\n- OpenRouter integration\n\n**Derivative Work by Amiable:**\n- MCP (Model Context Protocol) server implementation\n- Removal of web frontend (focus on MCP functionality)\n- Python package structure for PyPI distribution\n- User-configurable model selection\n- Enhanced features (style normalization, self-vote exclusion, synthesis modes)\n- Test suite and modern packaging standards\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famiable-dev%2Fllm-council","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famiable-dev%2Fllm-council","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famiable-dev%2Fllm-council/lists"}