Quality gates for AI-generated code — TDD enforcement, secret scanning, and audit trails for coding agents.
Project description
Tribunal
Quality gates for AI-generated code. v2.0.0
Tribunal scans code for secrets, enforces TDD, lints Python / TypeScript / Go, and outputs SARIF — in one command. Works everywhere: CI pipelines, pre-commit hooks, local dev. Agent-agnostic.
5 checkers · SARIF 2.1.0 · GitHub Action · pre-commit hook
Quick Start
pip install tribunal
tribunal ci .
That's it. Tribunal walks every source file, runs applicable checkers, and exits non-zero if anything fails.
What It Does
| Checker | What it catches |
|---|---|
| Secrets | AWS keys, GitHub tokens, Anthropic/OpenAI keys, private keys, JWTs, database URLs, generic API keys (14 patterns) |
| Python | Ruff lint violations, Pyright/mypy type errors |
| TypeScript | ESLint issues, tsc --noEmit type errors |
| Go | go vet issues, golangci-lint findings |
| TDD | Source files with no corresponding test file (Python, TypeScript, Go) |
Secrets scanning runs on every file. Language checkers run only on matching extensions.
Output Formats
tribunal ci . # Human-readable text (default)
tribunal ci . --format sarif # SARIF 2.1.0 for GitHub Code Scanning
tribunal ci . --format json # Machine-readable JSON
tribunal ci . --output report.sarif # Write to file
CLI Commands
tribunal ci . # Run all checkers on current directory
tribunal ci src/ tests/ # Check specific paths
tribunal ci . --checkers secrets,python # Run only specific checkers
tribunal ci . --format sarif --output results.sarif # SARIF output
tribunal init # Set up project config
tribunal status # Show active rules and config
tribunal rules # List configured rules
tribunal audit # View audit log
tribunal config # Show resolved config
tribunal pack list # Show available rule packs
tribunal doctor # Health check
GitHub Action
# .github/workflows/tribunal.yml
name: Tribunal CI
on: [push, pull_request]
jobs:
tribunal:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: thebotclub/tribunal@v2
The action installs Tribunal, runs tribunal ci . with SARIF output, and uploads results to GitHub Code Scanning automatically.
pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/thebotclub/tribunal
rev: v2.0.0
hooks:
- id: tribunal-ci # Full check suite
- id: tribunal-secrets # Secrets only (fast)
Secrets Scanning
14 built-in patterns covering:
- AWS access keys and secret keys
- GitHub personal access tokens (classic and fine-grained)
- Anthropic and OpenAI API keys
- Slack tokens and webhooks
- Private keys (RSA, EC, etc.)
- Database connection URLs with passwords
- JWTs, Bearer tokens
- Generic hex secrets and API keys
.secretsignore
Suppress false positives with a .secretsignore file in your project root:
# Patterns (one per line, matched against file path)
docs/examples/*
test_fixtures/mock_keys.py
Placeholder Detection
Tribunal automatically skips placeholder values like your-api-key-here, CHANGE_ME, xxxx, and TODO patterns — only real secrets trigger findings.
TDD Enforcement
For every source file, Tribunal checks whether a corresponding test file exists:
| Source | Expected test |
|---|---|
src/auth.py |
tests/test_auth.py or test_auth.py (sibling) |
src/api.ts |
src/api.test.ts or src/api.spec.ts |
internal/server.go |
internal/server_test.go |
Files that are reasonably excluded (test files themselves, __init__.py, index.ts, main.go) are skipped.
Rule Packs
Pre-built rule sets for common standards:
tribunal pack list # Show available packs
tribunal pack install soc2 # Install SOC 2 rules
Available: soc2, startup, enterprise, security.
Configuration
Tribunal reads config from .tribunal/config.yaml:
rules:
tdd-python:
match:
path: "*.py"
action: block
condition: no-matching-test
message: "Write a failing test first."
no-secrets:
action: block
condition: contains-secret
message: "Possible secret detected."
Programmatic API
from tribunal.checkers import run_checkers, collect_files
from tribunal.sarif import findings_to_sarif, sarif_to_json
files = collect_files("/path/to/project")
results = run_checkers(files, project_root="/path/to/project")
# Check pass/fail
passed = all(r.passed for r in results)
# Generate SARIF
sarif = findings_to_sarif(results, "/path/to/project")
print(sarif_to_json(sarif))
REST endpoints: /api/projects, /api/summary, /api/projects/{id}/audit|cost|agents.
VS Code Extension
Visual governance in the editor sidebar:
- Rules Tree — See all rules with action icons
- Audit Tree — Browse recent events
- Cost Tree — Track budget usage
- Agents Tree — Monitor sub-agents
- Status Bar — Rule count and block count at a glance
Architecture
.tribunal/
├── rules.yaml # Rule definitions
├── config.yaml # Project configuration
├── permissions.yaml # Permission policies
├── audit.jsonl # Audit log (gitignored)
├── state.json # Cost tracking state (gitignored)
├── skills/ # Custom skills
└── bundle.json # Air-gapped bundle (export)
.claude/
├── claudeconfig.json # Hook wiring
└── memory/ # Tribunal memory entries
├── tribunal-rule-*.md
└── tribunal-session-*.md
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tribunal-2.0.0.tar.gz.
File metadata
- Download URL: tribunal-2.0.0.tar.gz
- Upload date:
- Size: 34.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50d161c4626a44e70447092a73b1fa3ef70e819d0c5808c023de177db967f8e2
|
|
| MD5 |
77e8aca2d11bdccfbda9f8d9338aae18
|
|
| BLAKE2b-256 |
701aaefd9e1b1cf2f1091ee5af0ebd2ed81c495c9218b4cbbae6af21f76b5c1d
|
Provenance
The following attestation bundles were made for tribunal-2.0.0.tar.gz:
Publisher:
publish.yml on thebotclub/tribunal.dev
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tribunal-2.0.0.tar.gz -
Subject digest:
50d161c4626a44e70447092a73b1fa3ef70e819d0c5808c023de177db967f8e2 - Sigstore transparency entry: 1215416310
- Sigstore integration time:
-
Permalink:
thebotclub/tribunal.dev@3df48a95084946290d9a1c07b3cce79c531e8e00 -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/thebotclub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3df48a95084946290d9a1c07b3cce79c531e8e00 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tribunal-2.0.0-py3-none-any.whl.
File metadata
- Download URL: tribunal-2.0.0-py3-none-any.whl
- Upload date:
- Size: 45.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dcf814f6c59b2838ca2431f8d6dcbcf656620ea246f64130d82648fd11369ea
|
|
| MD5 |
0bea3b5e761a9303c860a306f3ad0ab8
|
|
| BLAKE2b-256 |
3c75f582b74a2c45829ac7165a6eb2e920fef3b5b9c020c8a35aba5505c98bee
|
Provenance
The following attestation bundles were made for tribunal-2.0.0-py3-none-any.whl:
Publisher:
publish.yml on thebotclub/tribunal.dev
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tribunal-2.0.0-py3-none-any.whl -
Subject digest:
2dcf814f6c59b2838ca2431f8d6dcbcf656620ea246f64130d82648fd11369ea - Sigstore transparency entry: 1215416420
- Sigstore integration time:
-
Permalink:
thebotclub/tribunal.dev@3df48a95084946290d9a1c07b3cce79c531e8e00 -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/thebotclub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3df48a95084946290d9a1c07b3cce79c531e8e00 -
Trigger Event:
push
-
Statement type: