Wagoe 1.0.0 is out. If you have been waiting for a version you can build on without reading every changelog for breaks, this is it. Semantic Versioning now applies to the public surface: ports, schemas, :wagoe/* component keys and their options, configuration, and the CLI commands.
It is a new 1.0, not a mature one. Your first project will find things we haven’t. The promise is about how a fix reaches you, not that there will be none.
What you can rely on from here
-
A breaking change to the public surface needs a major version. Nothing in
1.xbreaks code written against a stable library in1.0.0. -
Nothing is removed without warning. A removal in
2.0must be deprecated in a1.xminor first, for at least one minor release and 90 days, whichever is longer. Deprecated vars carry^:deprecatedmetadata naming the replacement, so your editor and clj-kondo flag them. -
Every library carries the same version.
wagoe-user 1.0.0goes withwagoe-platform 1.0.0; you never work out a compatibility matrix. -
Generated code is yours. The scaffolder’s output is not covered — we change the generator, never your files.
Eight libraries are published as incubating and sit outside the guarantee, because we already know their API is not finished: payments, config, ai, geo, external, reports, audience and workflow. Saying so now is cheaper for you than a 2.0 for a fix we can see coming. wagoe list modules and wagoe add print a library’s tier, so you learn it before you depend on it. The stability page gives the reason for each, and what promotes a library to stable.
Pin exact versions. The discontinued 1.0.1-alpha-42 still sorts above 1.0.0 under Maven ordering, so a version range or anything resolving "newest" picks the old alpha. Pre-releases from here are cut from the next minor — 1.1.0-rc-1, never 1.0.1-alpha-1 — so this cannot happen again.
Breaking: three, in 1.0.0 itself
The release candidates said a break would land in an RC, never in 1.0.0. Three did anyway, rather than promise, for the life of 1.x, a shape we already knew was wrong. The list for 1.0.0 closes at twenty-eight. Each is under # Breaking in the changelog.
-
Every JSON error body is
{"error": {"type": …, "message": …}}. Refused input isvalidation-error. Readerror.typeanderror.message;detailsandcorrelation-idmoved insideerror. -
A write a unique or foreign key refuses is
409 conflictnaming the field, on H2, SQLite and PostgreSQL. It was a500. A scaffolded API answered a missing reference with400: read409. -
A scaffolded API refuses a delete or move below
--minwith409 conflict, as the admin does. It was400. Only regenerated service files change; an existing module keeps its400.
Fixed: a client’s mistake is not a 500
The one error shape came out of a pass over every endpoint asking what a client’s mistake answers. Too often it was a 500, sometimes with exception text in it:
-
An unknown admin entity, and a workflow admin id that is not a UUID, answer
404. -
Profile preferences, password and MFA setup answer
400or404for bad input or a deleted user. -
The MFA endpoints no longer put an exception’s text in a
400. -
Audience `422`s send the fields' messages, not the whole Malli schema.
-
The search API reads the body it is sent; indexing answered
500, and a search ran for"". -
The audit log page works on H2.
-
A duplicate unique value in the admin marks the field instead of saying "Failed to create Invoice".
Fixed: bb db:reset, bb db:seed and bb setup
-
bb db:resetkept users, sessions and tenants. It now drops everything the app owns, then migrates — and only in an explicitly nameddev,testoracc, confirmed by the database name. Prod changes through migrations.--helpprints usage instead of running the reset. -
bb db:seedruns wherebb db:resetdoes, honoursbb db:seed path/to/file.edn, and says what each seed hook did: "Started 3 workflow instances (invoice-workflow)". -
bb setup --prod true … --ai-provider xexited 1. It writes the rest and leaves AI out of prod, and its next steps name the variables prod actually reads. -
bb doctorsees a user module switched on in:extra-modules, and treats an unsetREDIS_PASSWORDas a warning, not a failure. -
bb ai admin-entityandbb scaffold airefuse without a terminal unless you pass--yes;--forcenever prompts. -
A
bb scaffoldwizard’sCommand:line pastes back — it is shell-quoted now.
Fixed: workflows and the admin
-
A workflow transition answered
"available-transitions": null, in the workflow API and a scaffolded/:id/transition. Both now list what the caller may do from the new state. -
The workflow boot put a unique index on
workflow_instancesin production. It changes that table only in dev, test and acc now; elsewhere it warns you to runbb migrate up. -
Admin toasts named one record in the plural, "Invoices created successfully". One record is singular, and translated; set
:label-singularwhere the automatic singular is wrong. -
Every boot logged each full
CREATE TABLEat INFO. DDL is DEBUG now. Copy themigratus.databaselogger fromwagoe new’s `logback.xml. -
A dev server on
HTTP_PORT=3200logged "searching ports 3000-3099". The log names the port requested and the port bound. -
Every
bb guidetopic matches the code, andbb guide seedexplains the seed file.
Added: seed data that writes itself
-
The seeder fills in
id,created-atandupdated-at, and a child names its parent by a symbolic id::id :invoice/acmeon the parent,:invoice-id :invoice/acmeon the child. -
bb scaffold generateandentityadd a commented example per entity toresources/seeds/dev.edn. Uncomment one to seed it; existing seeds are kept. -
workflow_instances.entity_uuidholds the entity id as a UUID, indexed. Join on it instead of castingentity_id.migrate upadds it, rewriting the table once on PostgreSQL.
Version alignment
All 31 artifacts bumped to v1.0.0 to maintain lockstep versioning.
Upgrade
Re-run the installer to pick up the latest release:
curl -fsSL https://get.wagoe.org | bash
Coming from rc-4, in this order:
-
Pin
1.0.0exactly indeps.edn, not a range. -
Run
bb migrate upto addentity_uuid. On PostgreSQL it rewritesworkflow_instancesonce; plan for that on a large table. -
API clients read
error.typeanderror.message, and expect409where a unique or foreign key refuses a write. -
Logging: copy the
migratus.databaselogger from a freshwagoe newproject’slogback.xml. -
Scripts that drive
bb ai admin-entityorbb scaffold aiwithout a terminal pass--yesor--force.
Coming from an earlier candidate, work through the rc-4 upgrade list first.