Repository navigation
RaySpec v1.7.0
The complete entry for this release is the ## [1.7.0] block in
CHANGELOG.md — Added,
Changed, Fixed, Documentation and Security. It is larger than a GitHub release body can
hold, so only its Upgrade notes are reproduced below, verbatim. Where they point at what is
documented "above", that is those changelog sections.
Upgrade notes
Everything below is documented in place above; this is the checklist. Nothing here applies to a
deployment that only authors specs and deploys them — the items are for embedders, for operators of an
existing database, and for clients written against the HTTP surface.
-
Three interfaces gained REQUIRED members, so an out-of-repository implementation stops
typechecking until it grows them.ServerConfig(@rayspec/server) gains
tenantBootstrapEnabled: boolean; the neutralDurableExecutor(@rayspec/platform) gains
cancel(jobId: string): Promise<void>;CronSchedulerDeps(@rayspec/durable-dbos) gains
tenantExists(tenantId: string): Promise<boolean>. A deployment that builds its config with
loadServerConfigneeds no change — it fills the new field from the environment; only code that
constructs one of these objects itself is affected. -
Apply migration
0010_journal_step_error_columns. Two additive nullableADD COLUMNs on
journal_steps; no table rewrite and no backfill. -
A product deployment whose
RAYSPEC_PRODUCT_TENANT_IDis malformed, or names no live org, now
refuses to boot where it previously came up and waited for the org to appear. Settle the org before
deploying —rayspec tenant ensure --org-id <uuid> --name <n>does it againstDATABASE_URLwith no
running server. The cron tenant is deliberately unchanged. -
A store read through the handler data facade with no explicit
orderBynow comes back ordered
id asc. A caller that passes its ownorderByis unaffected. Code that depended on the previous
unordered result should state the order it wants. -
A mounted static frontend answers non-content methods with
405and anAllow: GET, HEAD, OPTIONSheader, where such a request previously fell through to the SPA shell with200. A client
that sent one and read the shell as success will now see the refusal. -
/healthcarries one more field and one more status value. A probe that matches the body exactly
should acceptfrontendnext todb, andstatus: "degraded"with503when a covered dependency
is not ready. -
errorClasshas a new terminal value,cancelled. A client that enumerates error classes should
accept it; a same-key retry replays it rather than starting a new run. -
The two auth secrets are no longer mirrored into
process.env. Code that read
RAYSPEC_JWT_SIGNING_KEYorRAYSPEC_API_KEY_PEPPERback out of the environment after boot now finds
nothing there, and a spawned child no longer inherits them. -
A deployment booted from a
*.product.yamldocument starts running the daily system cleanup, and
one half of it deletes data. The job did not run there before, so on such a deployment both halves
are new behavior. The OIDC prune is ungated and starts hard-deleting expiredoidc_modelsrows on
the first scheduled instant after the upgrade; on a deployment that has been up for a while that
first pass can clear a large accumulated backlog in one go — these are already-expired OAuth
artifacts, but the delete is real. The GDPR tombstone purge runs only ifRAYSPEC_GDPR_PURGE_ENABLED
is exactlytrue: if you have that gate armed on a product deployment today you have been getting
nothing from it, and after this upgrade you get the irreversible hard-delete the gate asks for — every
user tombstone older thanRAYSPEC_GDPR_RETENTION_DAYS(default 30), and every membership tombstone
older than its own org'sorgs.retention_dayswhere that column is set, else that same default, goes
on the first pass, across every org in the database rather than only the deployment tenant. Confirm
that is what you want before upgrading; leaving the variable unset, or set to anything other than
true, keeps the purge as a dry run that counts and deletes nothing, and that dry run is the only
mitigation the shipped surface offers — the on-demand seam is in-process
(BootedServer.runCleanupNow, for a host that embeds the server), so there is no command to run the
pass once under supervision first.RAYSPEC_CLEANUP_SCHEDULE
(default0 3 * * *) now actually decides when that pass happens on this
deployment shape — and because the expression is handed to the worker's scheduler as written, a value
that scheduler cannot parse now aborts the boot of a product deployment that previously ignored it.
The scheduler takes the standard 5-field crontab and the 6-field form that prepends a seconds field;
shorthand such as@daily, a 4-field expression, or an out-of-range field is refused, and the refusal
is the scheduler's own error, which names neither the variable nor the cleanup. Check the value before
upgrading. Registering the job also adds one durable workflow to this deployment, which rotates the
DBOS application version the product boot runs under: runs a pre-upgrade process enqueued or left in
flight carry the old version and are neither dequeued nor recovered by the new one, so let the durable
queues drain before restarting into this release (theapplicationVersionthat/recovery-scope
reports changes with it). Deployments booted from a classicrayspec.yamlare unaffected: the job is
wired there whenever the spec declaresdeployment.durableWorker: trueand backends are wired, exactly
as before — a classic spec that declares no durable worker never ran this job and still does not. -
rayspec gen-handlernow refuses a holes file carrying a key the hole shape it sits in does not
declare, where it previously ignored the key and rendered anyway. This applies at the top level
(per template) and inside eachcolumns[]entry,fkRevalidate, andclampValuesrule. A holes
file that only uses declared keys is unaffected and renders identical bytes; one that carried a
typo, a key of the other template, or a hand-added comment/metadata key at any level stops with
ok: falseand exit1, and the error names the key (and the declared key it is a near-miss of).
Fix the key or drop it — a build step that runsgen-handlerwill fail until it is settled, which
is the point: that key was configuring nothing. -
If you were reading your agent traces in the OpenAI dashboard from a
rayspec deploy
deployment, setRAYSPEC_AGENT_TRACING=openaibefore upgrading, or they stop arriving. That path
now leaves the export off unless the variable is exactlyopenai;rayspec-serveand the local
development wrapper are unchanged. Set nothing else to that variable — any value other than
openaioroffrefuses the boot. Whichever way you leave it, the boot banner states the resolved
posture, so check theTrace export:line on the first boot after upgrading.
Release artifacts
rayspec-release-identity.json is attached. It pins this release to the commit it was built from and
records, per package, the tarball integrity and the unpacked file-list digest, plus the schema digests,
the lockfile and dependency-SBOM digests, and the Node/pnpm requirement. The package tarballs it pins
are attached alongside it, so the manifest can be checked against the exact bytes it describes.
The manifest is unsigned: this repository has no release workflow, so keyless CI signing would mean
moving the release into CI. Its authenticity comes from the authenticated release it is attached to.
Verified before publishing: verified: 29 package(s), 0 failure(s).
Packages
The npm registry publish for this version follows separately.