openapi.json is never regenerated. Client SDKs break, integration partners get confused, and the mismatch only surfaces in production. Geni’s geni:check command solves this by running the same static analysis it uses to generate specs and comparing the result against your committed file, failing the CI build the moment any discrepancy appears.
How geni:check Works
Run the command by pointing it at your committed spec file:
geni:check executes four steps on every run:
1
Regenerate in memory
Geni traverses the current codebase using AST analysis — no database connection and no application boot required — and produces a fresh OpenAPI document entirely in memory.
2
Read the committed spec
Geni reads the specification file at the path you supplied with
--path from disk.3
Normalize and canonicalize
Both documents are normalized by recursively sorting object keys while preserving semantically significant array orders (such as parameter lists and enum values), so cosmetic formatting differences never trigger a false positive.
4
Compare and report
If the two documents are identical, Geni prints a confirmation message and exits cleanly. If they differ, Geni prints a human-readable list of every added, removed, or changed path, method, parameter, and schema before exiting with a non-zero code.
Exit Codes
A non-zero exit code causes any CI system to fail the build, blocking the pull request from merging until the spec is regenerated and committed.
Adding to GitHub Actions
Add a drift check step to your existing GitHub Actions workflow. The step runs after your dependencies are installed and requires no additional services or environment variables beyond a working PHP setup:.github/workflows/ci.yml
php artisan geni:export --path=openapi.json, the Verify OpenAPI Specification Drift step fails and blocks the PR from merging.
Diagnostic Relativization
When Geni stores file-path references insidex-geni-unresolved extension fields, it automatically converts absolute paths to paths relative to the project root before writing them to the spec. This means a spec generated on your MacBook laptop and a spec generated inside a Linux CI container produce byte-for-byte identical output for those fields, even though the absolute filesystem paths are completely different. Without relativization, every CI run would report spurious drift caused solely by environment differences rather than real code changes.