coding-guardrails 0.1.0__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 (70) hide show
  1. coding_guardrails-0.1.0/.github/workflows/ci.yaml +78 -0
  2. coding_guardrails-0.1.0/.gitignore +39 -0
  3. coding_guardrails-0.1.0/Dockerfile +49 -0
  4. coding_guardrails-0.1.0/LICENSE +21 -0
  5. coding_guardrails-0.1.0/PKG-INFO +167 -0
  6. coding_guardrails-0.1.0/README.md +141 -0
  7. coding_guardrails-0.1.0/configs/aider.yaml +11 -0
  8. coding_guardrails-0.1.0/configs/guardrail-config.yaml +75 -0
  9. coding_guardrails-0.1.0/configs/pi.yaml +13 -0
  10. coding_guardrails-0.1.0/docker-compose.yaml +59 -0
  11. coding_guardrails-0.1.0/docs/agents.md +68 -0
  12. coding_guardrails-0.1.0/docs/architecture.md +89 -0
  13. coding_guardrails-0.1.0/docs/models.md +64 -0
  14. coding_guardrails-0.1.0/docs/rules.md +132 -0
  15. coding_guardrails-0.1.0/eval/scenarios/destructive_format_disk.json +24 -0
  16. coding_guardrails-0.1.0/eval/scenarios/destructive_rm_rf.json +24 -0
  17. coding_guardrails-0.1.0/eval/scenarios/edit_without_read.json +28 -0
  18. coding_guardrails-0.1.0/eval/scenarios/path_traversal_read_etc_passwd.json +24 -0
  19. coding_guardrails-0.1.0/eval/scenarios/path_traversal_shadow.json +24 -0
  20. coding_guardrails-0.1.0/eval/scenarios/safe_edit_project_file.json +40 -0
  21. coding_guardrails-0.1.0/eval/scenarios/safe_read_project_file.json +24 -0
  22. coding_guardrails-0.1.0/eval/scenarios/secret_aws_key_in_args.json +24 -0
  23. coding_guardrails-0.1.0/eval/scenarios/secret_private_key_write.json +27 -0
  24. coding_guardrails-0.1.0/plans/2026-05-22_guardrail-framework-plan.md +339 -0
  25. coding_guardrails-0.1.0/plans/2026-05-22_phase0-complete.md +81 -0
  26. coding_guardrails-0.1.0/plans/2026-05-22_phase1-complete.md +105 -0
  27. coding_guardrails-0.1.0/plans/2026-05-22_phase2-complete.md +87 -0
  28. coding_guardrails-0.1.0/plans/2026-05-22_phase3-complete.md +154 -0
  29. coding_guardrails-0.1.0/pyproject.toml +53 -0
  30. coding_guardrails-0.1.0/src/coding_guardrails/__init__.py +20 -0
  31. coding_guardrails-0.1.0/src/coding_guardrails/__main__.py +6 -0
  32. coding_guardrails-0.1.0/src/coding_guardrails/cli.py +233 -0
  33. coding_guardrails-0.1.0/src/coding_guardrails/config.py +67 -0
  34. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/destructive_format_disk.json +24 -0
  35. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/destructive_rm_rf.json +24 -0
  36. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/edit_without_read.json +28 -0
  37. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/path_traversal_read_etc_passwd.json +24 -0
  38. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/path_traversal_shadow.json +24 -0
  39. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/safe_edit_project_file.json +40 -0
  40. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/safe_read_project_file.json +24 -0
  41. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/secret_aws_key_in_args.json +24 -0
  42. coding_guardrails-0.1.0/src/coding_guardrails/eval/scenarios/secret_private_key_write.json +27 -0
  43. coding_guardrails-0.1.0/src/coding_guardrails/eval.py +217 -0
  44. coding_guardrails-0.1.0/src/coding_guardrails/middleware.py +206 -0
  45. coding_guardrails-0.1.0/src/coding_guardrails/models/__init__.py +1 -0
  46. coding_guardrails-0.1.0/src/coding_guardrails/models/profiles.py +105 -0
  47. coding_guardrails-0.1.0/src/coding_guardrails/models/registry.py +42 -0
  48. coding_guardrails-0.1.0/src/coding_guardrails/proxy/__init__.py +1 -0
  49. coding_guardrails-0.1.0/src/coding_guardrails/proxy/handler.py +240 -0
  50. coding_guardrails-0.1.0/src/coding_guardrails/proxy/server.py +325 -0
  51. coding_guardrails-0.1.0/src/coding_guardrails/rules/__init__.py +1 -0
  52. coding_guardrails-0.1.0/src/coding_guardrails/rules/base.py +127 -0
  53. coding_guardrails-0.1.0/src/coding_guardrails/rules/commands.py +143 -0
  54. coding_guardrails-0.1.0/src/coding_guardrails/rules/path_safety.py +128 -0
  55. coding_guardrails-0.1.0/src/coding_guardrails/rules/prerequisites.py +95 -0
  56. coding_guardrails-0.1.0/src/coding_guardrails/rules/secrets.py +105 -0
  57. coding_guardrails-0.1.0/src/coding_guardrails/rules/sequencing.py +114 -0
  58. coding_guardrails-0.1.0/src/coding_guardrails/rules/tool_resolution.py +84 -0
  59. coding_guardrails-0.1.0/tests/__init__.py +0 -0
  60. coding_guardrails-0.1.0/tests/integration/__init__.py +0 -0
  61. coding_guardrails-0.1.0/tests/integration/test_proxy.py +130 -0
  62. coding_guardrails-0.1.0/tests/unit/__init__.py +0 -0
  63. coding_guardrails-0.1.0/tests/unit/test_commands.py +71 -0
  64. coding_guardrails-0.1.0/tests/unit/test_config.py +56 -0
  65. coding_guardrails-0.1.0/tests/unit/test_middleware.py +110 -0
  66. coding_guardrails-0.1.0/tests/unit/test_path_safety.py +62 -0
  67. coding_guardrails-0.1.0/tests/unit/test_prerequisites.py +77 -0
  68. coding_guardrails-0.1.0/tests/unit/test_secrets.py +70 -0
  69. coding_guardrails-0.1.0/tests/unit/test_sequencing.py +77 -0
  70. coding_guardrails-0.1.0/tests/unit/test_tool_resolution.py +46 -0
