v0.17.2
Fixed
-
rebase db pushwas impossible for any collection declaring a
{ type: "vector" }property. The column compiled toVECTOR(n)in
drizzle/schema.sql, and Atlas computes its desired state by materialising
that file in a scratch database it creates empty and empties again at the
start of every run — so the type was resolved against a database that
structurally cannot have pgvector, and every push died with
pq: type "vector" does not exist. Not intermittently: permanently, for the
framework's own embedding property.Nothing in userland got past it. Seeding the extension does not survive
Atlas's clean (measured: present before the run, gone after), a
CREATE EXTENSIONin the desired state is refused as a paid feature, an
extension in a non-publicschema makes the scratch database "not clean",
and--excludefilters the diff only after the file has been parsed and
applied.Vector now takes the carve-out full-text search already had. The column, its
ANN indexes and the extension are generated intodrizzle/vector.sql, Atlas
is told to exclude them, and Rebase applies the file itself after
schema applyand appends it to migrations. Excluding the column turns out
to be enough on its own — aNOT NULLorUNIQUEon it is a property of
the column and goes with it. -
rebase db generateandrebase db migratewere both down for any project
with asearchblock.--excludeis accepted byatlas schema applyand
by nothing else, and the guard that added it read as a subcommand test
without being one:migrate applymatchesargs.includes("apply")exactly
asschema applydoes. Atlas rejects an unknown flag before doing any work,
so both commands exited withunknown flag: --exclude. Present since the
same commit that started appending search DDL to migrations, which means that
append had never once run. -
A migration could carry a
DROP COLUMNfor a search or vector column
nobody asked to lose.migrate diffcomputes the current state by
replaying the migration directory — which builds those columns, because that
DDL is appended to migrations — and diffs it against aschema.sqlthat
deliberately omits them, so Atlas plans a drop. Nothing caught it: the
destructive gate reads the push plan, and this is a file applied days
later. Those statements are now removed from the file Atlas writes, clause by
clause because Atlas folds the phantom drop into whatever real change shares
the table. A drop the CLI cannot rewrite stopsdb generaterather than
being guessed at. -
A no-op
rebase db generategrew the last migration every time it ran.
TheCREATE SCHEMArewrite and the RLS policy append were not gated on Atlas
having written a new file, so a run that found nothing to diff appended
another copy of the policies to a migration that had already been applied in
production — changing a hash Atlas had recorded, while the appended SQL ran
nowhere. -
Live schema editing left behind a
schema.sqlthatdb pushchokes on.
The commit generated it whole, so it carried the RLS policies, the search
helpers Atlas will not parse, and the vector column. It now writes the same
splitrebase db generatedoes. -
rebase devcould not host a vector column at all. The managed
development database derived every extension bundle's module path as
@electric-sql/pglite/contrib/<name>, which does not exist for pgvector — it
is a package of its own, and it was not declared.CREATE EXTENSION vector
failed there withextension "vector" is not available, which reads like a
broken database rather than a missing import. -
rebase db push --helpapplied the schema. The flag printed usage and
then ran the command it was documenting, against whatever database the project
was pointed at. Asking what a destructive command does is the one moment you
are most certain not to want it to happen. -
A first deploy deadlocked on a step nothing named. A project created with
rebase cloud projects createhad no database, was written
status: "provisioning", and stayed there: nothing was in progress, the
platform was waiting forrebase cloud db create, and no output, help page or
skill named that command. "Provisioning" reads as work underway, and the
correct response to work underway is to wait — so the correct response to this
state was the one thing guaranteed never to resolve it. Measured at 43 minutes
of polling on a real first deploy; an unattended agent would still be polling. -
cloud deploymeant two different things depending on the runtime. The
managed-bundle path stopped at "deploy started" and told you to run
cloud logs, while the source path waited and made its exit code the verdict —
so the same command returned 0 for builds that went on to fail. It now follows
on both paths unless--no-followsays otherwise, and takes--waitand
--timeout. -
A cluster's refusal was printed as if it were yours. Failures arrived as a
whole KubernetesStatusobject with request headers, an audit id and a
flowschema uid. Worse than the noise: a403naming a
system:serviceaccount:is the control plane's OWN credentials being refused,
which nothing in a user's project can grant — and printed raw in a failed
deploy it reads exactly like a project fault. Someone acting on that reading
deletes working code. Failures are now classified before they are summarised,
carryplatform: truein the JSON, and say in words when retrying and
changing the project will not help. The untouched body stays behind--debug. -
clusters verifynever saw the id it was given. It selected one from
rawArgs, which is the whole ofprocess.argv, so the first match was the
node binary path: every invocation asked about a cluster called
/usr/bin/node, got a 404, and read as "this diagnostic is not deployed yet".
It is the one command that reportspermissions.allowed/permissions.denied
for a cluster, so the diagnostic for a missing RBAC grant was itself
unavailable.
Added
-
rebase cloud projects create --db managed|byodb|none, defaulting to
managed, so the sequence every project needs is one command rather than two.
--db noneis the deliberate opt-out and still prints the command that
finishes the job. -
blockedOnandnextActiononcloud status.blockedOn: nullis the
load-bearing value — it is the CLI saying that waiting is correct, and the only
condition under which pollingstatusmakes sense. Every other value names a
command. -
db create --wait, which polls a bring-your-own database until it answers.
For a managed one it reports that there is nothing to wait for and returns,
since a loop there would be the same non-terminating wait in a new place. -
A
rebase-cloudagent skill, andrebase-deploymentnow points at it. -
database({ extensions: ["vector"] }). Declared inconfig/resources.ts,
it letsrebase db pushand the boot schema-ensure run
CREATE EXTENSION IF NOT EXISTS vectorfor you.A permission rather than a request: the statement is issued only where
something in the schema needs it, so naming an extension nothing uses
installs nothing. It is opt-in because everything that decides whether the
install can succeed — the image shipping the library, the role's grant, a
managed provider's allow-list — is invisible from inside the connection.
Saying nothing withholds the install, never the column, so a database where
pgvector was installed by hand keeps working with no configuration.database()also accepts options in place of a key, since the default
database has no name to pass.
Changed
- A changed
dimensionson a vector property is no longer silent. Atlas used
to own the column and plan the type change; now that it cannot see it,
ADD COLUMN IF NOT EXISTSwould have done nothing and left the old width
behind a config that says otherwise. The generated DDL widens the column when
it holds no values and refuses — naming the statement to run — when it does.
Removed
seedDevDatabaseSearchHelpers, which never did anything. Its docstring
claimed an excluded column is still materialised in Atlas's scratch database;
it is not. Measured with a real generatedtsvectorcolumn: a seeded scratch
database and an empty one produce byte-identical output in every
configuration, and Atlas wipes that database before it plans. The--exclude
patterns were always the whole protection.