Docs/Testing & Quality/Quality Gates & CI Checks

Quality Gates & CI Checks

Every gate defined in the repository: what it checks, which script or workflow implements it, and how it is triggered. Strategy and layers are on Test Strategy; the workflows themselves are described on CI/CD Pipelines.

What to require on pull requests

CI OK (the summary job of ci.yml) and CodeQL OK (codeql.yml) are the required checks (CONTRIBUTING.md). CI OK covers the static gates (static-gates.yml, called from ci.yml), the secret scan, DCO sign-off, dependency review and the docs link check. The same static gates run locally through make gates and the .githooks/pre-push hook (enable with make hooks).

Static gates (static-gates.yml)

Called from ci.yml on pull requests and pushes to main, or by manual dispatch. Each script also runs from a shell:

GateScriptWhat it enforcesMode
Flyway lintscripts/ci/flyway-lint.sh(a) no edit or renumber of a migration that already exists at the merge-base; (b) new migrations containing DROP TABLE, DROP COLUMN or ALTER COLUMN ... SET NOT NULL need a -- gated:contract marker; (c) no version number twice across controlplane/ and tenant/ (one shared namespace). Writes scripts/ci/flyway.lock, uploaded as the flyway-lock artifact. Escape hatches: flyway-lint-allowed-renames.txt, flyway-lint-allowed-edits.txt.Blocking
Duplicate bean / entity namesUniqueBeanNamesTest (core/app, run by mvn verify; make spring-wiring)Duplicate Spring bean names (scanned components, Spring Data repositories, unconditional @Bean methods, named with Spring's own generator) and JPA entity names across core modules (a class of failure that passes compile and unit tests but fails at Spring context start).Blocking
Injectable constructorInjectableConstructorTest (core/app, run by mvn verify; make spring-wiring)A Spring component with several constructors and none marked @Autowired ("No default constructor found" at startup), a @ConfigurationProperties class Boot cannot bind, and a no-arg constructor that silently shadows a @Value one.Blocking
Namespace lintscripts/ci/entity-name-lint.shEntity, table, bean and controller base-path collisions; allowlist in entity-name-lint-allowlist.txt.Blocking
Expired test-skip checkscripts/ci/skip-expiry.shAny test.fixme, @Disabled or .skip that carries an expires:YYYY-MM-DD token fails once the date has passed; environment-gated skips are exempt.Blocking
File-size ratchetscripts/ci/check-file-size.shHard cap of 700 lines: no new tracked source file over 665 lines, i.e. over the cap or within 5% of it (override FILE_SIZE_CAP, FILE_SIZE_NEAR_CAP_PCT); no file in scripts/ci/file-size-baseline.txt may grow, and a change may not add a path to the baseline (compared with the merge-base). Never raise a baseline to go green; --update regenerates it after a split.Ratchet
Module-size ratchetscripts/ci/check-module-size.shADR-0023: at most 300 main .java files per core/* module (override MODULE_SIZE_MAX) and no classes directly in com.agenticai.core.agents; modules and the root package already over are listed in scripts/ci/module-size-baseline.txt, may not grow, and a change may not add an entry (compared with the merge-base). --update lowers the baseline after a split.Ratchet
Secret scanscripts/ci/secret-scan.shgitleaks over commits added since the base ref (a separate Secret scan job), not full history.Blocking

The pre-push hook runs the full static-gate suite when pushing to main, Flyway lint alone for other pushes that touch core/app/src/main/resources/db/migration, and gitleaks (when installed) on every push. git push --no-verify bypasses it.

Build and test jobs (ci.yml)

Path-filtered; the CI OK job aggregates them. Details are on CI/CD Pipelines.

JobLocal equivalentMode
core (Maven verify, JDK 21, Postgres with pgvector + AGE)make test-coreBlocking
web, web-admin (lint, typecheck, test, build)make test-web, make test-web-admin, make lintBlocking
python (ruff, sidecar pytest, code-intel harness)make test-python, make lintBlocking
python-extra (app-builder, tool-sandbox, voice-agent)—Blocking
node-services (mcp-stdio-runner, example MCP servers)—Blocking (http-gateway example advisory)
shellcheck, hadolintmake shellcheckBlocking
compose (docker compose config)make compose-validateBlocking
helm (lint, template, kubeconform, render guards)make helm-lintBlocking

Other workflows

WorkflowWhat it runsTrigger
codeql.ymlCodeQL SAST for java-kotlin, javascript-typescript and pythonPull request, push, weekly, dispatch
scorecard.ymlOpenSSF ScorecardWeekly, push, dispatch
e2e.ymlPlaywright suite in tests/e2e against the compose stack built from the commit; see E2E SuitesNightly, dispatch

Running the gates yourself

make gates            # all static gates
make hooks            # install the pre-push hook
make lint             # eslint + tsc, ruff, shellcheck
make test             # core, web, web-admin, python
make compose-validate
make helm-lint
Not documented in the repository

Required-status-check configuration on GitHub, current pass/fail status of any workflow, and coverage figures are not recorded in the repository.

Evidence & references

Related: Test Strategy · E2E Suites · ADR-0002