3488 Commits

Author SHA1 Message Date
Ryan a08663c7b9 Version bump 2.7.0 (#5399)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

- Bumps version to 2.7.0

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None

# Expected complexity level and risk

- 1 - this is just a version bump

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Version number is correct (`2.7.0`)
- [x] BSL license file has been updated with the new date and version
number
v2.7.0
2026-06-22 04:08:56 +00:00
clockwork-labs-bot 353557cede Track outgoing queue disconnects (#5331)
# Description of Changes

Adds a Prometheus counter for client disconnects caused by the outgoing
WebSocket message queue reaching capacity.

The new metric is
`spacetime_client_outgoing_queue_disconnects_total{db=...}`. It
increments only on the `TrySendError::Full` path that kicks a client
after its bounded outgoing queue fills.

# API and ABI breaking changes

None.

# Expected complexity level and risk

1. This is a narrow observability change: one metric definition and one
increment at the existing kick site.

# Testing

- [x] `cargo fmt --all`
- [x] `LC_ALL=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 LANG=en_US.UTF-8 cargo
check -p spacetimedb-core`
- [x] `git diff --check`

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-20 13:27:42 +00:00
Jason Larabie 95e61f415c Unreal SDK query builder (#4810)
# Description of Changes
- Added a client-side query builder for the Unreal SDK
- Added typed query-builder subscriptions for Unreal C++ via
SubscriptionBuilder.AddQuery(...).Subscribe()
- Added generated Blueprint query-builder support with source query
nodes, column nodes, predicates, Where, AddQuery, and Subscribe
- Added Blueprint autocasts at the AddQuery boundary so source-specific
Blueprint queries can connect cleanly into the generic subscription
builder for better devex in Blueprint
- Synced the Unreal query-builder core with the C++ module
implementation
- Updated the copied Unreal core query-builder headers to match the
shared C++
- Moved Unreal-specific literal/type adapters out of the shared core
copy and into Unreal-specific expansion code
- Added Unreal SDK test coverage and documentation for the new
query-builder surface
  - Added new test harnesses to start to match the View/ViewPk tests
- Added documentation for the Unreal query builder
- Refactor generation for modules with more than 255 reducers, required
to get the TestClient back in working order

# API and ABI breaking changes
- No intended API or ABI breaking changes to released Unreal SDK
behavior
- Adds a new public client-side query-builder API to the Unreal SDK for
C++ and Blueprint
  - Raw SQL subscriptions remain available

# Expected complexity level and risk

3 - Adds new query-builder surface with large changes to the code-gen,
the risk here is keeping the C++ module core mirrored to the SDK in the
future

# Testing
What I've done so far:
- [x] Updated and ran the following tests:
  - [x] TestClientEditor
  - [x] TestViewClientEditor
  - [x] TestViewPkClientEditor
- [x] Ran the Unreal harness suites covering the query-builder client
paths
- [x] Verified the generated Unreal query-builder surface in both C++
and Blueprint testing supported fields with a small sample project

Should be done at least once by a reviewer:
- [ ] Re-run the full `sdk-unreal-test-harness` as it's disabled in CI
- [ ] Play with the C++ and Blueprint versions in a small Unreal project

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-19 23:52:02 +00:00
Jason Larabie 47a7794111 Add small module-test* as a compile check for http handlers (#5330)
# Description of Changes

HTTP handlers already have smoketest coverage, but in order to add to
`module-test`s all languages had to have parity as `module-test` has a
check to ensure schemas match.

The existing integration tests using `module-test` load SpacetimeDB in
memory, expanding these tests would require significant and potentially
ugly work to handle hosting for HTTP handlers. Instead, this PR adds
compile-only for each `module-test` with a matching handler + route.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1 - tiny addition to `module-test` for all languages

# Testing

- [x] `cargo test -p spacetimedb-schema module_test`
- [x] `cargo test -p spacetimedb-testing`
2026-06-19 17:40:34 +00:00
Jason Larabie cf73acff92 Add primary keys for C++ procedural views (#5354)
# Description of Changes

Adds primary keys to procedural views in C++. This mirrors the work from
#5111, #5246, and #5327 adding the feature and the docs changes.

# API and ABI breaking changes

None

# Expected complexity level and risk

3

# Testing

- [x] Equivalent tests as were added in #5111 and #5246 for rust,
typescript, and C#
2026-06-18 22:43:51 +00:00
Kilian Strunz d8de4ab980 Allow to use Uuid as literal value in ts Query Builder (#5075)
# Description of Changes

Was forgotten while migrating to the QueryBuilder i suppose.
Closes #5073

Maybe @clockwork-tien could lend a hand again in reviewing? ^^

# API and ABI breaking changes

None
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing
Works in my project :>
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Type Error goes away when using .eq(uuid)

---------

Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
2026-06-18 19:44:29 +00:00
clockwork-labs-bot e357f5a677 Fix release notification workflow startup (#5394)
# Description of Changes

Fixes the `Release Notifications` workflow startup failure seen in
<https://github.com/clockworklabs/SpacetimeDB/actions/runs/27775721225/workflow>.

The internal announcement job referenced `needs: on-release`, but no
`on-release` job exists in `.github/workflows/tag-release.yml`, so the
workflow failed before scheduling any jobs. This removes the dangling
dependency and gates the internal Discord announcement to real `release`
events so manual `workflow_dispatch` dry runs do not try to send an
internal release announcement using missing release-event fields.

# API and ABI breaking changes

None. This only changes GitHub Actions configuration.

# Expected complexity level and risk

1 - Low complexity. The change is limited to one workflow job
dependency/condition.

# Testing

- [x] Parsed `.github/workflows/tag-release.yml` as YAML.
- [x] Checked that all remaining `needs:` targets in
`.github/workflows/tag-release.yml` refer to existing jobs.
- [x] Ran `git diff --check`.
- [ ] Optional reviewer check: run the workflow manually with the
default dry-run inputs after merge.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-18 18:36:03 +00:00
Ryan a9629de937 Adds a GitHub automation to send Release Notes to our public Discord (#5383)
# Description of Changes

Creates a new GitHub action that triggers any time a `Release` on the
SpacetimeDB repo changes to the `published` state.
When this triggers, the workflow will take information from that
release, and build a message from it, in the form of:
```
**SpacetimeDB ${RELEASE_TAG}**

View the full release notes:
${RELEASE_URL}

${RELEASE_BODY}
```
And send that message to the SpacetimeDB Public Discord Webhook.

Note: This PR itself does not setup or configure the Discord Webhook,
and relies on the Webhook URL already being available.

# API and ABI breaking changes

No API or ABI changes, this is only related to GitHub tooling.

# Expected complexity level and risk

1 - Low complexity. The only risk is in sending garbage messages to the
Discord URL if this automation is improperly configured.

# Testing

- [X] Ran a local version of similar code to test formatting. No testing
of this GitHub Action has been performed.

---------

Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-06-18 16:06:30 +00:00
joshua-spacetime 156d515afe Remove Promise.withResolvers and replace with deferred pattern (#5384)
# Description of Changes

Removes all references to `Promise.withResolvers` from the codebase
since it's not supported universally and replaces it with the classic
pre-ES2024 deferred pattern. See #5031 and #5342.

Also adds a lint to avoid re-introducing it in the future.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

...
2026-06-18 14:21:12 +00:00
clockwork-labs-bot 1e51e32852 Fast-path no-op merge queue CI (#5381)
# Description of Changes

Adds a merge-queue fast path for CI when the synthetic merge-group
commit has the same tree as the queued PR head.

The new `merge_queue_noop` job parses the PR number from the merge-group
ref, resolves the PR head SHA, and compares that tree to `GITHUB_SHA`.
If there is no diff, the expensive CI jobs are skipped as duplicate
work. Matrix jobs with required per-matrix check names get lightweight
no-op counterparts so branch protection still sees the expected
successful check names.

# API and ABI breaking changes

None.

# Expected complexity level and risk

2. This is limited to GitHub Actions wiring, but it interacts with merge
queue semantics and required check names. The implementation
intentionally falls back to normal CI if it cannot parse the PR number
or resolve the PR head.

# Testing

- [x] Parsed `.github/workflows/ci.yml` with Ruby YAML.
- [x] Ran `git diff --check`.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-18 00:58:27 +00:00
clockwork-labs-bot f24e9615ec Refactor smoketest publish and subscribe helpers to builder pattern (#5283)
# Description of Changes

Refactors the Rust smoketest helper surface so publish and subscribe
variants use builders instead of parallel helper methods.

- Replaces `publish_module*` helper variants with `Smoketest::publish()`
and fluent options for name, clear, current database, break clients,
stdin, replicas, organization, and source modules.
- Replaces `subscribe_*` / `subscribe_background*` variants with
`Smoketest::subscribe(...).expect_rows(...).confirmed(...).background()`.
- Updates smoketest call sites to the builder APIs.

# API and ABI breaking changes

Internal smoketest helper API change only. No product API or ABI
changes.

# Expected complexity level and risk

2

This touches many smoketest call sites, but the underlying CLI command
behavior remains centralized in the same helper internals.

# Testing
- [x] Existing CI passes

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-17 15:16:17 +00:00
joshua-spacetime 1747ca6c3d Use the normal shutdown path for the standalone integration tests (#5350)
# Description of Changes

This is an attempt at fixing a SIGABRT that sometimes happens when
running the standalone integration tests.

It's not clear exactly what causes it, however one thing that may have
contributed to it was that previously the tests did not initiate a clean
shutdown of the database.

Some modules schedule repeating work in `init`, and it's not obvious to
me that in flight operations will exit cleanly if we just drop all of
the database/runtime handles at once.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

This is a testing fix.
2026-06-17 14:53:12 +00:00
clockwork-tien 695b97827d spacetime init --template without arg prints template list and link to website (#5264)
# Description of Changes
- spacetime init --template without arg prints templates list and link
to website

# Screenshot
<img width="696" height="392" alt="screenshot"
src="https://github.com/user-attachments/assets/98e87537-554b-411b-96ab-3ceb9a6a9d45"
/>

<!-- Please describe your change, mention any related tickets, and so on
here. -->

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk
1

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] I tested the changes
2026-06-17 10:21:32 +00:00
Kilian Strunz 3ec168d146 [Procedures] Fix Identityand ConnectionId Regression (#5323)
# Description of Changes

Closes #5250

#4636 introduced a regression where the ProcedureContext used to include
the sender and connection_id from the caller while now it is always
empty (which is wrong)

Correct it.

Also fully migrate to `database_identity` which was forgotten about so i
deprecated it for procedures (since they are now stable) and just
changed it for HttpHandlers (because they are still unstable)

@gefjon since you did the lil woopsie (ugh pinging you again lol hope im
not annoying haha)

# API and ABI breaking changes

Breaking the HttpHandler function which is unstable.

Restoring behaviour of 2.3 which got lost with 2.4.
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1. Trivial refactoring 
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] The caller identity is there again for Procedures.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-17 04:00:55 +00:00
joshua-spacetime 5ea558ed1b Drop tps threshold in keynote bench (#5360)
# Description of Changes

Reviewing recent benchmark runs, it appears that #5071 probably
regressed TPS by around 3-5%. I don't want to revert that change because
it has implications for replication, and so for now we'll just live with
the slight regression.

# API and ABI breaking changes

None

# Expected complexity level and risk

0

# Testing

N/A
2026-06-17 03:34:17 +00:00
joshua-spacetime b929eb5ef6 Skip bsatn decode proptest (#5361)
# Description of Changes

Attempted to fix this test in #5343, but we're still getting SIGKILLS,
so ignoring for now. This will require more investigation to fix. I've
included what I believe is the reason in the help text and created
[this](#5362) tracker to unskip.

# API and ABI breaking changes

None

# Expected complexity level and risk

0

# Testing

N/A
2026-06-17 02:45:35 +00:00
clockwork-labs-bot f8ccbbed7a Re-land spacetime lock/unlock to prevent accidental database deletion (#4888)
Re-lands #4502 on current `master` after the revert in #4881.

## Summary
- restore `spacetime lock` / `spacetime unlock`
- block deleting locked databases
- restore the database-lock smoketests

## Validation
- `cargo fmt --all --check`
- `cargo check -p spacetimedb-cli -p spacetimedb-client-api -p
spacetimedb-standalone`

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-06-17 01:15:05 +00:00
joshua-spacetime fc47257d85 Use SpacetimeDBGuard for SDK test suite (#5340)
# Description of Changes

Use an isolated server process per SDK test instead of a single process
for all of the tests. In addition to reducing the memory footprint of
each test run, this should also allow for more parallelism among the
individual tests.

# API and ABI breaking changes

None

# Expected complexity level and risk

1.5

# Testing

The SDK test suite should continue to work
2026-06-17 00:16:10 +00:00
Kris Jenkins b85f7786d6 Use non-deprecated databaseIdentity accessor in docs reference tables (#5321)
# API and ABI breaking changes

None. Docs-only change.

# Expected complexity level and risk

1 - trivial documentation fix, no code or behaviour change.

# Testing

- [x] Confirmed accessor names against the SDK source:
`database_identity()` (Rust/C++), `databaseIdentity` (TS),
`DatabaseIdentity` (C#); the old forms are marked deprecated/obsolete in
bindings.

# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

The reducer-context cheat-sheet and the "Context Properties Reference"
tables still listed `ctx.identity` / `ctx.identity()` as the accessor
for the module's own identity. That accessor was deprecated in favour of
`databaseIdentity` / `database_identity()` / `DatabaseIdentity`, and the
troubleshooting guide added in c70d00246 (#5142) documented the
deprecation but missed updating these other references — these stray
updates should have landed there. This brings all four language tabs in
line with the non-deprecated accessor.

Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-16 21:11:15 +00:00
clockwork-labs-bot 59b5d49ba2 Fix Internal Tests paths filter checkout (#5295)
## What changed

Adds an explicit checkout step before `dorny/paths-filter` in the
Internal Tests workflow.

## Why

`dorny/paths-filter@v3` needs a git working tree for `push` events. The
Internal Tests workflow ran it before any checkout, so every `push` run
on `master` failed immediately in `Detect non-docs changes` with:

```text
fatal: not a git repository (or any of the parent directories): .git
```

This only showed up consistently on `master` because those runs are
`push` events. On `pull_request` events, `dorny/paths-filter` can use
the GitHub pull request files API with the PR number, so it does not
need a local checkout for the same file detection path.

Adding checkout gives the action a repository when it handles `push`
events, while leaving PR behavior unchanged.

## Testing

- `git diff --check`
- PR #5295 `Internal Tests` job completed `Checkout` and `Detect
non-docs changes` successfully, then moved on to private dispatch/wait.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-16 20:14:16 +00:00
John Detter fc2f7614bb Remove unused docker workflow (#5349)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

We believe this docker build is completely unused. This docker container
is different than the docker build that we send out for releases which
is the one users actually end up using. This specific docker build used
to be for internal deploys but we have not used it in a very long time
now, probably more than a year or two.

# API and ABI breaking changes

None - this is just a CI change.

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1 - just a CI change

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- Not tested but we sync'd on this in the discord and there were no
objections from the devops team or @joshua-spacetime .

---------

Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-16 19:57:33 +00:00
John Detter ab280222fa Remove spacetimedb-update test on aarch64 (#5348)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

This removes the `spacetimedb-update` check specifically on arm. This
test doesn't have a whole lot of value because we're already covering
Linux + Windows on x86 and then macOS on aarch64. Removing this will
allow us to decom the arm runner.

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None - just a CI change

# Expected complexity level and risk

1

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- I have not tested this but me and Zeke sync'd on this and we think it
makes sense.
2026-06-16 19:18:12 +00:00
Shubham Mishra 77ffdbbe18 Move RelationalDB to spacetimedb-engine crate. (#5113)
# Description of Changes

Moves `RelationalDB` and related database code into a new
`spacetimedb-engine` crate.
The main motivation is to tighten dependency control around the engine
layer and isolate `RelationalDB`
 behind a crate boundary.
  - Majority of this PR is code-motion.
- Removes direct production dependence on `tokio` from
`spacetimedb-engine`.
- Keeps `tokio` only as a dev-dependency for test-only code in
`spacetimedb-engine`.
- This is intended to be a structural refactor only and should not
result in any functional change in
  production.
- Adds a CI check to ensure `spacetimedb-engine` continues to compile in
simulation mode

# API and ABI breaking changes
NA

# Expected complexity level and risk
1.5.

# Testing
Existing tests should be enough.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-16 16:16:13 +00:00
clockwork-labs-bot 934158a36b Fix TypeScript optional row keys (#4940)
# Description of Changes

Fix TypeScript inference for generated object shapes containing
`Option<T>` fields.

Previously, generated TypeScript represented an optional SATS field as a
required object key whose value could be `undefined`:

```ts
{
  foo: string | undefined;
}
```

This PR changes those generated shapes to make the key itself optional:

```ts
{
  foo?: string | undefined;
}
```

The original issue was reported in #4516: generated TypeScript
reducer/procedure calls required users to pass explicit `undefined`
values for omitted optional arguments. This PR fixes that for reducer
and procedure params, and also applies the same optional-key inference
to generated row shapes.

This is a fresh bot-owned replacement for stalled PR #4518.

## Examples

A reducer with an optional argument now generates a TypeScript call
shape where the optional key may be omitted:

```rust
#[spacetimedb::reducer]
pub fn update_category(
    _ctx: &spacetimedb::ReducerContext,
    id: u64,
    name: String,
    button_text: Option<String>,
) {
    // ...
}
```

Before this PR, generated TypeScript callers had to pass the optional
argument explicitly:

```ts
await conn.reducers.updateCategory({
  id: 1n,
  name: 'updated category name',
  buttonText: undefined,
});
```

After this PR, generated TypeScript callers can omit the optional key:

```ts
await conn.reducers.updateCategory({
  id: 1n,
  name: 'updated category name',
});
```

A table row with an optional column also changes its generated
TypeScript row shape:

```rust
#[spacetimedb::table(name = player, public)]
pub struct Player {
    #[primary_key]
    pub id: u64,
    pub display_name: String,
    pub alias: Option<String>,
}
```

Before this PR, generated TypeScript treated `alias` as a required key:

```ts
type Player = {
  id: bigint;
  displayName: string;
  alias: string | undefined;
};
```

After this PR, generated TypeScript treats `alias` as an optional key:

```ts
type Player = {
  id: bigint;
  displayName: string;
  alias?: string | undefined;
};
```

# API and ABI breaking changes

This is a TypeScript source/API breaking change for generated type
shapes that contain `Option<T>` fields. It is not an ABI or wire-format
break: SATS encoding and decoding of `Option<T>` are unchanged.

The breaking edge is structural TypeScript code that requires optional
SATS fields to exist as object properties. For example, code like this
may stop compiling:

```ts
type RequiresAliasProperty = {
  id: bigint;
  displayName: string;
  alias: string | undefined;
};

function renderPlayer(player: RequiresAliasProperty) {
  return player.alias ?? player.displayName;
}

conn.db.player.onInsert((_ctx, player) => {
  renderPlayer(player);
});
```

With this PR, the generated `player` row has `alias?: string |
undefined`, so it is not assignable to a type requiring an `alias`
property.

Code using `Required<GeneratedRow>`, explicit generated-row mirror
interfaces, or generic constraints that require optional SATS fields to
be present as object keys may need to loosen those keys to optional
properties.

Reducer and procedure params are primarily loosened by this change.
Existing calls that pass `undefined` explicitly should continue to
typecheck, while calls can now omit optional keys.

# Expected complexity level and risk

2.

The change is contained to TypeScript type inference and generated
TypeScript test coverage. The main risk is source compatibility for
TypeScript consumers that depend on the old required-key shape for
`Option<T>` fields.

# Testing

- [x] `pnpm --filter @clockworklabs/test-app build`
- [x] `pnpm test`
- [x] targeted `prettier --check`
- [x] `git diff --check`

Closes #4516.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-16 16:07:22 +00:00
joshua-spacetime f26451133f Don't preallocate based on bsatn length prefix (#5343)
# Description of Changes

Fixes an OOM kill in the proptest `bsatn_invalid_wont_decode`.

`bsatn_invalid_wont_decode` generates arbitrary invalid bytes, proves
validation fails, then still calls full AlgebraicValue::decode. For
generated array-like types, decode reads a u32 length prefix, and the
generic array visitor then reserves that capacity. But because they're
random bytes, this could cause a huge initial allocation which could OOM
kill the test process.

Now the visitor reserves a smaller initial capacity instead of assuming
the binary input data is well formed.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

This should fix the flaky `spacetimedb-sats` `Test Suite` failures that
occasionally end in a SIGKILL.
2026-06-16 14:30:02 +00:00
joshua-spacetime a2ca083c48 Add args column to view backing tables (#5300)
# Description of Changes

Review #5287 first.

This patch updates view backing table schemas to have a single private
column `arg_hash`. Previously sender-scoped views had a `sender` column
for the calling identity, however now that's been replaced with a single
unified `arg_hash` column that encodes the calling identity within it.

When we add parameterized views, the view args will also be encoded in
this hash and stored in this column.

This column exists for both anonymous and sender scoped views meaning
that the backing tables for all views now have the same number of
private columns - one.

This hash is now used as a runtime variable that the query engine uses
to evaluate view table scans.

In order to keep the diff small, this patch does update view read sets
with this new hash value. That change has a larger blast radius and will
be done in the next set of changes.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

2

# Testing

Existing coverage.
2026-06-16 02:51:49 +00:00
Zeke Foppa 0f7615f202 Add stub release workflow (#5334)
# Description of Changes

Adding a stub version of this workflow so we can test it with
`workflow_dispatch`

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1

# Testing

None, can't test until it's merged

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-06-16 01:36:23 +00:00
Ryan 31fd1c8c33 Version bump 2.6.0 (#5326)
# Description of Changes

* Bump version to 2.6.0

# API and ABI breaking changes

None

# Expected complexity level and risk

* 1 - this is just a version bump

# Testing

- [X] Version number is correct (`2.6.0`)
- [X] BSL license file has been updated with the new date and version
number
v2.6.0
2026-06-16 01:11:36 +00:00
joshua-spacetime 4ae01aefbd Update docs for view primary keys (#5327)
# Description of Changes

All of rust, C#, and typescript are included.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

N/A - docs only change
2026-06-15 23:44:46 +00:00
joshua-spacetime 315afc938f Parameterized query plans (#5287)
# Description of Changes

Makes runtime parameters explicit in query plans (prerequisite for
parameterized views).

As part of this change, `sender` is no longer baked directly into query
plans as a literal value. Instead it is represented as a parameter in
the query plan. Values are supplied at runtime via a variable
environment called `ExecutionParams`.

Note, parameterized plans are still not shared across subscriptions yet.
That will be done in a follow up.

This is mostly a mechanical change. The majority of the diff is just
threading runtime params/variables through various call sites.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

...

# Testing

Existing coverage
2026-06-15 21:46:00 +00:00
clockwork-labs-bot eb5b287c95 Restore CLA Gate status publishing (#5329)
# Description of Changes

Restores `CLA Gate` as a repository-owned commit status on the actual
target SHA.

The merged workflow tried to use the Actions job result for `status`
events. Those runs are attached to the default-branch SHA, so a
`license/cla` status on a PR head can trigger the workflow without
creating any required context on the PR commit. This change mirrors the
`license/cla` result back to `CLA Gate` on the PR or merge-group SHA.

# API and ABI breaking changes

None.

# Expected complexity level and risk

1. This is a narrow workflow fix for the required CLA check context.

# Testing

- [x] Ruby YAML parse for `.github/workflows/cla-gate.yml`
- [x] `git diff --check`
- [ ] Confirm a new `license/cla` status posts `CLA Gate` on the same PR
head SHA

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-15 20:03:33 +00:00
Shubham Mishra 2fd8a87d3c Compilation guard && tokio::sync re-export from runtime crate. (#5255)
# Description of Changes

Runtime specific changes from
https://github.com/clockworklabs/SpacetimeDB/pull/5113.

- `spacetimedb-runtime` enforces exactly one feature at compile time:
`tokio` or `simulation`. It rejects both-enabled and neither-enabled
builds explicitly.

- This also keeps `tokio::sync` re-exported from runtime, look at code
comment for reasoning.

# API and ABI breaking changes

NA

# Expected complexity level and risk
1
2026-06-15 08:28:25 +00:00
clockwork-labs-bot b0a8070c95 Simplify CLA gate workflow (#5316)
## Summary
- keep the CLA Gate workflow using `cargo ci cla-assistant status` for
CLA Assistant lookups
- stop mirroring pull request/status `license/cla` results into a custom
`CLA Gate` commit status
- use a plain `pull_request` trigger for PR checks, and keep merge-group
status publishing for synthetic queue SHAs
- let the Actions job pass when `license/cla` is success and fail when
it is missing or non-success

## Notes
Merge-group handling is left as-is. This PR intentionally keeps the
helper command and only changes the workflow behavior needed to avoid
the custom status mirror on PR/status events.

## Testing
- `cargo fmt --all`
- `cargo check -p ci`
- `cargo ci self-docs --check`
- Ruby YAML parse
- `git diff --check`

`actionlint` unavailable locally.

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-15 01:26:58 +00:00
clockwork-labs-bot 0306826613 Announce GitHub releases in Discord (#5314)
## Summary
- Add a Discord announcement job for published GitHub releases.
- Use `DISCORD_WEBHOOK_RELEASE_CHANNEL_URL` so the target channel can be
configured as a GitHub secret.
- Run the announcement job even if Docker `latest` retagging fails, and
include the retag result in the message.

## Verification
- `ruby -e 'require "yaml";
YAML.load_file(".github/workflows/tag-release.yml")'`
- `git diff --check`

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-14 22:55:03 +00:00
clockwork-labs-bot d93b381719 Add CLA gate status wrapper (#5299)
## Summary
- Add a CLA Gate workflow that publishes a repository-owned commit
status.
- Mirror CLA Assistant license/cla status on pull requests and status
events.
- Publish CLA Gate=success on merge_group runs, because entries have
already passed PR checks before entering the queue.

## Required settings change after merge
 - Remove license/cla from required checks.
 - Add CLA Gate as the required CLA check.

This keeps CLA enforcement before merge queue while removing CLA
Assistant from the merge-group critical path.

## Test plan
 - Parsed .github/workflows/cla-gate.yml with Ruby YAML loader.
 - Ran git diff --check.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-14 22:26:28 +00:00
clockwork-labs-bot 11276aa839 Nest CLA Assistant retry command (#5313)
## Summary
- Move `cargo ci retry-cla-assistant` under `cargo ci cla-assistant
retry`.
- Rename the helper module to `cla_assistant.rs`.
- Update the Retry CLA Assistant workflow and generated `cargo ci` docs.

## Verification
- `cargo fmt --all`
- `cargo check -p ci`
- `cargo ci self-docs --check`
- `git diff --check`

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-14 20:08:59 +00:00
clockwork-labs-bot dc20faa611 docs: improve docs and agent discovery metadata (#5243)
## Summary

- Fix TypeScript view examples to use `ctx.sender` as a property,
matching the server SDK `ViewCtx` API.
- Update the architecture overview TypeScript view snippet to use
`players.rowType` and `undefined` for optional view returns.
- Clarify shared `ViewContext` prose so it does not imply every language
uses a callable `ctx.sender()` API.
- Improve docs agent-readiness metadata:
- publish `/docs/robots.txt` with a docs sitemap directive and
Content-Signal policy
- add Markdown alternate links for the existing `/docs/llms.txt` and
`/docs/llms-full.txt` outputs
- generate `/.well-known/agent-skills`-style discovery metadata under
`/docs/.well-known/agent-skills/` from the repo's existing `skills/`
source files during docs builds

## Validation

- `pnpm --dir docs build`
- `pnpm --dir docs typecheck`
- Verified the docs build emits `robots.txt` and
`.well-known/agent-skills/index.json`.
- Verified generated Agent Skills SHA-256 digests match the emitted
`SKILL.md` artifacts.

## Notes

The Cloudflare agent-readiness scan for `spacetimedb.com` still depends
on the root/marketing host exposing root-level files such as
`/robots.txt`, `/sitemap.xml`, and
`/.well-known/agent-skills/index.json`. This PR makes the docs origin
produce the corresponding docs-scoped artifacts at `/docs/...`; the root
host can route or mirror these if we want the exact `spacetimedb.com`
scan to pick them up.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: rain <rain@rain.local>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-06-13 20:37:38 +00:00
joshua-spacetime 2161148e8a Disable automatic snapshots in replay tests (#5297)
# Description of Changes

So as not to race with the manual snapshots in these tests.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

Fixes a flaky test
2026-06-13 13:00:43 +00:00
joshua-spacetime b53d3afc70 Move index scan tests into benchmark job (#5298)
# Description of Changes

Moves `test_index_scans` to its own job that uses the same runner as the
keynote benchmark.

This test had several issues:
1. It was a performance regression test that didn't run in an isolated
environment because it was just a test.
2. It measured timings by search the module log for `ns`(nanosecond) and
`us`(microsecond) suffixes

As a result it would occasionally flake.

Now it runs on dedicated hardware in an isolated environment, so we
shouldn't see anymore flakes.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

N/A
2026-06-13 02:56:06 +00:00
Tyler Cloutier b432c08f8b Replay: delete orphaned st_event_table rows after replay (#5289)
# Description of Changes

Follow-up to #5288. Stacked on that branch; only the last commit is new.

#5288 fixed `drop_table` to delete a dropped event table's
`st_event_table` row, but databases which already dropped an event table
on an unfixed version still carry an orphaned `st_event_table` row in
their commitlogs and snapshots. This PR adds
`fixup_delete_orphaned_st_event_table_rows` to
`rebuild_state_after_replay`, following the existing
`fixup_delete_duplicate_system_sequence_rows` pattern: after replay,
delete any `st_event_table` row whose table id has no row in `st_table`.

This heals affected databases on their next restart, with no migration
or operator action required. The fixup is a no-op for databases without
orphans, and skips cleanly when `st_event_table` does not exist yet
(histories from before event tables were introduced, where
`migrate_system_tables` creates it later).

# API and ABI breaking changes

None.

# Expected complexity level and risk

1. Same shape as the existing system sequence fixup; runs once per
database open over two small system tables.

# Testing

- [x] New unit test `test_fixup_deletes_orphaned_st_event_table_rows`:
creates a real event table, replays an orphaned `st_event_table` row for
a nonexistent table id (simulating a commitlog written by an unfixed
version), runs the fixup, and asserts the orphan is deleted while the
extant event table's row is preserved.
- [x] Verified end-to-end against a data directory produced by stock
2.5.0 which dropped an event table (and was bricked by the replay bug):
opened with a binary built from this branch, the database replays, the
orphaned `st_event_table` row is gone, and user data is intact.

---------

Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
2026-06-12 21:14:30 +00:00
Jason Larabie 346e2b2514 Add C++ query builder (#4664)
# Description of Changes
- Added a query builder for C++ module bindings
  - Added query-builder table/filter/join types
- Added semijoin support with compile-time checks for lookup-table and
indexed-field usage
  - Added support for returning query-builder queries from C++ views
- Hooked query-builder metadata into the C++ table/view macros and V10
module-def path
- Added test coverage for the new C++ query-builder behavior
  - Compile tests for pass/fail cases
  - SQL tests for generated query output
  - Added a C++ test module for view primary key coverage
- **Update:** Switched the core to pass the columns and index-columns
metadata with the table source for better client-side codegen to have
some shared code between server + client.
# API and ABI breaking changes
- No intended API or ABI breaking changes
- Adds a new public query-builder API to the C++ bindings
- C++ views can now return query-builder query types in addition to
materialized row results

# Expected complexity level and risk

3 - Mostly contained to C++ bindings, but it touches macros, view
registration/serialization, and module-def generation, so there are a
few places where the pieces need to stay in sync.

# Testing

I've done end to end testing of I think every type as well as built some
tests to confirm the SQL output.

- [x] Run the C++ query-builder SQL tests
[crates/bindings-cpp/tests/query-builder-compile/run_query_builder_compile_tests.sh]
- [x] Smoke test a generated C++ module using query-builder views

---------

Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-12 13:02:36 +00:00
joshua-spacetime 7b7e6a393f Stop tracking multiple plan types in the subscription cache (#5263)
# Description of Changes

Required before we add formal parameters to query plans which in turn is
required to support parameterized views.

Before this change, we cached two types of query representations for a
subscription - a physical plan and what we call a pipelined executor.

This was mainly an artifact of built up technical debt, so this change
removes the physical plan and only caches the actual executor for the
subscription, in preparation for adding bind variables that are
substituted by the executor at runtime.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

...

# Testing

Existing coverage
2026-06-12 13:01:02 +00:00
Gustavo Aguiar e415c924a9 Fix TypeScript React provider reconnect (#5185)
# Description of Changes

Fix TypeScript SDK React provider recovery when the underlying WebSocket
closes or reports an error while a `SpacetimeDBProvider` is still
mounted.

- Mark `DbConnection` inactive before emitting `disconnect` /
`connectError`, so lifecycle callbacks observe the closed state.
- Teach the React `ConnectionManager` to clear closed retained provider
connections and rebuild them after a short delay.
- Cancel pending reconnects during provider release so React StrictMode
cleanup does not create replacement connections.
- Detach manager callbacks from the old connection before reconnecting,
preventing stale closed connections from updating provider state.
- Use the latest same-key retained builder when a replacement connection
is needed.
- Add focused lifecycle/reconnect regression tests and document that
this recovery is provider-level only; direct `DbConnection` users still
own reconnection.

# API and ABI breaking changes

None. This does not remove or change public APIs. It changes React
provider lifecycle behavior so retained provider connections recover
after close/error.

# Expected complexity level and risk

3/5.

The change is localized to the TypeScript SDK, but it touches async
connection lifecycle behavior, timer cancellation, React provider
reference counting, and callback-visible connection state. Main risks
are duplicate reconnects, stale connection callbacks updating state,
using an outdated retained builder for replacement connections, or
StrictMode release/remount regressions. The implementation guards
against stale callbacks, detaches manager callbacks from closed
connections, and cancels reconnect timers during release.

# Testing

- [x] `pnpm --dir crates/bindings-typescript exec vitest run
tests/db_connection.test.ts tests/connection_manager.test.ts
tests/connection_manager_reconnect.test.ts`
- [x] `pnpm --dir crates/bindings-typescript lint`
- [x] `pnpm --dir crates/bindings-typescript build`
- [x] `pnpm --dir crates/bindings-typescript test`
2026-06-12 13:00:42 +00:00
Tyler Cloutier 2c9738d212 Fix commitlog replay of dropped event tables (#5288)
# Description of Changes

Fixes two bugs around dropping event tables.

**Bug 1:** a deterministic commitlog replay failure introduced in #5269
that permanently prevents a database from restarting after an event
table is dropped. Observed in production on 2.5.0:

```
ERROR ... Failed to open database: DatastoreError: Error deleting row ProductValue { elements: [U32(4134), U16(0), String("account_id"), Array([13])] } from table "st_column" during transaction 26002 playback: ... TableError: Table with ID `4134` not found in `st_table`.
```

## Root cause

Dropping an event table (a `RemoveTable` automigration) deletes its
`st_table`, `st_column`, and `st_event_table` rows in a single
transaction. `prepare_tx_data_for_durability` sorts delete ops by
ascending table id, so replay applies them in this order:

1. The `st_table` (table id 1) delete is replayed first. The table is
recorded in `replay_table_dropped` and its `st_table` row is removed.
2. The `st_column` (table id 2) deletes are replayed next. The handling
added in #5269 calls `is_event_table_for_replay`, which still finds the
table's `st_event_table` (table id 17) row, since that delete has not
been replayed yet.
3. `st_column_changed` is invoked to refresh the table's layout. It
calls `find_st_table_row`, which fails because the `st_table` row is
already gone.

Production replay runs with `ErrorBehavior::FailFast`, so the replica
fails to launch on every restart. The commitlog itself is intact:
databases bricked by this bug recover with no data loss once opened with
this fix.

#5269 tested in-place event table reschemas (which keep the `st_table`
row alive) but not drops.

## Fix

Skip the layout refresh when the referenced table was dropped earlier in
the same transaction, as tracked by `replay_table_dropped`. That set is
the existing mechanism for exactly this replay ordering hazard, and the
`st_table` delete is always replayed before the `st_column` deletes due
to the table id sort, so the guard is reliable.

**Bug 2:** `drop_table` never deletes the table's `st_event_table` row.
It cleans up `st_table`, `st_column`, `st_index`, `st_sequence`,
`st_constraint`, the accessor tables, and `st_scheduled`, but
`st_event_table` was missed when event tables were introduced. Dropping
an event table therefore leaves an orphaned `st_event_table` row,
verified empirically:

```
> SELECT * FROM st_event_table     -- after dropping the only event table
 table_id
----------
 4097
> SELECT table_id FROM st_table WHERE table_id = 4097
 (no rows)
```

The orphan is latent today (`st_event_table` is only read via point
lookups by live table ids), but it is the precondition that exposed bug
1, and it is incorrect catalog state. `drop_table` now deletes the row.

Note that both fixes are required independently: the replay guard is
needed even with the `drop_table` fix, because the `st_event_table`
delete replays after the `st_column` deletes (table id 17 vs. 2), and
also because commitlogs already written by unfixed versions contain drop
transactions with no `st_event_table` delete at all. Databases which
already dropped an event table on an unfixed version keep their orphaned
row; cleaning those up retroactively is left for a follow-up (e.g. a
fixup in `rebuild_state_after_replay`, like
`fixup_delete_duplicate_system_sequence_rows`).

# API and ABI breaking changes

None.

# Expected complexity level and risk

1. A guard on an existing replay invariant, plus tests.

# Testing

- [x] New unit regression tests `replay_event_table_drop_no_snapshot`
and `replay_event_table_drop_after_snapshot` in
`crates/core/src/db/update.rs`, following the structure of the #5269
replay tests (create event table, write an event row, drop the table via
`RemoveTable` automigration, reopen to force replay). Verified both fail
with the production error signature before the fix and pass after:

  ```
  ---- db::update::test::replay_event_table_drop_no_snapshot stdout ----
Error: DatastoreError: Error deleting row ProductValue { elements:
[U32(4096), U16(0), String("payload"), Array([13])] } from table
"st_column" during transaction 3 playback
  ...
      1: TableError: Table with ID `4096` not found in `st_table`.
  ```

- [x] The pre-existing #5269 replay tests
(`replay_event_table_schema_change_*`) still pass.
- [x] New smoketest
`automigrate_drop_event_table_replays_after_restart`: publishes a module
with an event table, emits an event, drops the table via automigration,
restarts the server, and verifies the database replays and serves reads
and writes. Passes locally.
- [x] Reproduced the production failure on a stock 2.5.0 standalone
(publish module with event table, republish without it, restart,
identical error), then opened the same bricked data directory with a
standalone built from this branch and verified the database replays and
serves queries with all data intact.
2026-06-12 12:18:26 +00:00
joshua-spacetime 9af04b4b3f Fail if spacetime subscribe -n N doesn't receive exactly N updates (#5278)
# Description of Changes

Previously, if the server closed the connection, it was not considered
an error. The reason for this was because `-n` did not always mean the
connection should receive **exactly** `n` updates. Sometimes it meant
that the connection should receive **at most** `n` updates. This was the
case for client disconnecting auto-migration tests.

However, as a consequence, if the server were to close the connection
for some other reason - let's say it crashed before broadcasting all `n`
updates - the cli would not report this as an error. If this happened
during a smoketest, it would fail on some later assertion, but it
wouldn't be immediately obvious why.

`spacetime subscribe -n N` now fails if the websocket closes before it
receives `N` transaction updates. `subscribe_background(..., n)` also
fails if the CLI exits successfully but produced fewer or more than `n`
JSON update lines, where previously it did not.

This change, makes it very clear when this happens that the connection
to the server was closed before the test received its expected number of
updates.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

The purpose of this change is to provide more diagnostic info for
smoketest failures.

---------

Signed-off-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-11 21:32:51 +00:00
joshua-spacetime 5d1b1360e3 Unify index key representation in query plan (#5275)
# Description of Changes

Refactors index probes so that multi-column index keys are represented
as a single product value expression `PhysicalExpr::Product` instead of
being split across various fields and structs. As a result, this patch
also simplifies the index-scan and index-join query executor variants
now that index scans/probes share one physical shape.

This change is in preparation for adding formal parameters to query
plans. Since index probe values now have single unified representation
as a `PhysicalExpr`, a future parameterized plan can represent an index
scan or index join as follows:

```rust
IndexProbe::Point(PhysicalExpr::Product(vec![
    PhysicalExpr::Param(sender_slot),
    PhysicalExpr::Value(other_const),
]))

PhysicalExpr::Product(vec![
    PhysicalExpr::Param(sender_slot),
    PhysicalExpr::Field(lhs_join_field),
])
```

This will avoid having to duplicate parameter handling in a bunch of
different places or rules.

Note, a very nice consequence of this refactor is that it
removes/consolidates a significant amount of code as the diff shows.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

...

# Testing

Existing coverage
2026-06-11 19:06:53 +00:00
joshua-spacetime 945b2556a5 Timestamps can be primary keys in C# (#5262)
# Description of Changes

Makes C# consistent with the other module languages.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

Unit test
2026-06-11 17:22:30 +00:00
clockwork-labs-bot 0783d7a7cc Document schedule table lifecycle (#5265)
## Summary

- document schedule row lifecycle differences for scheduled reducers,
scheduled procedures, and interval schedules
- clarify that scheduled functions should read row data from the
argument they receive
- document the scheduler's in-memory queue behavior when a schedule row
is deleted before its queued entry fires

Fixes #5252

## Testing

- `pnpm build` from `docs/`

Note: docs build completed successfully. It emitted the existing
`docusaurus-plugin-llms-txt` warning for `/docs/ask-ai/ask-ai` being
skipped during HTML-to-Markdown conversion.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-11 16:40:35 +00:00
joshua-spacetime fd1447d1d3 Catch unwinding panics in the scheduler (#5280)
# Description of Changes

This fixes a scheduler crash where a panic from a scheduled JS
reducer/procedure could unwind out of `SchedulerActor::handle_queued`.

The fix keeps the existing panic semantics through `ModuleHost`, so
`defer_on_unwind` still runs and poisons the failed module host, but the
scheduler now catches the unwind after that boundary, logs a warning,
and returns without rescheduling that queue item.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

...
2026-06-11 15:36:21 +00:00
Julien Lavocat 20e165b39a Fix broken links in auth docs (#4742)
# Description of Changes

Fix a broken link

# API and ABI breaking changes

None

# Expected complexity level and risk

Between 0.001 and 0.01

# Testing

- [x] Rendered locally
2026-06-11 15:35:58 +00:00