council-gate 1.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. council_gate-1.2.2/.claude-plugin/marketplace.json +16 -0
  2. council_gate-1.2.2/.claude-plugin/plugin.json +13 -0
  3. council_gate-1.2.2/.dockerignore +19 -0
  4. council_gate-1.2.2/.github/workflows/docker.yml +47 -0
  5. council_gate-1.2.2/.github/workflows/release-test.yml +65 -0
  6. council_gate-1.2.2/.github/workflows/release.yml +79 -0
  7. council_gate-1.2.2/.github/workflows/test.yml +40 -0
  8. council_gate-1.2.2/.gitignore +26 -0
  9. council_gate-1.2.2/.pre-commit-config.yaml +21 -0
  10. council_gate-1.2.2/CHANGELOG.md +38 -0
  11. council_gate-1.2.2/Dockerfile +25 -0
  12. council_gate-1.2.2/LICENSE +21 -0
  13. council_gate-1.2.2/PKG-INFO +261 -0
  14. council_gate-1.2.2/README.md +206 -0
  15. council_gate-1.2.2/SECURITY.md +40 -0
  16. council_gate-1.2.2/commands/review.md +50 -0
  17. council_gate-1.2.2/install.ps1 +52 -0
  18. council_gate-1.2.2/install.sh +55 -0
  19. council_gate-1.2.2/integrations/README.md +16 -0
  20. council_gate-1.2.2/integrations/claude-code/council-gate/SKILL.md +62 -0
  21. council_gate-1.2.2/integrations/codex/README.md +52 -0
  22. council_gate-1.2.2/integrations/github-action/README.md +29 -0
  23. council_gate-1.2.2/integrations/github-action/action.yml +45 -0
  24. council_gate-1.2.2/pyproject.toml +76 -0
  25. council_gate-1.2.2/skills/council-gate.md +51 -0
  26. council_gate-1.2.2/src/council_gate/__init__.py +15 -0
  27. council_gate-1.2.2/src/council_gate/_assets/__init__.py +0 -0
  28. council_gate-1.2.2/src/council_gate/_assets/analysis_review.md +18 -0
  29. council_gate-1.2.2/src/council_gate/_assets/eng_review.md +10 -0
  30. council_gate-1.2.2/src/council_gate/_assets/env.example +36 -0
  31. council_gate-1.2.2/src/council_gate/_assets/escalation.md +10 -0
  32. council_gate-1.2.2/src/council_gate/_assets/general_review.md +10 -0
  33. council_gate-1.2.2/src/council_gate/_assets/proposal_review.md +17 -0
  34. council_gate-1.2.2/src/council_gate/cli.py +627 -0
  35. council_gate-1.2.2/src/council_gate/council.py +61 -0
  36. council_gate-1.2.2/src/council_gate/escalation.py +39 -0
  37. council_gate-1.2.2/src/council_gate/gate.py +129 -0
  38. council_gate-1.2.2/src/council_gate/ingest.py +110 -0
  39. council_gate-1.2.2/src/council_gate/parsing.py +50 -0
  40. council_gate-1.2.2/src/council_gate/providers.py +159 -0
  41. council_gate-1.2.2/src/council_gate/redaction.py +130 -0
  42. council_gate-1.2.2/src/council_gate/types.py +24 -0
  43. council_gate-1.2.2/tests/__init__.py +0 -0
  44. council_gate-1.2.2/tests/test_council.py +60 -0
  45. council_gate-1.2.2/tests/test_escalation.py +24 -0
  46. council_gate-1.2.2/tests/test_gate.py +67 -0
  47. council_gate-1.2.2/tests/test_ingest.py +78 -0
  48. council_gate-1.2.2/tests/test_parsing.py +23 -0
  49. council_gate-1.2.2/tests/test_providers.py +99 -0
  50. council_gate-1.2.2/tests/test_redaction.py +188 -0
  51. council_gate-1.2.2/uv.lock +1399 -0
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "council-gate",
3
+ "owner": {
4
+ "name": "AdishAssain",
5
+ "url": "https://github.com/AdishAssain"
6
+ },
7
+ "plugins": [
8
+ {
9
+ "name": "council-gate",
10
+ "source": ".",
11
+ "description": "Cross-model adversarial review for docs, proposals, and PR diffs.",
12
+ "version": "1.2.1",
13
+ "category": "review"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "council-gate",
3
+ "version": "1.2.1",
4
+ "description": "Cross-model adversarial review of docs, proposals, and PR diffs. Runs your artifact past frontier LLMs from different providers, measures disagreement, and routes consensus vs disagreement to an explicit escalation channel.",
5
+ "author": {
6
+ "name": "council-gate contributors",
7
+ "url": "https://github.com/AdishAssain/council-gate"
8
+ },
9
+ "homepage": "https://github.com/AdishAssain/council-gate",
10
+ "repository": "https://github.com/AdishAssain/council-gate",
11
+ "license": "MIT",
12
+ "keywords": ["review", "llm", "ensemble", "evaluation", "proposal", "pr-review"]
13
+ }
@@ -0,0 +1,19 @@
1
+ .git
2
+ .github
3
+ .venv
4
+ venv
5
+ __pycache__
6
+ *.pyc
7
+ .pytest_cache
8
+ .ruff_cache
9
+ .mypy_cache
10
+ dist
11
+ build
12
+ *.egg-info
13
+ notes
14
+ tests
15
+ CLAUDE.md
16
+ .claude
17
+ .env
18
+ .env.*
19
+ council-gate-*.md
@@ -0,0 +1,47 @@
1
+ name: docker
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ["v*"]
7
+ pull_request:
8
+ paths: [Dockerfile, .dockerignore, .github/workflows/docker.yml]
9
+
10
+ permissions:
11
+ contents: read
12
+ packages: write
13
+
14
+ jobs:
15
+ build:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - uses: docker/setup-buildx-action@v3
21
+
22
+ - uses: docker/login-action@v3
23
+ if: github.event_name != 'pull_request'
24
+ with:
25
+ registry: ghcr.io
26
+ username: ${{ github.actor }}
27
+ password: ${{ secrets.GITHUB_TOKEN }}
28
+
29
+ - uses: docker/metadata-action@v5
30
+ id: meta
31
+ with:
32
+ images: ghcr.io/${{ github.repository_owner }}/council-gate
33
+ tags: |
34
+ type=ref,event=branch
35
+ type=ref,event=pr
36
+ type=semver,pattern={{version}}
37
+ type=semver,pattern={{major}}.{{minor}}
38
+ type=raw,value=latest,enable={{is_default_branch}}
39
+
40
+ - uses: docker/build-push-action@v6
41
+ with:
42
+ context: .
43
+ push: ${{ github.event_name != 'pull_request' }}
44
+ tags: ${{ steps.meta.outputs.tags }}
45
+ labels: ${{ steps.meta.outputs.labels }}
46
+ cache-from: type=gha
47
+ cache-to: type=gha,mode=max
@@ -0,0 +1,65 @@
1
+ # Dry-run publish to TestPyPI. Manually triggered from the Actions tab.
2
+ # Use this BEFORE tagging v* to catch metadata / OIDC / wheel issues without
3
+ # burning a real PyPI version number.
4
+ #
5
+ # ONE-TIME SETUP (mirrors release.yml, but on test.pypi.org):
6
+ # 1. https://test.pypi.org/manage/account/publishing/ → Add pending publisher:
7
+ # Project name: council-gate
8
+ # Owner: AdishAssain
9
+ # Repository: council-gate
10
+ # Workflow name: release-test.yml
11
+ # Environment: testpypi ← matches `environment:` below
12
+ # 2. GitHub → Settings → Environments → New environment named `testpypi`
13
+ #
14
+ # Then to dry-run: Actions tab → "release-test" → "Run workflow" (button).
15
+ # Verify install:
16
+ # uv pip install --index-url https://test.pypi.org/simple/ \
17
+ # --extra-index-url https://pypi.org/simple/ \
18
+ # council-gate==<version>
19
+ #
20
+ # Note: TestPyPI also rejects re-uploads of the same version. If you need to
21
+ # re-test, bump the dev suffix in pyproject.toml (e.g. 1.2.2 → 1.2.2.dev1)
22
+ # before re-running. The .devN suffix doesn't affect the eventual real release.
23
+
24
+ name: release-test
25
+
26
+ on:
27
+ workflow_dispatch:
28
+
29
+ permissions:
30
+ contents: read
31
+
32
+ jobs:
33
+ build:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: astral-sh/setup-uv@v3
38
+ with:
39
+ enable-cache: true
40
+ - name: Build sdist + wheel
41
+ run: uv build
42
+ - name: Verify metadata
43
+ run: uvx twine check dist/*
44
+ - name: Upload artifacts
45
+ uses: actions/upload-artifact@v4
46
+ with:
47
+ name: dist
48
+ path: dist/
49
+
50
+ publish-testpypi:
51
+ needs: build
52
+ runs-on: ubuntu-latest
53
+ environment:
54
+ name: testpypi
55
+ url: https://test.pypi.org/p/council-gate
56
+ permissions:
57
+ id-token: write
58
+ steps:
59
+ - uses: actions/download-artifact@v4
60
+ with:
61
+ name: dist
62
+ path: dist/
63
+ - uses: pypa/gh-action-pypi-publish@release/v1
64
+ with:
65
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,79 @@
1
+ # Publishes council-gate to PyPI on every v* tag, via PyPI Trusted Publishing
2
+ # (OIDC — no API tokens stored in GitHub).
3
+ #
4
+ # ONE-TIME SETUP (Adish, you must do this on pypi.org BEFORE the first tag):
5
+ #
6
+ # 1. Go to https://pypi.org/manage/account/publishing/
7
+ # 2. Click "Add a new pending publisher" (yes, even before the project exists)
8
+ # 3. Fill in:
9
+ # Project name: council-gate
10
+ # Owner: AdishAssain
11
+ # Repository: council-gate
12
+ # Workflow name: release.yml
13
+ # Environment: pypi ← must match `environment:` below
14
+ # 4. In this GitHub repo: Settings → Environments → New environment named `pypi`
15
+ # (no protection rules needed for personal repos; add reviewers if you want
16
+ # a manual approval gate before each publish).
17
+ #
18
+ # Then to release: bump version in pyproject.toml + CHANGELOG, commit, then:
19
+ # git tag v1.2.2 && git push origin v1.2.2
20
+ # This workflow takes over from there.
21
+
22
+ name: release
23
+
24
+ on:
25
+ push:
26
+ tags: ["v*"]
27
+
28
+ permissions:
29
+ contents: read
30
+
31
+ jobs:
32
+ build:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - uses: astral-sh/setup-uv@v3
37
+ with:
38
+ enable-cache: true
39
+ - name: Build sdist + wheel
40
+ run: uv build
41
+ - name: Verify metadata
42
+ run: uvx twine check dist/*
43
+ - name: Upload artifacts
44
+ uses: actions/upload-artifact@v4
45
+ with:
46
+ name: dist
47
+ path: dist/
48
+
49
+ publish-pypi:
50
+ needs: build
51
+ runs-on: ubuntu-latest
52
+ environment:
53
+ name: pypi
54
+ url: https://pypi.org/p/council-gate
55
+ permissions:
56
+ id-token: write # required for PyPI Trusted Publishing OIDC
57
+ steps:
58
+ - uses: actions/download-artifact@v4
59
+ with:
60
+ name: dist
61
+ path: dist/
62
+ - uses: pypa/gh-action-pypi-publish@release/v1
63
+
64
+ github-release:
65
+ needs: publish-pypi
66
+ runs-on: ubuntu-latest
67
+ permissions:
68
+ contents: write
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+ - uses: actions/download-artifact@v4
72
+ with:
73
+ name: dist
74
+ path: dist/
75
+ - uses: softprops/action-gh-release@v2
76
+ with:
77
+ files: dist/*
78
+ generate_release_notes: true
79
+ body_path: CHANGELOG.md
@@ -0,0 +1,40 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Set up uv
15
+ uses: astral-sh/setup-uv@v5
16
+ with:
17
+ enable-cache: true
18
+
19
+ - name: Set up Python
20
+ run: uv python install 3.12
21
+
22
+ - name: Sync deps
23
+ run: uv sync --extra dev
24
+
25
+ - name: Lint
26
+ run: uv run ruff check .
27
+
28
+ - name: Type-check
29
+ run: uv run mypy src/ || true # informational until strict-typed
30
+
31
+ - name: Test
32
+ run: uv run pytest -v
33
+
34
+ - name: Build wheel
35
+ run: uv build
36
+
37
+ - name: Sanity-check installed CLI resolves
38
+ run: |
39
+ uv pip install dist/*.whl
40
+ uv run council-gate --help
@@ -0,0 +1,26 @@
1
+ .env
2
+ .env.*
3
+ !.env.example
4
+
5
+ .venv/
6
+ venv/
7
+ __pycache__/
8
+ *.py[cod]
9
+ *.egg-info/
10
+ .pytest_cache/
11
+ .ruff_cache/
12
+ .mypy_cache/
13
+
14
+ dist/
15
+ build/
16
+
17
+ .DS_Store
18
+ .idea/
19
+ .vscode/
20
+
21
+ notes/
22
+ dist/
23
+
24
+ CLAUDE.md
25
+ .claude/
26
+ .smoke-venv/
@@ -0,0 +1,21 @@
1
+ # Run on every commit. Install once: `uv run pre-commit install`
2
+ # (pre-commit is in the dev extras: `uv sync --extra dev` already pulls it.)
3
+ #
4
+ # Mirrors what CI runs. Catching failures here prevents red-X commits.
5
+
6
+ repos:
7
+ - repo: https://github.com/astral-sh/ruff-pre-commit
8
+ rev: v0.6.9
9
+ hooks:
10
+ - id: ruff
11
+ args: [--fix]
12
+ - id: ruff-format
13
+
14
+ - repo: local
15
+ hooks:
16
+ - id: pytest
17
+ name: pytest
18
+ entry: uv run pytest -q
19
+ language: system
20
+ pass_filenames: false
21
+ stages: [pre-commit]
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ ## Stability
4
+
5
+ > **`council-gate` is pre-stable.** While the major version is `1.x` for ergonomics (the tool is functionally complete and shipping real reviews), the API surface — CLI flags, env var names, and report format — is **not frozen** until `2.0`. Minor versions may break things. Pin a version in CI / scripts.
6
+ >
7
+ > Until 2.0, treat version bumps as 0Ver-style: any release can change behaviour. Read the entry below before upgrading.
8
+
9
+ ## 1.2.2 — 2026-05-06
10
+
11
+ PyPI-readiness housekeeping. No user-visible behavior change.
12
+
13
+ - `pyproject.toml`: added `[project.authors]`, fixed `Operating System :: POSIX` → `OS Independent` (we ship Windows + Docker), added `Documentation` and `Changelog` to `[project.urls]`, added `Programming Language :: Python :: 3.13` classifier, bumped `Development Status :: 3 - Alpha` → `4 - Beta`.
14
+ - `.github/workflows/release.yml`: PyPI publishing on `v*` tag via Trusted Publishing (OIDC, no API tokens). Also attaches wheels to a GitHub Release.
15
+ - Verified: `uv build` produces clean sdist + wheel, `twine check` passes, wheel installs in a fresh venv with the entrypoint resolving.
16
+
17
+ ## 1.2.1 — 2026-05-06
18
+
19
+ - One-line installer for macOS/Linux/WSL (`install.sh`) and Windows (`install.ps1`). Both auto-install `uv`, install `council-gate`, and update your shell PATH so the binary works in fresh terminals — fixes the "command not found after restart" friction.
20
+ - Docker image published to `ghcr.io/adishassain/council-gate:latest` (and per-version tags). Hermetic, no Python required on host, ideal for CI.
21
+ - `council-gate update` now also runs `uv tool update-shell` so existing users get the PATH fix on next upgrade.
22
+
23
+ ## 1.2.0 — 2026-05-06
24
+
25
+ - Multi-format ingestion: `.docx`, `.pdf`, `.pptx`, `.xlsx`, `.odt`, `.rtf`, `.epub` are now first-class inputs alongside `.md`/`.diff`/source code. Office formats are converted via [MarkItDown](https://github.com/microsoft/markitdown) before review.
26
+ - Smart `--mode` default: `.docx`/`.pdf`/`.odt` artifacts default to `proposal` review; everything else stays on `eng`. Override with `--mode` as before.
27
+ - Friendly errors throughout: file-load failures, missing dependencies, and unexpected crashes now print plain-English messages instead of Python tracebacks. `--verbose` re-enables full tracebacks.
28
+ - More resilient PATH setup: `council-gate init` now writes to both `.zshrc`+`.zprofile` (zsh) and `.bashrc`+`.bash_profile` (bash), so the binary survives a terminal restart on macOS where Terminal.app launches login shells.
29
+ - `council-gate doctor` now reports the resolved `council-gate` binary path.
30
+ - Helpful messages for unsupported Apple iWork formats (`.pages`, `.numbers`, `.keynote`, `.gdoc`) telling the user how to export.
31
+
32
+ ## 1.1.0
33
+
34
+ - README review-modes table; version bump.
35
+
36
+ ## 1.0.0
37
+
38
+ - Initial public release.
@@ -0,0 +1,25 @@
1
+ # Hermetic council-gate image. ~150MB, no venv state, runs as non-root.
2
+ # Usage:
3
+ # docker run --rm -v "$PWD:/work" -w /work \
4
+ # -e OPENROUTER_API_KEY=sk-or-... \
5
+ # ghcr.io/adishassain/council-gate review proposal.docx
6
+
7
+ FROM python:3.12-slim
8
+
9
+ # uv for the install — same toolchain as the host installer
10
+ COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
11
+
12
+ WORKDIR /opt/council-gate
13
+ COPY pyproject.toml README.md LICENSE ./
14
+ COPY src ./src
15
+
16
+ # System install (no venv) so the entrypoint resolves without activation
17
+ RUN uv pip install --system --no-cache .
18
+
19
+ # Non-root user — review jobs must not run as root inside the container
20
+ RUN useradd --create-home --shell /bin/bash council
21
+ USER council
22
+ WORKDIR /work
23
+
24
+ ENTRYPOINT ["council-gate"]
25
+ CMD ["--help"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 council-gate contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.