AI-Assisted Development
Hegemony is developed with AI coding agents in the loop, and this document explains exactly what that means — because "AI was involved" can describe anything from disciplined engineering to unreviewed code dumped into a repository, and the difference is the process, not the tool.
The position
Code quality in this project is enforced by deterministic, provenance-blind gates, not by trusting any author. A patch written by a human and a patch drafted by an agent travel through the identical pipeline, and neither merges unless every gate passes. AI assistance changes how fast a change is drafted; it changes nothing about what is required for that change to land.
What AI agents are used for here: drafting implementations against a written spec, extending test suites, keeping documentation in sync, and mechanical refactors. What they are not: an excuse to skip review, a reason to accept code nobody understands, or an author of architectural decisions. Design decisions are made by maintainers and recorded before significant implementation starts.
How the agents are constrained
The repository configures its AI tooling explicitly, in version control, where you can audit it:
- .github/copilot-instructions.md — the contract every agent session works under: search for existing code before writing new code, prefer reuse over parallel implementations, ship the full slice (API + worker + UI + tests + docs), and end with concrete verification steps.
- .github/instructions/ — scoped conventions per area (backend, worker, UI, deploy, flow patterns), so generated code follows the same architecture the existing code does.
- .github/hooks/ — runtime guardrails for agent sessions: dangerous shell commands are blocked before execution, edits to sensitive files (auth, permissions, deploy credentials) require explicit human confirmation, and every edit is auto-formatted on write.
The enforced gates and assurance checks
These checks are provenance-blind; where they run depends on the gate:
| Gate | Enforced by |
|---|---|
Lint, formatting, strict type checking (ruff, ty) | pre-commit + CI |
Dead-code detection (vulture, curated whitelist) | pre-commit + CI |
Test suite with coverage floor (pytest) | CI |
Every API route must be covered by the centralized RBAC registry (RBACMiddleware + apps/api/auth/routes.yaml, grouped into actions in apps/api/auth/actions.yaml) | pre-commit + CI |
| Committed OpenAPI schema must match the code, byte for byte | CI |
| Generated UI API types must match the schema | CI |
| UI lint, typecheck, build, Playwright end-to-end suites | CI |
Secrets scanning (gitleaks) | pre-commit |
GitHub Actions policy checks (zizmor) | pre-commit |
Security rules (semgrep) | CI security workflow |
Python security scan (bandit) | CI heavy-assurance workflow |
| License policy and REUSE/SPDX compliance | pre-commit + CI |
| Conventional Commit messages | pre-commit + CI |
| DCO sign-off on every commit, by the person who submits it; an agent never signs off for itself (CONTRIBUTING.md) | DCO GitHub App |
| Human review of every pull request | branch protection |
The OpenAPI byte-sync check deserves a highlight: it makes "the docs say one thing, the code does another" — the classic failure mode of generated code — a CI failure rather than a discovery some user makes later.
What this means for the code you're reading
Some practical consequences of this setup, verifiable in the tree:
- Behavior is specified first, implemented second, and the spec stays in the repo as the record of why.
- Tests assert behavior (handler results, ticket lifecycles, sanitization invariants), not just status codes — and failure paths are tested alongside happy paths.
- There is one way to do each thing: one settings system, one HTTP client pattern, one handler registry. The reuse-before-create rule exists precisely because unconstrained generation tends to produce parallel near-duplicates.
- Accepted trade-offs are written down where they live (e.g., the in-memory BFF ticket store's single-instance limitation) and consolidated in the Production Hardening Guide, instead of being silently generated around.
What this means for contributors
You are welcome to use AI tools for your contributions — the maintainers do. Two expectations come with that:
- You own your patch. Submit code you have read, understood, and can defend in review. "The tool wrote it" is not an answer to a review question.
- The same Definition of Done applies. Tests, docs, migrations, and verification steps as described in CONTRIBUTING.md — regardless of how the first draft came to be.
If you find a place where the codebase doesn't live up to the standards this document claims, that's a bug in the process. Please open an issue.