Gates¶
gates
¶
Reusable pre- and post-agent gates.
Gates validate data before and after an AI agent runs. Pre-gates filter input so the agent never sees invalid data. Post-gates validate output to catch dangerous changes before they reach the forge.
All functions are stateless and tracker-agnostic -- they operate on dicts and file lists, not Jira-specific types.
The GATE_REGISTRY maps CLI-friendly names to GateSpec instances.
Use resolve_gates() to look up gates by name and
validate_gate_env() to check required environment variables before
running any gate.
GateSpec(name, fn, phase, required_env=list())
dataclass
¶
Metadata for a registered gate function.
resolve_gates(names)
¶
Look up gate specs by CLI name. Raises SystemExit on unknown names.
Source code in src/agentic_ci/gates.py
validate_gate_env(gates)
¶
Check that all required env vars for the given gates are set.
Fails with a clear error listing every missing variable and which gate needs it.
Source code in src/agentic_ci/gates.py
check_sensitive_files(changed_files, blocklist=None)
¶
Check if any changed files match a sensitive-file blocklist.
A pattern without a / is matched against the file's basename, so
*secret* blocks config/secret.yaml but not a secrets/
directory. A pattern with a / is matched against the full
repo-relative path (.agentic-ci/*); fnmatch's * crosses /,
so it covers nested files too. A path is blocked when it matches as
given or after unquote_git_path() (for git's C-quoted output), so
unquoting can only add a match. Matching is case-sensitive.
Returns a list of blocked file paths, as given (empty means all clear).
Source code in src/agentic_ci/gates.py
check_commit_identity(commit_info, expected_email)
¶
Verify the commit committer matches the expected bot email.
log_changed_files(changed_files, ticket_key)
¶
Log changed files for observability.
Source code in src/agentic_ci/gates.py
gitleaks_scan(repo_dir, compare_ref='origin/HEAD')
¶
Scan new commits for secrets using gitleaks.
Scans the commits in compare_ref..HEAD with gitleaks' built-in
rules. Nothing in repo_dir changes what is detected: config and
ignore files in the working tree, gitleaks:allow comments and the
GITLEAKS_CONFIG variables are all ignored.
Returns a list of error strings (empty means clean).
Requires gitleaks to be installed on PATH. Fails closed:
returns an error if gitleaks is missing or times out.
Source code in src/agentic_ci/gates.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | |
filter_comments_by_domain(comments, allowed_domain_re)
¶
Keep only comments from authors whose email matches allowed_domain_re.
Comments with a missing (None) or non-string author_email are dropped.
Source code in src/agentic_ci/gates.py
filter_bot_comments(comments, sentinel_phrases)
¶
Remove comments containing any of the given bot sentinel phrases.
A missing (None) or non-string body holds no sentinel, so the
comment is kept.
Source code in src/agentic_ci/gates.py
check_description_editors(editors, reporter_email, internal_domain_re)
¶
Check if any description editors are outside the trusted domain.
Validates the reporter (original author) and all changelog editors. Returns a list of untrusted email addresses (empty means all clear). Treats empty or missing emails as untrusted.
Source code in src/agentic_ci/gates.py
check_external_reporter(ticket, internal_domain_re, *, external_label)
¶
Check if a ticket was filed by an external reporter.
Returns external_label if the reporter is external and the label
is not already present, otherwise None.
Source code in src/agentic_ci/gates.py
check_label_author_email(author_info, domain_pattern)
¶
Verify that the label's author email matches domain_pattern.
author_info is the dict returned by JiraClient.get_label_author(),
expected to contain "found" (bool) and "email" (str) keys.
Returns True if the author was found and the email matches. A missing (None) or non-string email never matches.