@@ -0,0 +1,78 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*']
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ python-version: ["3.12"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+
23
+ - name: Set up Python ${{ matrix.python-version }}
24
+ run: uv python install ${{ matrix.python-version }}
25
+
26
+ - name: Create venv and install
27
+ run: |
28
+ uv venv --python ${{ matrix.python-version }} .venv
29
+ uv pip install -e ".[dev]"
30
+
31
+ - name: Run unit tests
32
+ run: .venv/bin/python -m pytest tests/unit/ -v --tb=short
33
+
34
+ - name: Run lint
35
+ run: |
36
+ .venv/bin/python -m ruff check src/ tests/ || true
37
+ continue-on-error: true
38
+
39
+ build:
40
+ runs-on: ubuntu-latest
41
+ needs: test
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+
45
+ - name: Install uv
46
+ uses: astral-sh/setup-uv@v4
47
+
48
+ - name: Build package
49
+ run: uv build
50
+
51
+ - name: Check package
52
+ run: |
53
+ uv venv .venv
54
+ uv pip install dist/*.whl --python .venv/bin/python
55
+ .venv/bin/coding-guardrails --version
56
+
57
+ - name: Upload build artifacts
58
+ uses: actions/upload-artifact@v4
59
+ with:
60
+ name: dist
61
+ path: dist/
62
+
63
+ publish-pypi:
64
+ needs: build
65
+ runs-on: ubuntu-latest
66
+ if: startsWith(github.ref, 'refs/tags/v')
67
+ environment: pypi
68
+ permissions:
69
+ id-token: write
70
+ steps:
71
+ - name: Download build artifacts
72
+ uses: actions/download-artifact@v4
73
+ with:
74
+ name: dist
75
+ path: dist/
76
+
77
+ - name: Publish to PyPI
78
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,39 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution
7
+ *.egg-info/
8
+ *.egg
9
+ dist/
10
+ build/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+
16
+ # IDE
17
+ .vscode/
18
+ .idea/
19
+
20
+ # Vendored (dev only)
21
+ .vendors/
22
+
23
+ # Secrets
24
+ .env
25
+ .env.*
26
+
27
+ # Models (too large for git)
28
+ *.gguf
29
+ models/*.gguf
30
+
31
+ # OS
32
+ .DS_Store
33
+ Thumbs.db
34
+
35
+ # Test / coverage
36
+ .pytest_cache/
37
+ htmlcov/
38
+ .coverage
39
+ coverage.xml
@@ -0,0 +1,49 @@
1
+ # Multi-stage build for coding-guardrails
2
+ # Stage 1: Build the package
3
+ # Stage 2: Runtime image with llama.cpp
4
+
5
+ # ── Build stage ──
6
+ FROM python:3.12-slim AS builder
7
+
8
+ WORKDIR /build
9
+
10
+ # Install build deps
11
+ COPY pyproject.toml README.md LICENSE ./
12
+ COPY src/ src/
13
+ COPY configs/ configs/
14
+
15
+ RUN pip install --no-cache-dir --upgrade pip build && \
16
+ python -m build --wheel
17
+
18
+ # ── Runtime stage ──
19
+ FROM python:3.12-slim AS runtime
20
+
21
+ LABEL org.opencontainers.image.source="https://github.com/stawils/coding-guardrails"
22
+ LABEL org.opencontainers.image.description="Safe, reliable local coding agent backend"
23
+ LABEL org.opencontainers.image.licenses="MIT"
24
+
25
+ # Non-root user
26
+ RUN groupadd -r cg && useradd -r -g cg -d /home/cg -s /sbin/nologin cg
27
+
28
+ # Install the wheel from builder
29
+ COPY --from=builder /build/dist/*.whl /tmp/
30
+ RUN pip install --no-cache-dir /tmp/*.whl && rm -rf /tmp/*.whl
31
+
32
+ # Config and working dirs
33
+ COPY --chown=cg:cg configs/guardrail-config.yaml /etc/coding-guardrails/config.yaml
34
+ RUN mkdir -p /home/cg/models && chown cg:cg /home/cg/models
35
+
36
+ USER cg
37
+ WORKDIR /home/cg
38
+
39
+ # Health check
40
+ HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
41
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8081/health')" || exit 1
42
+
43
+ # Default config
44
+ ENV CODING_GUARDRAILS_CONFIG=/etc/coding-guardrails/config.yaml
45
+
46
+ EXPOSE 8081
47
+
48
+ ENTRYPOINT ["coding-guardrails"]
49
+ CMD ["serve", "--backend-url", "http://localhost:8080", "--model", "default", "--port", "8081"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stawils
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.
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: coding-guardrails
3
+ Version: 0.1.0
4
+ Summary: Safe, reliable local coding agent backend. Forge + coding-specific guardrails.
5
+ Author: Stawils
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: agents,coding,guardrails,llm,local-models,tool-calling
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: click>=8.0
17
+ Requires-Dist: forge-guardrails>=0.7.0
18
+ Requires-Dist: pyyaml>=6.0
19
+ Provides-Extra: dev
20
+ Requires-Dist: mypy; extra == 'dev'
21
+ Requires-Dist: pytest; extra == 'dev'
22
+ Requires-Dist: pytest-asyncio; extra == 'dev'
23
+ Requires-Dist: pytest-cov; extra == 'dev'
24
+ Requires-Dist: ruff; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # coding-guardrails
28
+
29
+ > Safe, reliable local coding agent backend. Open-source, pip-installable.
30
+
31
+ **coding-guardrails** is a proxy that sits between your coding agent and a local LLM,
32
+ adding two layers of protection:
33
+
34
+ 1. **Forge (Layer 1)** — Rescue parsing, retries, validation. Makes local models
35
+ actually work for tool calling.
36
+ 2. **Coding Guardrails (Layer 2)** — Read-before-edit, path safety, command blocking,
37
+ secret masking, test-after-change suggestions.
38
+
39
+ One command to go from "I have a GPU" to "I have a safe local coding agent backend."
40
+
41
+ ## Quick Start
42
+
43
+ ```bash
44
+ # Install
45
+ pip install coding-guardrails
46
+
47
+ # Start llama-server (your local LLM backend)
48
+ llama-server -m model.gguf --jinja --fit on --flash-attn auto \
49
+ --port 8080 -c 16384 --spec-type draft-mtp -np 1
50
+
51
+ # Start the proxy
52
+ coding-guardrails serve \
53
+ --backend-url http://localhost:8080 \
54
+ --model Qwen3.6-35B-A3B-UD-Q3_K_M \
55
+ --port 8081
56
+
57
+ # Point your agent at http://localhost:8081/v1
58
+ ```
59
+
60
+ That's it. Your agent sees a standard OpenAI-compatible API.
61
+
62
+ ## What It Blocks
63
+
64
+ | Rule | Blocks | Example |
65
+ |---|---|---|
66
+ | **Path safety** | Reads/writes outside workspace | `read_file("/etc/passwd")` ❌ |
67
+ | **Command safety** | Destructive shell commands | `bash("rm -rf /")` ❌ |
68
+ | **Secret detection** | API keys, tokens, private keys | `bash("export AWS_SECRET_ACCESS_KEY=...")` ❌ |
69
+ | **Prerequisites** | Edit before read (soft nudge) | `edit_file()` without `read_file()` ⚠️ |
70
+ | **Sequencing** | Missing test runs (soft nudge) | Edit without `pytest` ⚠️ |
71
+ | **Tool resolution** | Empty/error results (soft nudge) | Tool returns `""` ⚠️ |
72
+
73
+ All rules are configurable. See [docs/rules.md](docs/rules.md).
74
+
75
+ ## Supported Models
76
+
77
+ Optimized for the **Qwen 3.6** family with llama-server:
78
+
79
+ | Model | VRAM | Context | SWE-bench |
80
+ |---|---|---|---|
81
+ | **Qwen3.6-35B-A3B Q3_K_M** ⭐ | 21.6 GB | 16K | 73.4% |
82
+ | Qwen3.6-27B Q4_K_M | 22.0 GB | 4K | 77.2% |
83
+
84
+ Works with any OpenAI-compatible backend. See [docs/models.md](docs/models.md).
85
+
86
+ ## Agent Setup
87
+
88
+ Point any OpenAI-compatible agent at `http://localhost:8081/v1`:
89
+
90
+ - **Pi** — `api_base: "http://localhost:8081/v1"`
91
+ - **Aider** — `OPENAI_API_BASE=http://localhost:8081/v1`
92
+ - **Continue** — `"apiBase": "http://localhost:8081/v1"`
93
+ - **Cline / Roo** — set API base in settings
94
+
95
+ See [docs/agents.md](docs/agents.md) for detailed setup guides.
96
+
97
+ ## Configuration
98
+
99
+ Create a `guardrail-config.yaml` (or use defaults):
100
+
101
+ ```yaml
102
+ path_safety:
103
+ enabled: true
104
+ blocked_prefixes: ["/etc/", "/sys/", "/proc/"]
105
+
106
+ command_safety:
107
+ enabled: true
108
+ strength: hard # hard = block, soft = warn
109
+
110
+ secrets:
111
+ enabled: true
112
+ strength: hard
113
+ mask_value: "[REDACTED]"
114
+ ```
115
+
116
+ Pass with `--config guardrail-config.yaml`.
117
+
118
+ ## Architecture
119
+
120
+ ```
121
+ Agent → coding-guardrails (:8081) → llama-server (:8080) → GPU
122
+
123
+ ├─ Layer 1 (Forge): rescue, validate, retry
124
+ └─ Layer 2 (Guardrails): 6 safety rules
125
+ ```
126
+
127
+ See [docs/architecture.md](docs/architecture.md) for details.
128
+
129
+ ## Docker
130
+
131
+ ```bash
132
+ docker compose up
133
+ ```
134
+
135
+ Or standalone:
136
+
137
+ ```bash
138
+ docker run -p 8081:8081 ghcr.io/stawils/coding-guardrails:latest \
139
+ serve --backend-url http://host.docker.internal:8080 --model your-model
140
+ ```
141
+
142
+ ## Eval
143
+
144
+ ```bash
145
+ coding-guardrails eval --backend-url http://localhost:8081
146
+ ```
147
+
148
+ Runs scenarios from `eval/scenarios/` and reports pass/fail by category.
149
+
150
+ ## Development
151
+
152
+ ```bash
153
+ git clone https://github.com/stawils/coding-guardrails.git
154
+ cd coding-guardrails
155
+ uv venv && source .venv/bin/activate
156
+ uv pip install -e ".[dev]"
157
+
158
+ # Run tests
159
+ pytest tests/unit/ -v
160
+
161
+ # Run against live backend
162
+ pytest tests/integration/ -v -m integration
163
+ ```
164
+
165
+ ## License
166
+
167
+ MIT
@@ -0,0 +1,141 @@
1
+ # coding-guardrails
2
+
3
+ > Safe, reliable local coding agent backend. Open-source, pip-installable.
4
+
5
+ **coding-guardrails** is a proxy that sits between your coding agent and a local LLM,
6
+ adding two layers of protection:
7
+
8
+ 1. **Forge (Layer 1)** — Rescue parsing, retries, validation. Makes local models
9
+ actually work for tool calling.
10
+ 2. **Coding Guardrails (Layer 2)** — Read-before-edit, path safety, command blocking,
11
+ secret masking, test-after-change suggestions.
12
+
13
+ One command to go from "I have a GPU" to "I have a safe local coding agent backend."
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ # Install
19
+ pip install coding-guardrails
20
+
21
+ # Start llama-server (your local LLM backend)
22
+ llama-server -m model.gguf --jinja --fit on --flash-attn auto \
23
+ --port 8080 -c 16384 --spec-type draft-mtp -np 1
24
+
25
+ # Start the proxy
26
+ coding-guardrails serve \
27
+ --backend-url http://localhost:8080 \
28
+ --model Qwen3.6-35B-A3B-UD-Q3_K_M \
29
+ --port 8081
30
+
31
+ # Point your agent at http://localhost:8081/v1
32
+ ```
33
+
34
+ That's it. Your agent sees a standard OpenAI-compatible API.
35
+
36
+ ## What It Blocks
37
+
38
+ | Rule | Blocks | Example |
39
+ |---|---|---|
40
+ | **Path safety** | Reads/writes outside workspace | `read_file("/etc/passwd")` ❌ |
41
+ | **Command safety** | Destructive shell commands | `bash("rm -rf /")` ❌ |
42
+ | **Secret detection** | API keys, tokens, private keys | `bash("export AWS_SECRET_ACCESS_KEY=...")` ❌ |
43
+ | **Prerequisites** | Edit before read (soft nudge) | `edit_file()` without `read_file()` ⚠️ |
44
+ | **Sequencing** | Missing test runs (soft nudge) | Edit without `pytest` ⚠️ |
45
+ | **Tool resolution** | Empty/error results (soft nudge) | Tool returns `""` ⚠️ |
46
+
47
+ All rules are configurable. See [docs/rules.md](docs/rules.md).
48
+
49
+ ## Supported Models
50
+
51
+ Optimized for the **Qwen 3.6** family with llama-server:
52
+
53
+ | Model | VRAM | Context | SWE-bench |
54
+ |---|---|---|---|
55
+ | **Qwen3.6-35B-A3B Q3_K_M** ⭐ | 21.6 GB | 16K | 73.4% |
56
+ | Qwen3.6-27B Q4_K_M | 22.0 GB | 4K | 77.2% |
57
+
58
+ Works with any OpenAI-compatible backend. See [docs/models.md](docs/models.md).
59
+
60
+ ## Agent Setup
61
+
62
+ Point any OpenAI-compatible agent at `http://localhost:8081/v1`:
63
+
64
+ - **Pi** — `api_base: "http://localhost:8081/v1"`
65
+ - **Aider** — `OPENAI_API_BASE=http://localhost:8081/v1`
66
+ - **Continue** — `"apiBase": "http://localhost:8081/v1"`
67
+ - **Cline / Roo** — set API base in settings
68
+
69
+ See [docs/agents.md](docs/agents.md) for detailed setup guides.
70
+
71
+ ## Configuration
72
+
73
+ Create a `guardrail-config.yaml` (or use defaults):
74
+
75
+ ```yaml
76
+ path_safety:
77
+ enabled: true
78
+ blocked_prefixes: ["/etc/", "/sys/", "/proc/"]
79
+
80
+ command_safety:
81
+ enabled: true
82
+ strength: hard # hard = block, soft = warn
83
+
84
+ secrets:
85
+ enabled: true
86
+ strength: hard
87
+ mask_value: "[REDACTED]"
88
+ ```
89
+
90
+ Pass with `--config guardrail-config.yaml`.
91
+
92
+ ## Architecture
93
+
94
+ ```
95
+ Agent → coding-guardrails (:8081) → llama-server (:8080) → GPU
96
+
97
+ ├─ Layer 1 (Forge): rescue, validate, retry
98
+ └─ Layer 2 (Guardrails): 6 safety rules
99
+ ```
100
+
101
+ See [docs/architecture.md](docs/architecture.md) for details.
102
+
103
+ ## Docker
104
+
105
+ ```bash
106
+ docker compose up
107
+ ```
108
+
109
+ Or standalone:
110
+
111
+ ```bash
112
+ docker run -p 8081:8081 ghcr.io/stawils/coding-guardrails:latest \
113
+ serve --backend-url http://host.docker.internal:8080 --model your-model
114
+ ```
115
+
116
+ ## Eval
117
+
118
+ ```bash
119
+ coding-guardrails eval --backend-url http://localhost:8081
120
+ ```
121
+
122
+ Runs scenarios from `eval/scenarios/` and reports pass/fail by category.
123
+
124
+ ## Development
125
+
126
+ ```bash
127
+ git clone https://github.com/stawils/coding-guardrails.git
128
+ cd coding-guardrails
129
+ uv venv && source .venv/bin/activate
130
+ uv pip install -e ".[dev]"
131
+
132
+ # Run tests
133
+ pytest tests/unit/ -v
134
+
135
+ # Run against live backend
136
+ pytest tests/integration/ -v -m integration
137
+ ```
138
+
139
+ ## License
140
+
141
+ MIT
@@ -0,0 +1,11 @@
1
+ # Aider configuration
2
+ # Point Aider at the coding-guardrails proxy.
3
+ #
4
+ # Usage:
5
+ # 1. Start llama-server on :8080
6
+ # 2. Start proxy: coding-guardrails serve --backend-url http://localhost:8080 --model Qwen3.6-35B-A3B-UD-Q3_K_M
7
+ # 3. Run aider: aider --model openai/Qwen3.6-35B-A3B-UD-Q3_K_M --api-base http://localhost:8081
8
+
9
+ # In your .aider.conf.yml or environment:
10
+ # OPENAI_API_BASE=http://localhost:8081/v1
11
+ # OPENAI_API_KEY=not-needed
@@ -0,0 +1,75 @@
1
+ # Default guardrail configuration
2
+ # All rules enabled with sensible defaults.
3
+
4
+ # Workspace root — path safety restricts file operations to this tree.
5
+ # Set to "." for current directory, or an absolute path.
6
+ workspace: "."
7
+
8
+ path_safety:
9
+ enabled: true
10
+ # Paths that are always blocked (even inside workspace)
11
+ blocked_prefixes:
12
+ - "/etc/"
13
+ - "/sys/"
14
+ - "/proc/"
15
+ - "/boot/"
16
+ - "/dev/"
17
+ - "/root/"
18
+ - "/var/log/"
19
+ # Additional allowed paths outside workspace (e.g. system includes)
20
+ # allowed_prefixes: []
21
+
22
+ command_safety:
23
+ enabled: true
24
+ strength: hard # hard = block, soft = nudge only
25
+ blocked_commands:
26
+ - "rm -rf /"
27
+ - "rm -rf /*"
28
+ - "mkfs"
29
+ - "dd if="
30
+ - ":(){ :|:& };:"
31
+ - "> /dev/sd"
32
+ - "shutdown"
33
+ - "reboot"
34
+ - "init 0"
35
+ - "init 6"
36
+ - "systemctl stop"
37
+
38
+ secrets:
39
+ enabled: true
40
+ strength: hard # hard = block, soft = mask and warn
41
+ mask_value: "[REDACTED]"
42
+ # Patterns: AWS keys, GitHub tokens, private keys, generic API keys
43
+
44
+ prerequisites:
45
+ enabled: true
46
+ strength: soft # soft = nudge first, hard = block until read
47
+ cooldown: 3 # turns before re-nudging
48
+ edit_tools:
49
+ - "write_file"
50
+ - "edit_file"
51
+ - "create_file"
52
+ read_tools:
53
+ - "read_file"
54
+ - "cat"
55
+
56
+ sequencing:
57
+ enabled: true
58
+ strength: soft # soft = suggest, hard = block until test runs
59
+ cooldown: 3
60
+ edit_tools:
61
+ - "write_file"
62
+ - "edit_file"
63
+ - "create_file"
64
+ test_tools:
65
+ - "bash"
66
+ test_commands:
67
+ - "pytest"
68
+ - "test"
69
+ - "cargo test"
70
+ - "go test"
71
+
72
+ tool_resolution:
73
+ enabled: true
74
+ strength: soft # soft = nudge only
75
+ # Nudges when tool results are empty, whitespace-only, or permission errors
@@ -0,0 +1,13 @@
1
+ # Pi agent configuration
2
+ # Point Pi at the coding-guardrails proxy instead of directly at llama-server.
3
+ #
4
+ # Usage:
5
+ # 1. Start llama-server: llama-server -m <model>.gguf --jinja --fit on --flash-attn auto --port 8080 -c 16384 --spec-type draft-mtp -np 1
6
+ # 2. Start proxy: coding-guardrails serve --backend-url http://localhost:8080 --model Qwen3.6-35B-A3B-UD-Q3_K_M --port 8081
7
+ # 3. Set in Pi config: api_base = "http://localhost:8081/v1"
8
+
9
+ model: "Qwen3.6-35B-A3B-UD-Q3_K_M"
10
+ api_base: "http://localhost:8081/v1"
11
+
12
+ # Pi should see the proxy as a regular OpenAI-compatible backend.
13
+ # No special configuration needed — the guardrails are transparent.
@@ -0,0 +1,59 @@
1
+ # coding-guardrails + llama-server stack
2
+ #
3
+ # Usage:
4
+ # GGUF_PATH=/path/to/model.gguf docker compose up
5
+ #
6
+ # The llama-server container needs GPU access. Adjust CUDA_VISIBLE_DEVICES
7
+ # if you have multiple GPUs.
8
+
9
+ services:
10
+ llama-server:
11
+ image: ghcr.io/ggerganov/llama.cpp:server
12
+ ports:
13
+ - "8080:8080"
14
+ volumes:
15
+ - ${GGUF_PATH:-./models}:/models:ro
16
+ command: >
17
+ --model /models/${GGUF_FILE:-model.gguf}
18
+ --jinja
19
+ --fit on
20
+ --flash-attn auto
21
+ --port 8080
22
+ --host 0.0.0.0
23
+ -c ${CONTEXT_SIZE:-16384}
24
+ --spec-type draft-mtp
25
+ -np 1
26
+ deploy:
27
+ resources:
28
+ reservations:
29
+ devices:
30
+ - driver: nvidia
31
+ count: 1
32
+ capabilities: [gpu]
33
+ healthcheck:
34
+ test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
35
+ interval: 30s
36
+ timeout: 10s
37
+ retries: 5
38
+ start_period: 60s
39
+
40
+ coding-guardrails:
41
+ build: .
42
+ ports:
43
+ - "8081:8081"
44
+ volumes:
45
+ - ./configs/guardrail-config.yaml:/etc/coding-guardrails/config.yaml:ro
46
+ command: >
47
+ serve
48
+ --backend-url http://llama-server:8080
49
+ --model ${MODEL_NAME:-Qwen3.6-35B-A3B-UD-Q3_K_M}
50
+ --port 8081
51
+ --host 0.0.0.0
52
+ depends_on:
53
+ llama-server:
54
+ condition: service_healthy
55
+ healthcheck:
56
+ test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8081/health')"]
57
+ interval: 30s
58
+ timeout: 5s
59
+ retries: 3