vernac / architecture, expressed.
Browse documentation

Vernac build and migration tools for AI agents

Baseline: implemented tooling in the 0.5.0 release line. Use this guide with the AI language reference, the existing POM and the application’s requirements. It is a workflow reference, not additional syntax.

On this page

Locate the project and respect its configuration

Run commands from the directory containing the application’s POM. A standalone example under examples/ has its own POM; it is not necessarily a root reactor module. Keep the project’s compiler, runtime and plugin versions aligned. Do not replace them with a guessed release or silently upgrade Spring, Java or Flyway. Use the configured JDK and Maven wrapper if supplied.

Models normally live in src/main/vernac/<namespace-as-directories>/. Generated Java normally lives in target/generated-sources/vernac/. Edit Vernac and handwritten Java; do not repair generated Java by hand. Build output is not the source of truth for schema history.

Build and inspect

mvn generate-sources
mvn test

The first command executes generation when the POM binds Vernac to that phase. The second also compiles generated and handwritten Java and runs configured tests. Inspect the actual result: skipped database tests are not successful database verification. A language-only check cannot validate arbitrary embedded Java. An unresolvable embedded-Java class in IntelliJ may require a generation build and indexing of the generated source root; do not rewrite valid domain code to accommodate a broken editor inference.

For repository contributors rebuilding local compiler/plugin changes, use the repository’s build instructions and install matching snapshot artifacts before building a separate example. verify alone does not install them locally.

Inspect the schema without changing a database

mvn vernac:schema

Inspect target/vernac-schema/schema.json and schema.sql. The SQL describes the complete expected schema; it is not an incremental migration to run against an existing database. This goal does not execute application SQL.

Generate the initial or next migration candidate

After changing persisted models, including embedded VOs from dependencies:

mvn vernac:migration -Dvernac.migrationDescription=add_feature_tasks

Use a description appropriate to the actual change. The same goal handles initial and subsequent migrations. It compares the resolved current model with the latest source-controlled schema snapshot. It does not diff an arbitrary live database. An unchanged model produces no new candidate.

For applications, review both new files together:

Commit the SQL and matching snapshot together after review. Do not hand-edit the snapshot, remove prior history or overwrite applied/published migrations. For parallel unpublished histories, rebase and regenerate candidates on the integrated history instead of merging snapshots blindly.

Module projects with .vmodule normally keep SQL under src/main/vernac-schema/migration; module packaging supplies its own migration bundle. Consumers embedding changed exported VOs need their own application migration. Activation and module migration ordering are described in the module tutorial.

Required values, destructive changes and errors

A required new column can need an explicit, domain-approved SQL backfill. Do not invent one to make generation pass. Use the reviewed transformations JSON format from the migration tutorial and pass it with -Dvernac.transformations=src/main/vernac-schema/transformations.json.

Potentially destructive changes can require -Dvernac.force=true. Do not choose this override without the user’s authorization of that concrete change. It only allows candidate generation; it is not approval, execution or a safety guarantee. Renames and data conversions require explicit review; the generator cannot infer the author’s intent. Report divergence/backfill errors rather than deleting data, resetting Flyway or replacing existing migrations.

Verify candidates on a disposable PostgreSQL server

Obtain a designated test server and credentials from the user/environment: VERNAC_CHECK_URL, VERNAC_CHECK_USER, VERNAC_CHECK_PASSWORD. The administrative JDBC URL commonly ends in /postgres; the role needs CREATEDB permission. Never choose a production server or commit credentials.

mvn vernac:schema-check

The goal creates two temporary databases, replays migrations in one, creates the expected schema in the other, compares owned schema objects and removes those temporary databases. It does not migrate the application database. A successful check on empty databases does not validate existing production data, deployment ordering, performance or locking. Also test representative data where relevant.

Application startup and reporting

After review and approval, configured Spring Boot/Flyway startup applies pending migrations to the application datasource. Candidate generation and schema-check do not do this. Do not run startup against an arbitrary environment to test SQL. Never reset an application database or run Flyway clean/repair as a fallback.

Report changed models, generated candidate paths, checks actually executed, failures/skips and the review still required. The application owner alone is responsible for reviewing, testing and approving migrations before application; automated generation and verification do not transfer that responsibility.

Shell syntax

Commands above use Maven argument spelling suitable for IntelliJ’s Maven command field (without mvn) and POSIX shells. In PowerShell terminals, quote each complete dotted property argument, for example:

mvn vernac:migration "-Dvernac.migrationDescription=add_feature_tasks"

Do not put those shell quotes into IntelliJ’s Maven command field. Do not change the goal to deploy-file or switch working directories to work around an argument parsing error; check the active run configuration and shell first.