-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
145 lines (138 loc) · 6.09 KB
/
Copy pathpyproject.toml
File metadata and controls
145 lines (138 loc) · 6.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
[project]
name = "gate.cat"
version = "0.4.18"
description = "Block irreversible AI-agent actions before they run — deterministic, fail-closed action-veto (deny-list + exec-check + human-in-the-loop) for any tool-using agent, from a Claude Code hook to local LLMs."
readme = "README.md"
license = {text = "Apache-2.0"}
requires-python = ">=3.10"
authors = [
{name = "Bogumił Jankiewicz", email = "bogumil@bgml.ai"},
]
keywords = ["ai-agent", "agent-safety", "guardrails", "claude-code", "hook", "fail-closed", "deny-list", "llm-security", "ollama", "mcp", "devsecops", "action-veto"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Security",
"Topic :: Software Development :: Quality Assurance",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
# CORE = the action-veto guardrail: pure stdlib, ZERO third-party deps. A
# `pip install gate.cat` gives a working veto with no numpy/ONNX/hnswlib - so it
# installs in seconds and never OOMs/hangs importing an ML stack it doesn't use.
# The semantic cache (numpy/hnswlib/onnx) is an opt-in extra, see [cache].
dependencies = []
[project.optional-dependencies]
# semantic cache + embedders (the only heavy stack; opt-in). `__init__.py`'s
# lazy loader raises a clear "install gate.cat[cache]" error if a cache symbol
# is used without these.
cache = [
"numpy>=1.24.0",
"hnswlib>=0.8.0",
"onnxruntime>=1.17.0",
"huggingface-hub>=0.20.0",
"tokenizers>=0.15.0",
]
# optional ML escalation for the INGRESS guard (input_guard): MiniLM ONNX embed
# + a tiny logistic head lifts prompt-injection recall ~55%->~88%. Opt-in AND
# gated at runtime by GATECAT_ENABLE_ML_GUARD=1 (higher recall, higher FPR).
# The regex floor works with zero deps; this only adds the learned layer.
ml = [
"numpy>=1.24.0",
"onnxruntime>=1.17.0",
"huggingface-hub>=0.20.0",
"tokenizers>=0.15.0",
]
openai = ["openai>=1.0.0"]
anthropic = ["anthropic>=0.20.0"]
image = ["Pillow>=10.0.0"]
voice = ["soundfile>=0.12.0"]
proxy = ["fastapi>=0.110.0", "uvicorn[standard]>=0.27.0", "httpx>=0.27.0", "pydantic>=2.0.0"]
# Cloud reporter — client-side end-to-end encryption of the off-machine veto history
cloud = ["cryptography>=41.0.0"]
# framework adapters (gatecat.integrations) — lazy-imported, never pulled by core
crewai = ["crewai>=0.80,<2"]
langgraph = ["langgraph>=0.2,<2"]
all = [
"numpy>=1.24.0", "hnswlib>=0.8.0", "onnxruntime>=1.17.0",
"huggingface-hub>=0.20.0", "tokenizers>=0.15.0",
"openai>=1.0.0", "anthropic>=0.20.0", "Pillow>=10.0.0", "soundfile>=0.12.0",
]
dev = ["pytest>=8.0.0", "pytest-asyncio>=0.24.0", "pytest-timeout>=2.3.0",
"httpx>=0.27.0",
# proxy stack — the tool-call action-veto (test_proxy_tool_veto.py) is
# security-critical and must RUN in CI, not skip for lack of fastapi.
"fastapi>=0.110.0", "uvicorn[standard]>=0.27.0", "pydantic>=2.0.0",
"numpy>=1.24.0", "hnswlib>=0.8.0", "onnxruntime>=1.17.0",
"huggingface-hub>=0.20.0", "tokenizers>=0.15.0"]
[project.scripts]
# the user-facing guardrail dashboard (zero ML deps): shows that gate.cat is
# on duty - watched N, stopped M, recent events, `why <cmd>` explains a verdict.
"gate.cat" = "gatecat.integrations.dashboard:main"
gatecat = "gatecat.integrations.dashboard:main"
# F8 (eng review E1): ship the Claude Code veto hook as a console script so
# `pip install gate.cat` delivers it — no repo checkout, no sys.path hack.
gatecat-hook = "gatecat.hooks.claude_code:_entry"
# gated shell (0.4.12): the third enforcement point beside hook + proxy. A
# drop-in `sh -c` gate for any agent that shells out (Codex/Gemini CLI/aider/
# OpenClaw/...): block -> exit 2 (no exec), allow/warn -> exec the real shell.
gatecat-shell = "gatecat.shell:_entry"
# F3 (D1=A purge): the old `cacheback` / `cacheback-proxy` script names are
# dropped, not repointed — no `cacheback` command survives the rename.
gatecat-cli = "gatecat.cli:main"
gatecat-proxy = "gatecat.proxy.__main__:main"
truthgate-audit = "gatecat.audit:main"
[project.urls]
Homepage = "https://gate.cat"
Repository = "https://github.com/BGMLAI/gate.cat"
Issues = "https://github.com/BGMLAI/gate.cat/issues"
Pricing = "https://gate.cat/teams.html"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["gatecat"]
# ship the tiny (~2.5KB) trained injection head so the optional ML guard works
# out of the box once the [ml] extra's runtime deps are installed.
artifacts = ["gatecat/integrations/models/*.npz"]
# Explicit sdist allowlist. Without this, hatchling's default sdist ships the
# whole dir - including REJESTR_PRAWD.md, which catalogs the guardrail's OWN
# known bypasses (a gift to an attacker) plus internal ops notes. A security
# product must not publish its own weak-points map. Only ship what a user needs.
[tool.hatch.build.targets.sdist]
include = [
"gatecat/**/*.py",
"gatecat/py.typed",
# ship the trained injection head in the sdist too, else `pip install
# gate.cat[ml]` built from source silently falls back to the regex floor
# (the wheel already carries it via [tool.hatch.build.targets.wheel].artifacts).
"gatecat/integrations/models/*.npz",
"README.md",
"LICENSE",
"pyproject.toml",
]
exclude = [
"REJESTR_PRAWD.md",
"GOTCHAS.md",
"*.jsonl",
"benchmarks/**",
"tests/**",
"scripts/**",
"examples/**",
"**/*_internal*",
]
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
# A hung test must FAIL LOUDLY, never wedge the whole suite (fail-closed for CI).
# Known hazard: `import onnxruntime` can block in a WMI probe on some Windows /
# CPython 3.13 hosts — a per-test timeout turns that into a clean failure that
# names the culprit instead of an indefinite hang. `thread` method works on
# Windows (signal-based alarm does not).
timeout = 90
timeout_method = "thread"