This repository is a GitHub Action for policy-as-code in pull request CI.
If a proposed change does not make the action more useful, more reliable, easier to adopt, or easier to publish, do not make it.
Build and maintain the smallest genuinely useful MVP for:
uses: failuresmith/github-policy-gate@v1
The action evaluates a YAML policy file against pull request and repository facts, then warns or fails with clear messages.
Enable PR guardrails with minimal infrastructure:
- no bot
- no web service
- no database
- no GitHub App
- no external dependencies beyond GitHub and the checked-out repository
The product must be:
- easy to trust
- easy to read
- easy to adopt
When rules conflict, resolve in this order:
- Non-Negotiable Product Constraints
- Determinism Requirements
- Reward Function (priority order)
- Change Acceptance Criteria
- Engineering Priorities
Lower levels must not violate higher levels.
Optimize for:
- Correct policy decisions
- Clear user-facing failure messages
- Deterministic CI behavior
- Low adoption friction
- Small, maintainable code
- Publishable packaging
This defines what to optimize, not what is allowed.
- TypeScript GitHub Action (not a bot)
- Human-readable YAML config
- Policy engine model:
- facts
- simple predicates
- composable combinators
- explicit failure messages
If .github/policy-gate.yml is missing:
-
If mode = advisory (default):
- run in advisory-only mode
- emit warning
- do not fail CI
-
If mode = enforce:
- fail CI with clear message
- AI features
- AST parsing
- language-specific analysis
- hidden network calls beyond required GitHub API usage
The action must produce identical results given:
- same PR state
- same repository state
- same config
Disallowed:
- wall-clock time
- unordered iteration where order affects results
- non-pinned API assumptions
All evaluation inputs must be:
- fully materialized before execution
- explicitly ordered where needed
Tests must assert deterministic ordering.
- changed / added / removed / renamed files
- PR title / body
- labels
- reviewers
- approval count
- file existence
- targeted file content
changed(globs)exists(globs)body(patterns)title(patterns)has_label(labels)approval_count_at_least(n)file_contains(globs, patterns)
all,any,not
A new capability is allowed only if all are true:
- cannot be expressed with existing primitives
- required in ≥2 independent real-world examples
- reduces config or cognitive load
- fits current mental model
A change is allowed only if:
- decision correctness (via tests)
- message clarity (via expected outputs)
- determinism
- adoption friction
- code size/complexity (net justified)
- add external dependencies
- increase config surface area
- reduce test coverage
- introduce implicit behavior
- failing tests first (for behavior change)
- updated docs if user-visible behavior changes
- Never trade correctness for lower priorities
- Determinism overrides performance
- Clarity may justify small code increases
- Adoption improvements must remain explicit
- Code reduction must not reduce readability
- TDD for behavior changes
- strict TypeScript
- pure, deterministic core (
engine,predicates) - side effects only at edges
- targeted file reads (no full scans)
- small, readable functions
- minimal abstractions
All outputs must be:
- concise
- actionable
- specific
Do not optimize for:
- general-purpose policy engines
- extensibility frameworks
- non-CI-scale performance
- feature parity with competitors
Changes must not:
- require extra GitHub permissions
- require changes to consumer workflow YAML
(unchanged)
Must pass:
pnpm run checkpnpm run validatepnpm run release-dry-run
Coverage is required.
Must pass:
- Acceptance Criteria satisfied
- Determinism preserved (tests prove it)
- No implicit behavior introduced
- Docs updated if needed
- Read README
- Read relevant module
- Read tests
- Update tests
- Make smallest change
- Run verification
Do not expand scope.