From 545bb7c31ac40fe453789b8cf634248bcdadd9e0 Mon Sep 17 00:00:00 2001 From: joshua-spacetime Date: Fri, 23 Jan 2026 14:32:04 -0800 Subject: [PATCH 1/8] [2.0 Breaking]: Remove sender field from [Reducer|View|Procedure]Context (#4101) # Description of Changes Makes the `sender` field on `ViewContext` private and exposes a `sender()` method. Does the same for `ReducerContext` and `ProcedureContext`. The purpose of this change: So that the host can determine if/when a view invokes or reads the `sender`. Currently, because `sender` is a field, the host assumes that it is always read. This means views must be materialized per client, even if the view doesn't actually depend on `sender`, resulting in data duplication. The initial solution for this problem was `AnonymousViewContext` which doesn't have a `sender` field. The better solution is to make `sender` a method so that it can call into the host and record when it's actually invoked. Note, this patch only updates the module API, so the current implementation does not change. `ViewContext` views are still duplicated across clients. Changing this requires a new host syscall and for `sender()` to invoke that syscall. This however is backwards compatible and can be done anytime after the module APIs for the other languages (C#, TypeScript, C++) are updated. Also note that `ReducerContext` and `ProcedureContext` were updated purely for consistency. There are currently no plans to track reads of `sender` in these contexts. # API and ABI breaking changes Breaks the rust module api. # Expected complexity level and risk 1 # Testing N/A --- .../test-react-router-app/server/src/lib.rs | 12 +- crates/bindings/README.md | 2 +- crates/bindings/src/lib.rs | 30 +- demo/Blackholio/server-rust/src/lib.rs | 28 +- .../00400-key-architecture.md | 2 +- .../00300-tutorials/00100-chat-app.md | 12 +- .../00300-unity-tutorial/00300-part-2.md | 4 +- .../00300-unity-tutorial/00400-part-3.md | 8 +- .../00300-unity-tutorial/00500-part-4.md | 4 +- .../00400-unreal-tutorial/00300-part-2.md | 4 +- .../00400-unreal-tutorial/00400-part-3.md | 14 +- .../00400-unreal-tutorial/00500-part-4.md | 4 +- .../00100-databases/00500-cheat-sheet.md | 4 +- .../00300-incremental-migrations.md | 16 +- .../00300-reducers/00400-reducer-context.md | 4 +- .../00300-reducers/00500-lifecycle.md | 8 +- .../00200-functions/00500-views.md | 12 +- docs/docs/00200-core-concepts/00300-tables.md | 2 +- .../00300-tables/00210-file-storage.md | 2 +- .../00300-tables/00400-access-permissions.md | 10 +- .../00100-how-to/00300-logging.md | 4 +- docs/llms/docs-benchmark-analysis.md | 599 +++--- docs/llms/docs-benchmark-comment.md | 12 +- docs/llms/docs-benchmark-details.json | 1652 ++++++++--------- docs/llms/docs-benchmark-summary.json | 52 +- modules/module-test/src/lib.rs | 6 +- .../sdk-test-connect-disconnect/src/lib.rs | 4 +- modules/sdk-test-view/src/lib.rs | 10 +- modules/sdk-test/src/lib.rs | 10 +- smoketests/tests/rls.py | 4 +- smoketests/tests/views.py | 4 +- smoketests/tests/zz_docker.py | 4 +- .../chat-console-rs/spacetimedb/src/lib.rs | 16 +- 33 files changed, 1339 insertions(+), 1220 deletions(-) diff --git a/crates/bindings-typescript/test-react-router-app/server/src/lib.rs b/crates/bindings-typescript/test-react-router-app/server/src/lib.rs index 520e68eeaec..496acfd090f 100644 --- a/crates/bindings-typescript/test-react-router-app/server/src/lib.rs +++ b/crates/bindings-typescript/test-react-router-app/server/src/lib.rs @@ -22,23 +22,23 @@ fn init(ctx: &ReducerContext) { #[reducer(client_connected)] fn client_connected(ctx: &ReducerContext) { - let existing_user = ctx.db.offline_user().identity().find(ctx.sender); + let existing_user = ctx.db.offline_user().identity().find(ctx.sender()); if let Some(user) = existing_user { ctx.db.user().insert(user); - ctx.db.offline_user().identity().delete(ctx.sender); + ctx.db.offline_user().identity().delete(ctx.sender()); return; } ctx.db.offline_user().insert(User { - identity: ctx.sender, + identity: ctx.sender(), has_incremented_count: 0, }); } #[reducer(client_disconnected)] fn client_disconnected(ctx: &ReducerContext) -> Result<(), String> { - let existing_user = ctx.db.user().identity().find(ctx.sender).ok_or("User not found")?; + let existing_user = ctx.db.user().identity().find(ctx.sender()).ok_or("User not found")?; ctx.db.offline_user().insert(existing_user); - ctx.db.user().identity().delete(ctx.sender); + ctx.db.user().identity().delete(ctx.sender()); Ok(()) } @@ -48,7 +48,7 @@ fn increment_counter(ctx: &ReducerContext) -> Result<(), String> { counter.count += 1; ctx.db.counter().id().update(counter); - let mut user = ctx.db.user().identity().find(ctx.sender).ok_or("User not found")?; + let mut user = ctx.db.user().identity().find(ctx.sender()).ok_or("User not found")?; user.has_incremented_count += 1; ctx.db.user().identity().update(user); diff --git a/crates/bindings/README.md b/crates/bindings/README.md index a02a8ff0328..6374d9f79e9 100644 --- a/crates/bindings/README.md +++ b/crates/bindings/README.md @@ -608,7 +608,7 @@ struct PlayerAndLevel { // At-most-one row: return Option #[view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } // Multiple rows: return Vec diff --git a/crates/bindings/src/lib.rs b/crates/bindings/src/lib.rs index b8f59220776..ebe5f7075b3 100644 --- a/crates/bindings/src/lib.rs +++ b/crates/bindings/src/lib.rs @@ -662,7 +662,7 @@ pub use spacetimedb_bindings_macro::table; /// /// #[reducer] /// fn scheduled(ctx: &ReducerContext, args: ScheduledArgs) -> Result<(), String> { -/// if ctx.sender != ctx.identity() { +/// if ctx.sender() != ctx.identity() { /// return Err("Reducer `scheduled` may not be invoked by clients, only via scheduling.".into()); /// } /// // Reducer body... @@ -707,7 +707,7 @@ pub use spacetimedb_bindings_macro::reducer; /// #[procedure] /// fn return_value(ctx: &mut ProcedureContext, arg: MyArgument) -> MyReturnValue { /// MyReturnValue { -/// a: format!("Hello, {}", ctx.sender), +/// a: format!("Hello, {}", ctx.sender()), /// b: ctx.timestamp, /// } /// } @@ -816,13 +816,13 @@ pub use spacetimedb_bindings_macro::procedure; /// // A view that selects at most one row from a table /// #[view(name = my_player, public)] /// fn my_player(ctx: &ViewContext) -> Option { -/// ctx.db.player().identity().find(ctx.sender) +/// ctx.db.player().identity().find(ctx.sender()) /// } /// /// // An example of column projection /// #[view(name = my_player_id, public)] /// fn my_player_id(ctx: &ViewContext) -> Option { -/// ctx.db.player().identity().find(ctx.sender).map(|Player { id, .. }| PlayerId { id }) +/// ctx.db.player().identity().find(ctx.sender()).map(|Player { id, .. }| PlayerId { id }) /// } /// /// // An example that is analogous to a semijoin in sql @@ -894,7 +894,7 @@ impl Default for AnonymousViewContext { /// The other is [`AnonymousViewContext`]. /// Use this type if the view depends on the caller's identity. pub struct ViewContext { - pub sender: Identity, + sender: Identity, pub db: LocalReadOnly, pub from: QueryBuilder, } @@ -907,6 +907,11 @@ impl ViewContext { from: QueryBuilder {}, } } + + /// The `Identity` of the client that invoked the view. + pub fn sender(&self) -> Identity { + self.sender + } } /// The context that any reducer is provided with. @@ -924,7 +929,7 @@ impl ViewContext { #[non_exhaustive] pub struct ReducerContext { /// The `Identity` of the client that invoked the reducer. - pub sender: Identity, + sender: Identity, /// The time at which the reducer was started. pub timestamp: Timestamp, @@ -1014,6 +1019,11 @@ impl ReducerContext { } } + /// The `Identity` of the client that invoked the reducer. + pub fn sender(&self) -> Identity { + self.sender + } + /// Returns the authorization information for the caller of this reducer. pub fn sender_auth(&self) -> &AuthCtx { &self.sender_auth @@ -1124,7 +1134,7 @@ impl Deref for TxContext { #[cfg(feature = "unstable")] pub struct ProcedureContext { /// The `Identity` of the client that invoked the procedure. - pub sender: Identity, + sender: Identity, /// The time at which the procedure was started. pub timestamp: Timestamp, @@ -1162,6 +1172,12 @@ impl ProcedureContext { counter_uuid: Cell::new(0), } } + + /// The `Identity` of the client that invoked the procedure. + pub fn sender(&self) -> Identity { + self.sender + } + /// Read the current module's [`Identity`]. pub fn identity(&self) -> Identity { // Hypothetically, we *could* read the module identity out of the system tables. diff --git a/demo/Blackholio/server-rust/src/lib.rs b/demo/Blackholio/server-rust/src/lib.rs index 08a70a7a767..f12d554cf3f 100644 --- a/demo/Blackholio/server-rust/src/lib.rs +++ b/demo/Blackholio/server-rust/src/lib.rs @@ -143,7 +143,7 @@ pub fn init(ctx: &ReducerContext) -> Result<(), String> { #[spacetimedb::reducer(client_connected)] pub fn connect(ctx: &ReducerContext) -> Result<(), String> { - if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender) { + if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender()) { ctx.db.player().insert(player.clone()); ctx.db.logged_out_player().identity().delete(&player.identity); @@ -157,7 +157,7 @@ pub fn connect(ctx: &ReducerContext) -> Result<(), String> { } } else { ctx.db.player().try_insert(Player { - identity: ctx.sender, + identity: ctx.sender(), player_id: 0, name: String::new(), })?; @@ -167,10 +167,15 @@ pub fn connect(ctx: &ReducerContext) -> Result<(), String> { #[spacetimedb::reducer(client_disconnected)] pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> { - let player = ctx.db.player().identity().find(&ctx.sender).ok_or("Player not found")?; + let player = ctx + .db + .player() + .identity() + .find(&ctx.sender()) + .ok_or("Player not found")?; let player_id = player.player_id; ctx.db.logged_out_player().insert(player); - ctx.db.player().identity().delete(&ctx.sender); + ctx.db.player().identity().delete(&ctx.sender()); // Move any circles from the arena into logged out tables for circle in ctx.db.circle().player_id().filter(&player_id) { @@ -187,7 +192,7 @@ pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> { #[spacetimedb::reducer] pub fn enter_game(ctx: &ReducerContext, name: String) -> Result<(), String> { log::info!("Creating player with name {}", name); - let mut player: Player = ctx.db.player().identity().find(ctx.sender).ok_or("")?; + let mut player: Player = ctx.db.player().identity().find(ctx.sender()).ok_or("")?; let player_id = player.player_id; player.name = name; ctx.db.player().identity().update(player); @@ -234,7 +239,7 @@ pub fn respawn(ctx: &ReducerContext) -> Result<(), String> { .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("No such player found")?; spawn_player_initial_circle(ctx, player.player_id)?; @@ -248,7 +253,7 @@ pub fn suicide(ctx: &ReducerContext) -> Result<(), String> { .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("No such player found")?; for circle in ctx.db.circle().player_id().filter(&player.player_id) { @@ -260,7 +265,12 @@ pub fn suicide(ctx: &ReducerContext) -> Result<(), String> { #[spacetimedb::reducer] pub fn update_player_input(ctx: &ReducerContext, direction: DbVector2) -> Result<(), String> { - let player = ctx.db.player().identity().find(&ctx.sender).ok_or("Player not found")?; + let player = ctx + .db + .player() + .identity() + .find(&ctx.sender()) + .ok_or("Player not found")?; for mut circle in ctx.db.circle().player_id().filter(&player.player_id) { circle.direction = direction.normalized(); circle.speed = direction.magnitude().clamp(0.0, 1.0); @@ -467,7 +477,7 @@ pub fn player_split(ctx: &ReducerContext) -> Result<(), String> { .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("Sender has no player")?; let circles: Vec = ctx.db.circle().player_id().filter(&player.player_id).collect(); let mut circle_count = circles.len() as i32; diff --git a/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md b/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md index d4fa03561bd..63eff91f7b0 100644 --- a/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md +++ b/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md @@ -451,7 +451,7 @@ A view can be written in Rust like so: ```rust #[spacetimedb::view(name = my_player, public)] fn my_player(ctx: &spacetimedb::ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md b/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md index d1e6b2c3aae..06ef0c039ce 100644 --- a/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md +++ b/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md @@ -348,7 +348,7 @@ Add to `spacetimedb/src/lib.rs`: #[reducer] pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { let name = validate_name(name)?; - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender()) { ctx.db.user().identity().update(User { name: Some(name), ..user }); Ok(()) } else { @@ -439,7 +439,7 @@ pub fn send_message(ctx: &ReducerContext, text: String) -> Result<(), String> { let text = validate_message(text)?; log::info!("{}", text); ctx.db.message().insert(Message { - sender: ctx.sender, + sender: ctx.sender(), text, sent: ctx.timestamp, }); @@ -547,12 +547,12 @@ Add to `spacetimedb/src/lib.rs`: ```rust server #[reducer(client_connected)] pub fn client_connected(ctx: &ReducerContext) { - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender()) { ctx.db.user().identity().update(User { online: true, ..user }); } else { ctx.db.user().insert(User { name: None, - identity: ctx.sender, + identity: ctx.sender(), online: true, }); } @@ -560,10 +560,10 @@ pub fn client_connected(ctx: &ReducerContext) { #[reducer(client_disconnected)] pub fn identity_disconnected(ctx: &ReducerContext) { - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender()) { ctx.db.user().identity().update(User { online: false, ..user }); } else { - log::warn!("Disconnect event for unknown user with identity {:?}", ctx.sender); + log::warn!("Disconnect event for unknown user with identity {:?}", ctx.sender()); } } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md index 03c579a088a..b6766e12672 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md @@ -345,7 +345,7 @@ public static void Debug(ReducerContext ctx) ```rust #[spacetimedb::reducer] pub fn debug(ctx: &ReducerContext) -> Result<(), String> { - log::debug!("This reducer was called by {}.", ctx.sender); + log::debug!("This reducer was called by {}.", ctx.sender()); Ok(()) } ``` @@ -463,7 +463,7 @@ Next let's connect our client to our database. Let's start by modifying our `deb ```rust #[spacetimedb::reducer(client_connected)] pub fn connect(ctx: &ReducerContext) -> Result<(), String> { - log::debug!("{} just connected.", ctx.sender); + log::debug!("{} just connected.", ctx.sender()); Ok(()) } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md index a00681a6c49..ab95e71294d 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md @@ -391,7 +391,7 @@ Next, modify your `connect` reducer and add a new `disconnect` reducer below it: ```rust #[spacetimedb::reducer(client_connected)] pub fn connect(ctx: &ReducerContext) -> Result<(), String> { - if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender) { + if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender()) { ctx.db.player().insert(player.clone()); ctx.db .logged_out_player() @@ -399,7 +399,7 @@ pub fn connect(ctx: &ReducerContext) -> Result<(), String> { .delete(&player.identity); } else { ctx.db.player().try_insert(Player { - identity: ctx.sender, + identity: ctx.sender(), player_id: 0, name: String::new(), })?; @@ -413,11 +413,11 @@ pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> { .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("Player not found")?; let player_id = player.player_id; ctx.db.logged_out_player().insert(player); - ctx.db.player().identity().delete(&ctx.sender); + ctx.db.player().identity().delete(&ctx.sender()); Ok(()) } diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md index d00bd48fcf9..647efe78bcb 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md @@ -207,7 +207,7 @@ pub fn update_player_input(ctx: &ReducerContext, direction: DbVector2) -> Result .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("Player not found")?; for mut circle in ctx.db.circle().player_id().filter(&player.player_id) { circle.direction = direction.normalized(); @@ -218,7 +218,7 @@ pub fn update_player_input(ctx: &ReducerContext, direction: DbVector2) -> Result } ``` -This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.sender` value is not set by the client. Instead `ctx.sender` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. +This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.sender()` value is not set by the client. Instead `ctx.sender()` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md index 0502ab9f87f..bde4659ba26 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md @@ -343,7 +343,7 @@ public static void Debug(ReducerContext ctx) ```rust #[spacetimedb::reducer] pub fn debug(ctx: &ReducerContext) -> Result<(), String> { - log::debug!("This reducer was called by {}.", ctx.sender); + log::debug!("This reducer was called by {}.", ctx.sender()); Ok(()) } ``` @@ -459,7 +459,7 @@ Next let's connect our client to our database. Let's start by modifying our `deb ```rust #[spacetimedb::reducer(client_connected)] pub fn connect(ctx: &ReducerContext) -> Result<(), String> { - log::debug!("{} just connected.", ctx.sender); + log::debug!("{} just connected.", ctx.sender()); Ok(()) } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md index 859ab5157e9..192c7d3ebc8 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md @@ -384,7 +384,7 @@ Next, modify your `connect` reducer and add a new `disconnect` reducer below it: ```rust #[spacetimedb::reducer(client_connected)] pub fn connect(ctx: &ReducerContext) -> Result<(), String> { - if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender) { + if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender()) { ctx.db.player().insert(player.clone()); ctx.db .logged_out_player() @@ -392,7 +392,7 @@ pub fn connect(ctx: &ReducerContext) -> Result<(), String> { .delete(&player.identity); } else { ctx.db.player().try_insert(Player { - identity: ctx.sender, + identity: ctx.sender(), player_id: 0, name: String::new(), })?; @@ -406,11 +406,11 @@ pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> { .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("Player not found")?; let player_id = player.player_id; ctx.db.logged_out_player().insert(player); - ctx.db.player().identity().delete(&ctx.sender); + ctx.db.player().identity().delete(&ctx.sender()); Ok(()) } @@ -499,7 +499,7 @@ const START_PLAYER_MASS: i32 = 15; #[spacetimedb::reducer] pub fn enter_game(ctx: &ReducerContext, name: String) -> Result<(), String> { log::info!("Creating player with name {}", name); - let mut player: Player = ctx.db.player().identity().find(ctx.sender).ok_or("")?; + let mut player: Player = ctx.db.player().identity().find(ctx.sender()).ok_or("")?; let player_id = player.player_id; player.name = name; ctx.db.player().identity().update(player); @@ -589,11 +589,11 @@ pub fn disconnect(ctx: &ReducerContext) -> Result<(), String> { .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("Player not found")?; let player_id = player.player_id; ctx.db.logged_out_player().insert(player); - ctx.db.player().identity().delete(&ctx.sender); + ctx.db.player().identity().delete(&ctx.sender()); // Remove any circles from the arena for circle in ctx.db.circle().player_id().filter(&player_id) { diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md index 643256545c2..ae8eb620633 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md @@ -207,7 +207,7 @@ pub fn update_player_input(ctx: &ReducerContext, direction: DbVector2) -> Result .db .player() .identity() - .find(&ctx.sender) + .find(&ctx.sender()) .ok_or("Player not found")?; for mut circle in ctx.db.circle().player_id().filter(&player.player_id) { circle.direction = direction.normalized(); @@ -218,7 +218,7 @@ pub fn update_player_input(ctx: &ReducerContext, direction: DbVector2) -> Result } ``` -This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.sender` value is not set by the client. Instead `ctx.sender` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. +This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.sender()` value is not set by the client. Instead `ctx.sender()` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. diff --git a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md index 529e79d6ec4..e4754aca0e8 100644 --- a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md +++ b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md @@ -477,7 +477,7 @@ use spacetimedb::{view, ViewContext}; // Return single row #[view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } // Return multiple rows @@ -522,7 +522,7 @@ ctx.Rng // Random number generator ```rust ctx.db // Database access -ctx.sender // Identity of caller +ctx.sender() // Identity of caller ctx.connection_id // Option ctx.timestamp // Timestamp ctx.identity() // Module's identity diff --git a/docs/docs/00200-core-concepts/00100-databases/00500-migrations/00300-incremental-migrations.md b/docs/docs/00200-core-concepts/00100-databases/00500-migrations/00300-incremental-migrations.md index e8a2bcdd63c..692df88e501 100644 --- a/docs/docs/00200-core-concepts/00100-databases/00500-migrations/00300-incremental-migrations.md +++ b/docs/docs/00200-core-concepts/00100-databases/00500-migrations/00300-incremental-migrations.md @@ -46,7 +46,7 @@ fn create_character(ctx: &ReducerContext, class: Class, nickname: String) { "Creating new level 1 {class:?} named {nickname}", ); ctx.db.character().insert(Character { - player_id: ctx.sender, + player_id: ctx.sender(), nickname, level: 1, class, @@ -57,7 +57,7 @@ fn find_character_for_player(ctx: &ReducerContext) -> Character { ctx.db .character() .player_id() - .find(ctx.sender) + .find(ctx.sender()) .expect("Player has not created a character") } @@ -154,7 +154,7 @@ fn choose_alliance(ctx: &ReducerContext, alliance: Alliance) { "Setting {}'s alliance to {:?} for player {}", character.nickname, alliance, - ctx.sender, + ctx.sender(), ); update_character( ctx, @@ -194,18 +194,18 @@ When a new player creates a character, we'll make rows in both tables for them. fn create_character(ctx: &ReducerContext, class: Class, nickname: String) { log::info!( "Creating new level 1 {class:?} named {nickname} for player {}", - ctx.sender, + ctx.sender(), ); ctx.db.character().insert(Character { - player_id: ctx.sender, + player_id: ctx.sender(), nickname: nickname.clone(), level: 1, class, }); ctx.db.character_v2().insert(CharacterV2 { - player_id: ctx.sender, + player_id: ctx.sender(), nickname, level: 1, class, @@ -218,7 +218,7 @@ We'll update our helper functions so that they operate on `character_v2` rows. I ```rust fn find_character_for_player(ctx: &ReducerContext) -> CharacterV2 { - if let Some(character) = ctx.db.character_v2().player_id().find(ctx.sender) { + if let Some(character) = ctx.db.character_v2().player_id().find(ctx.sender()) { // Already migrated; just return the new player. return character; } @@ -228,7 +228,7 @@ fn find_character_for_player(ctx: &ReducerContext) -> CharacterV2 { .db .character() .player_id() - .find(ctx.sender) + .find(ctx.sender()) .expect("Player has not created a character"); ctx.db.character_v2().insert(CharacterV2 { diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md index 32b96e5ed33..38f447125d4 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md @@ -174,7 +174,7 @@ pub struct Player { #[reducer] fn update_score(ctx: &ReducerContext, new_score: u32) { // Get the caller's identity - let caller = ctx.sender; + let caller = ctx.sender(); // Find and update their player record if let Some(mut player) = ctx.db.player().identity().find(caller) { @@ -290,7 +290,7 @@ pub struct ScheduledTask { #[reducer] fn send_reminder(ctx: &ReducerContext, task: ScheduledTask) { // Only allow the scheduler (module identity) to call this - if ctx.sender != ctx.identity() { + if ctx.sender() != ctx.identity() { panic!("This reducer can only be called by the scheduler"); } diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md index 975f589b437..20f43bc8394 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md @@ -131,7 +131,7 @@ public static void OnConnect(ReducerContext ctx) ```rust #[reducer(client_connected)] pub fn on_connect(ctx: &ReducerContext) -> Result<(), String> { - log::info!("Client connected: {}", ctx.sender); + log::info!("Client connected: {}", ctx.sender()); // ctx.connection_id is guaranteed to be Some(...) let conn_id = ctx.connection_id.unwrap(); @@ -139,7 +139,7 @@ pub fn on_connect(ctx: &ReducerContext) -> Result<(), String> { // Initialize client session ctx.db.sessions().try_insert(Session { connection_id: conn_id, - identity: ctx.sender, + identity: ctx.sender(), connected_at: ctx.timestamp, })?; @@ -198,7 +198,7 @@ public static void OnDisconnect(ReducerContext ctx) ```rust #[reducer(client_disconnected)] pub fn on_disconnect(ctx: &ReducerContext) -> Result<(), String> { - log::info!("Client disconnected: {}", ctx.sender); + log::info!("Client disconnected: {}", ctx.sender()); // ctx.connection_id is guaranteed to be Some(...) let conn_id = ctx.connection_id.unwrap(); @@ -230,6 +230,6 @@ Reducers can be triggered at specific times using schedule tables. See [Schedule :::info Scheduled Reducer Context Scheduled reducer calls originate from SpacetimeDB itself, not from a client. Therefore: -- `ctx.sender` will be the module's own identity +- `ctx.sender()` will be the module's own identity - `ctx.connection_id` will be `None`/`null`/`undefined` ::: diff --git a/docs/docs/00200-core-concepts/00200-functions/00500-views.md b/docs/docs/00200-core-concepts/00200-functions/00500-views.md index 97ec7e2077f..0603fa97dad 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00500-views.md +++ b/docs/docs/00200-core-concepts/00200-functions/00500-views.md @@ -55,7 +55,7 @@ spacetimedb.view( { name: 'my_player', public: true }, t.option(players.rowType), (ctx) => { - const row = ctx.db.players.identity.find(ctx.sender); + const row = ctx.db.players.identity.find(ctx.sender()); return row ?? undefined; } ); @@ -197,7 +197,7 @@ pub struct PlayerAndLevel { // At-most-one row: return Option #[view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } // Multiple rows: return Vec @@ -232,7 +232,7 @@ Views can return either `Option` for at-most-one row or `Vec` for multiple Views use one of two context types: -- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.sender`. Use this when the view depends on who is querying it. +- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.sender()`. Use this when the view depends on who is querying it. - **`AnonymousViewContext`**: Does not provide caller information. Use this when the view produces the same results regardless of who queries it. Both contexts provide read-only access to tables and indexes through `ctx.db`. @@ -243,7 +243,7 @@ The choice between `ViewContext` and `AnonymousViewContext` has significant perf **Anonymous views can be shared across all subscribers.** When a view uses `AnonymousViewContext`, SpacetimeDB knows the result is the same for every client. The database can materialize the view once and serve that same result to all subscribers. When the underlying data changes, it recomputes the view once and broadcasts the update to everyone. -**Per-user views require separate computation for each subscriber.** When a view uses `ViewContext`, the result depends on `ctx.sender`, so each client potentially sees different data. SpacetimeDB must compute and track the view separately for each subscriber. With 1,000 connected users, that's 1,000 separate view computations and 1,000 separate sets of change tracking. +**Per-user views require separate computation for each subscriber.** When a view uses `ViewContext` and invokes `ctx.sender()`, each client potentially sees different data. SpacetimeDB must compute and track the view separately for each subscriber. With 1,000 connected users, that's 1,000 separate view computations and 1,000 separate sets of change tracking. **Prefer `AnonymousViewContext` when possible.** Design your views to be caller-independent when the use case allows. For example: @@ -294,7 +294,7 @@ public static Player? MyPlayer(ViewContext ctx) // Per-user: each client sees their own player #[view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(&ctx.sender) + ctx.db.player().identity().find(&ctx.sender()) } ``` @@ -541,7 +541,7 @@ fn entities_in_origin_chunk(ctx: &AnonymousViewContext) -> Vec { // Per-user: returns entities in the chunk the player is currently in #[view(name = entities_in_my_chunk, public)] fn entities_in_my_chunk(ctx: &ViewContext) -> Vec { - let Some(player) = ctx.db.player().identity().find(&ctx.sender) else { + let Some(player) = ctx.db.player().identity().find(&ctx.sender()) else { return vec![]; }; let Some(chunk) = ctx.db.player_chunk().player_id().find(&player.id) else { diff --git a/docs/docs/00200-core-concepts/00300-tables.md b/docs/docs/00200-core-concepts/00300-tables.md index 763bbcd8df7..cf3727b18d8 100644 --- a/docs/docs/00200-core-concepts/00300-tables.md +++ b/docs/docs/00200-core-concepts/00300-tables.md @@ -382,7 +382,7 @@ ctx.db.player().insert(Player { /* ... */ }); ctx.db.logged_out_player().insert(Player { /* ... */ }); // Move a row between tables -if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender) { +if let Some(player) = ctx.db.logged_out_player().identity().find(&ctx.sender()) { ctx.db.player().insert(player.clone()); ctx.db.logged_out_player().identity().delete(&player.identity); } diff --git a/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md b/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md index 5e0f51551b4..33e617c542a 100644 --- a/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md +++ b/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md @@ -263,7 +263,7 @@ pub fn register_document( ) { ctx.db.document().insert(Document { id: 0, // auto-increment - owner_id: ctx.sender, + owner_id: ctx.sender(), filename, mime_type, size_bytes, diff --git a/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md b/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md index 08cb9ed04f1..0f3c83978ed 100644 --- a/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md +++ b/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md @@ -330,7 +330,7 @@ Views can only access table data through indexed lookups, not by scanning all ro ### Filtering Rows by Caller -Use views with `ViewContext` to return only the rows that belong to the caller. The view accesses the caller's identity through `ctx.sender` and uses it to look up rows via an index. +Use views with `ViewContext` to return only the rows that belong to the caller. The view accesses the caller's identity through `ctx.sender()` and uses it to look up rows via an index. @@ -426,8 +426,8 @@ pub struct Message { #[spacetimedb::view(name = my_messages, public)] fn my_messages(ctx: &ViewContext) -> Vec { // Look up messages by index where caller is sender or recipient - let sent: Vec<_> = ctx.db.message().sender().filter(&ctx.sender).collect(); - let received: Vec<_> = ctx.db.message().recipient().filter(&ctx.sender).collect(); + let sent: Vec<_> = ctx.db.message().sender().filter(&ctx.sender()).collect(); + let received: Vec<_> = ctx.db.message().recipient().filter(&ctx.sender()).collect(); sent.into_iter().chain(received).collect() } ``` @@ -574,7 +574,7 @@ pub struct PublicUserProfile { #[spacetimedb::view(name = my_profile, public)] fn my_profile(ctx: &ViewContext) -> Option { // Look up the caller's account by their identity (unique index) - let user = ctx.db.user_account().identity().find(&ctx.sender)?; + let user = ctx.db.user_account().identity().find(&ctx.sender())?; Some(PublicUserProfile { id: user.id, username: user.username, @@ -726,7 +726,7 @@ pub struct Colleague { #[spacetimedb::view(name = my_colleagues, public)] fn my_colleagues(ctx: &ViewContext) -> Vec { // Find the caller's employee record by identity (unique index) - let Some(me) = ctx.db.employee().identity().find(&ctx.sender) else { + let Some(me) = ctx.db.employee().identity().find(&ctx.sender()) else { return vec![]; }; diff --git a/docs/docs/00300-resources/00100-how-to/00300-logging.md b/docs/docs/00300-resources/00100-how-to/00300-logging.md index 83dd011566f..1958b01634e 100644 --- a/docs/docs/00300-resources/00100-how-to/00300-logging.md +++ b/docs/docs/00300-resources/00100-how-to/00300-logging.md @@ -102,7 +102,7 @@ pub fn process_data(ctx: &ReducerContext, value: u32) -> Result<(), String> { return Err("Value cannot be zero".to_string()); } - log::debug!("Debug information: ctx.sender = {:?}", ctx.sender); + log::debug!("Debug information: ctx.sender = {:?}", ctx.sender()); Ok(()) } @@ -220,7 +220,7 @@ use spacetimedb::log; pub fn transfer_credits(ctx: &ReducerContext, to_user: u64, amount: u32) -> Result<(), String> { log::info!( "Credit transfer: from={:?}, to={}, amount={}", - ctx.sender, + ctx.sender(), to_user, amount ); diff --git a/docs/llms/docs-benchmark-analysis.md b/docs/llms/docs-benchmark-analysis.md index faa301f26fc..fe284ef576a 100644 --- a/docs/llms/docs-benchmark-analysis.md +++ b/docs/llms/docs-benchmark-analysis.md @@ -4,247 +4,394 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do ## Summary -- **Total failures analyzed**: 33 +- **Total failures analyzed**: 31 --- -## Analysis of SpacetimeDB Benchmark Test Failures - -### Rust / rustdoc_json Failures - -#### Compile/Publish Errors (2 Failures) - -##### Failure Group 1: `t_002_scheduled_table` and `t_017_scheduled_columns` -1. **The generated code**: - ```rust - use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt}; - - #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))] - pub struct TickTimer { - #[primary_key] - #[auto_inc] - scheduled_id: u64, - scheduled_at: ScheduleAt, - } - - #[reducer(init)] - pub fn init(ctx: &ReducerContext) { - if ctx.db.tick_timer().count() == 0 { - ctx.db.tick_timer().insert(TickTimer { - scheduled_id: 0, - scheduled_at: ScheduleAt::RepeatMicros(50_000), - }); - } - } - - #[reducer] - pub fn tick(_ctx: &ReducerContext, _row: TickTimer) { - } - ``` - -2. **The golden example**: - ```rust - use spacetimedb::{reducer, table, ReducerContext, ScheduleAt, Table}; - use std::time::Duration; - - #[table(name = tick_timer, scheduled(tick))] - pub struct TickTimer { - #[primary_key] - #[auto_inc] - pub scheduled_id: u64, - pub scheduled_at: ScheduleAt, - } - - #[reducer] - pub fn tick(_ctx: &ReducerContext, _schedule: TickTimer) { - } - - #[reducer(init)] - pub fn init(ctx: &ReducerContext) { - let every_50ms: ScheduleAt = Duration::from_millis(50).into(); - ctx.db.tick_timer().insert(TickTimer { - scheduled_id: 0, - scheduled_at: every_50ms, - }); - } - ``` - -3. **The error**: - - `publish_error: spacetime publish failed (exit=1)` - -4. **Explain the difference**: - - The generated code used `ScheduleAt::RepeatMicros(50_000)` instead of the correct `ScheduleAt::Interval(Duration::from_millis(50).into())`. The way the scheduling was set up was incorrect. - -5. **Root cause**: - - The documentation does not clearly specify the constructor syntax for `ScheduleAt` nor how to correctly set up the scheduled tasks in this context. - -6. **Recommendation**: - - Update documentation to provide examples of different constructors for `ScheduleAt`, specifically emphasizing how to define intervals correctly. +# Analysis of SpacetimeDB Benchmark Test Failures + +## Rust / rustdoc_json Failures + +### Compile/Publish Errors (3 Failures) + +#### 1. **t_002_scheduled_table** +- **Generated Code**: + ```rust + #[table(name = tick_timer, schedule(column = scheduled_at, reducer = tick))] + pub struct TickTimer { + #[primary_key] + #[auto_inc] + scheduled_id: u64, + scheduled_at: ScheduleAt, + } + ``` + +- **Golden Example**: + ```rust + #[table(name = tick_timer, scheduled(tick))] + pub struct TickTimer { + #[primary_key] + #[auto_inc] + pub scheduled_id: u64, + pub scheduled_at: ScheduleAt, + } + ``` + +- **Error**: `publish_error: spacetime publish failed (exit=1)` + +- **Explanation**: + The LLM used incorrect syntax for the `scheduled` attribute. It should be `scheduled(tick)` instead of `schedule(column = scheduled_at, reducer = tick)`. + +- **Root Cause**: The documentation may not clearly explain the syntax for the `scheduled` attribute. + +- **Recommendation**: Update documentation to emphasize that the `scheduled` attribute must be structured as `scheduled(reducer_name)`. --- -#### Other Failures (5 failures) - -##### Failure Group 2: `t_013_spacetime_sum_type`, `t_015_product_type_columns`, `t_016_sum_type_columns`, `t_018_constraints`, `t_020_ecs` -1. **The generated code**: - ```rust - use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType}; - - #[derive(SpacetimeType)] - pub struct Rect { - width: i32, - height: i32, - } - - #[table(name = result)] - pub struct ResultRow { - #[primary_key] - id: i32, - value: Shape, - } - - #[reducer] - pub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) { - ctx.db.result().insert(ResultRow { - id, - value: Shape::Circle(radius), - }); - } - ``` - -2. **The golden example**: - ```rust - use spacetimedb::{reducer, table, ReducerContext, SpacetimeType, Table}; - - #[derive(SpacetimeType, Clone, Debug)] - pub struct Rect { - pub width: i32, - pub height: i32, - } - - #[table(name = result)] - pub struct ResultRow { - #[primary_key] - pub id: i32, - pub value: Shape, - } - - #[reducer] - pub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) { - ctx.db.result().insert(ResultRow { id, value: Shape::Circle(radius) }); - } - ``` - -3. **The error**: - - `spacetime sql failed: no such table: result` - - `spacetime sql failed: no such table: profile` - - `spacetime sql failed: no such table: drawings` - -4. **Explain the difference**: - - The generated code omits the `pub` visibility keyword for fields and structs, which prevents proper access by the macros that generate the expected database schema. Additionally, the enum `Shape` wasn't declared correctly in the generated code. - -5. **Root cause**: - - Lack of proper visibility (missing `pub`) for structs and enum fields was not clearly emphasized in the documentation, leading to access issues. - -6. **Recommendation**: - - Provide clear guidelines in the documentation regarding the necessity of using `pub` for struct and enum fields when working with SpacetimeDB components. Include example schemas with visibility marked. +#### 2. **t_003_struct_in_table** +- **Generated Code**: + ```rust + #[spacetimedb::table(name = entity)] + pub struct Entity { + #[primary_key] + id: i32, + pos: Position, + } + ``` + +- **Golden Example**: + ```rust + #[table(name = entity)] + pub struct Entity { + #[primary_key] + pub id: i32, + pub pos: Position, + } + ``` + +- **Error**: `publish_error: spacetime publish failed (exit=1)` + +- **Explanation**: + The LLM did not use `pub` for struct fields which is required for visibility in SpacetimeDB. + +- **Root Cause**: The visibility rules for struct fields in Rust may need clearer explanation in the documentation. + +- **Recommendation**: Include specific examples indicating that all fields in SpacetimeDB tables should be public. --- -### Rust / docs Failures (22 total) +#### 3. **t_017_scheduled_columns** +- **Generated Code**: + ```rust + #[reducer(init)] + pub fn init(ctx: &ReducerContext) { + if ctx.db.tick_timer().count() == 0 { + ctx.db.tick_timer().insert(TickTimer { + scheduled_id: 0, + scheduled_at: ScheduleAt::repeat_micros(50_000), + }); + } + } + ``` + +- **Golden Example**: + ```rust + #[reducer(init)] + pub fn init(ctx: &ReducerContext) { + let every_50ms: ScheduleAt = Duration::from_millis(50).into(); + ctx.db.tick_timer().insert(TickTimer { + scheduled_id: 0, + scheduled_at: every_50ms, + }); + } + ``` + +- **Error**: `publish_error: spacetime publish failed (exit=1)` + +- **Explanation**: The method for initializing `scheduled_at` is incorrect. Instead of using `repeat_micros()`, the code should convert a `Duration` to `ScheduleAt`. + +- **Root Cause**: Misunderstanding of the proper way to initialize scheduled columns could be reflected in lacking documentation details. + +- **Recommendation**: Clarify the documentation regarding initializing `ScheduleAt`, emphasizing conversion from `Duration`. + +--- + +### Other Failures (2 Failures) + +#### 4. **t_016_sum_type_columns** +- **Generated Code**: + ```rust + #[spacetimedb::table(name = drawing)] + pub struct Drawing { + #[primary_key] + id: i32, + a: Shape, + b: Shape, + } + ``` + +- **Golden Example**: + ```rust + #[table(name = drawing)] + pub struct Drawing { + #[primary_key] + pub id: i32, + pub a: Shape, + pub b: Shape, + } + ``` + +- **Error**: Errors regarding tables not found. -#### Timeout Issues (1 failure) +- **Explanation**: Missing the `pub` attribute on struct fields results in failure to compile. -1. **Failure Group**: `t_015_product_type_columns` - - **Expected**: Modify the query logic to ensure no unnecessary long-running operations exist. - - **Recommendation**: Provide timeout considerations in the documentation to ensure optimization options are explored to prevent long-running tasks. +- **Root Cause**: Lack of clarity on the use of visibility attributes (`pub`) in struct definitions. + +- **Recommendation**: Revise documentation to instruct that fields must be public to work within SpacetimeDB. + +--- + +#### 5. **t_020_ecs** +- **Generated Code**: + ```rust + #[spacetimedb::table(name = entity)] + pub struct Entity { + #[primary_key] + id: i32, + } + + #[spacetimedb::table(name = position)] + pub struct Position { + #[primary_key] + entity_id: i32, + x: i32, + y: i32, + } + ``` + +- **Golden Example**: + ```rust + #[table(name = entity)] + pub struct Entity { + #[primary_key] + pub id: i32, + } + + #[table(name = position)] + pub struct Position { + #[primary_key] + pub entity_id: i32, + pub x: i32, + pub y: i32, + } + ``` + +- **Error**: Errors regarding tables not found. + +- **Explanation**: Missing the `pub` attribute leads to the struct not being properly registered with SpacetimeDB. + +- **Root Cause**: Similar to previous errors, the need for public access to struct fields is unclear. + +- **Recommendation**: Ensure documentation explicitly states that public access is necessary for all fields in SpacetimeDB structs. + +--- + +## Rust / docs Failures (22 total) + +### Timeout Issues (8 Failures) + +- **Failures**: Various tasks timed out, indicating potential performance or configuration issues. + +- **Root Cause**: Specifics of timeout settings and performance optimization strategies should be more explicit in the documentation. + +- **Recommendation**: Include guidelines on optimizing performance for long-running tasks or emphasize best practices for structuring queries and data handling. + +--- + +### Other Failures (14 Failures) + +#### 6. **t_000_empty_reducers** +- **Generated Code**: + ```rust + #[spacetimedb::reducer] + pub fn empty_reducer_no_args(_ctx: &spacetimedb::ReducerContext) { + } + ``` + +- **Golden Example**: + ```rust + #[reducer] + pub fn empty_reducer_no_args(ctx: &ReducerContext) -> Result<(), String> { + Ok(()) + } + ``` + +- **Error**: Schema-related errors due to missing return type and proper handling. + +- **Explanation**: Missing return type (`Result<(), String>`) was not implemented. + +- **Root Cause**: The documentation may not explicitly mention that reducers should return results. + +- **Recommendation**: Adjust the documentation to specify that reducer functions must include appropriate return types. + +--- + +#### 7. **t_001_basic_tables** +- **Generated Code**: + ```rust + #[spacetimedb::table(name = user)] + pub struct User { + #[primary_key] + id: i32, + name: String, + age: i32, + active: bool, + } + ``` + +- **Golden Example**: + ```rust + #[table(name = user)] + pub struct User { + #[primary_key] + pub id: i32, + pub name: String, + pub age: i32, + pub active: bool, + } + ``` + +- **Error**: Schema-related errors due to missing `pub` modifiers. + +- **Explanation**: Missing public access modifiers on struct fields prevented expected behavior. + +- **Root Cause**: Visibility rules may not have been adequately covered in the documentation. + +- **Recommendation**: Ensure the documentation includes examples with visibility modifiers. --- ### C# / docs Failures (4 total) -#### C# Failure Group: `t_014_elementary_columns`, `t_016_sum_type_columns`, `t_017_scheduled_columns`, `t_020_ecs` -1. **The generated code**: - ```csharp - using SpacetimeDB; - - public static partial class Module - { - [SpacetimeDB.Table(Name = "Primitive", Public = true)] - public partial struct Primitive - { - [SpacetimeDB.PrimaryKey] - public int Id; - public int Count; - public long Total; - public float Price; - public double Ratio; - public bool Active; - public string Name; - } - - [SpacetimeDB.Reducer] - public static void Seed(ReducerContext ctx) - { - ctx.Db.Primitive.Insert(new Primitive - { - Id = 1, - Count = 2, - Total = 3000000000L, - Price = 1.5f, - Ratio = 2.25, - Active = true, - Name = "Alice" - }); - } - } - ``` - -2. **The golden example**: - ```csharp - using SpacetimeDB; - - public static partial class Module - { - [Table(Name = "Primitive")] - public partial struct Primitive - { - [PrimaryKey] public int Id; - public int Count; - public long Total; - public float Price; - public double Ratio; - public bool Active; - public string Name; - } - - [Reducer] - public static void Seed(ReducerContext ctx) - { - ctx.Db.Primitive.Insert(new Primitive { - Id = 1, - Count = 2, - Total = 3000000000, - Price = 1.5f, - Ratio = 2.25, - Active = true, - Name = "Alice" - }); - } - } - ``` - -3. **The error**: `no such table: primitive` - -4. **Explain the difference**: - - Missing the `public` access modifier in the declaration of the `Table` attribute. The expected syntax properly utilizes attributes defined in the library. - -5. **Root cause**: - - Documentation may lack clarity about access modifiers, especially when it comes to how they affect visibility in entities. - -6. **Recommendation**: - - Ensure C# documentation includes explicit examples where `public` is required in class and struct declarations to prevent access issues with tables. +#### Other Failures (4 Failures) ---- +#### 8. **t_014_elementary_columns** +- **Generated Code**: + ```csharp + [SpacetimeDB.Table(Name = "Primitive", Public = true)] + public partial struct Primitive + { + [SpacetimeDB.PrimaryKey] + public int Id; + public int Count; + ... + } + ``` + +- **Golden Example**: + ```csharp + [Table(Name = "Primitive")] + public partial struct Primitive + { + [PrimaryKey] public int Id; + public int Count; + ... + } + ``` + +- **Error**: Table not found during sql operations. + +- **Explanation**: The `Public` attribute's use was incorrect; it's not necessary in the struct definition. + +- **Root Cause**: Confusion over the purpose and necessity of attributes. + +- **Recommendation**: Update documentation to clarify attributes' roles in table definitions, removing unnecessary ones for struct exposure. + +--- + +#### 9. **t_016_sum_type_columns** +- **Generated Code**: + ```csharp + [SpacetimeDB.Table(Name = "Drawing", Public = true)] + public partial struct Drawing + { + [SpacetimeDB.PrimaryKey] + public int Id; + } + ``` + +- **Golden Example**: + ```csharp + [Table(Name = "Drawing")] + public partial struct Drawing + { + [PrimaryKey] public int Id; + } + ``` + +- **Error**: Table not found during sql operations. + +- **Explanation**: Similar to the previous failure, the `Public` attribute was misapplied. + +- **Root Cause**: Misalignment between understood attribute requirements and actual usage. + +- **Recommendation**: Further clarification of when and where to apply attributes in C# constructs related to SpacetimeDB. + +--- + +#### 10. **t_017_scheduled_columns** +- **Generated Code**: + ```csharp + [Table(Name = "TickTimer", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))] + public partial struct TickTimer + { + [PrimaryKey, AutoInc] + public ulong ScheduledId; + public ScheduleAt ScheduledAt; + } + ``` + +- **Golden Example**: + ```csharp + [Table(Name = "TickTimer", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))] + public partial struct TickTimer + { + [PrimaryKey, AutoInc] public ulong ScheduledId; + public ScheduleAt ScheduledAt; + } + ``` + +- **Error**: Table not found during sql operations. + +- **Explanation**: The field definitions and relationships were incorrectly configured. + +- **Root Cause**: Possible gaps in documentation regarding definitions of scheduled columns and expected real structures. + +- **Recommendation**: Revise documentation to ensure clear expectations about table configuration and proper struct setup. + +--- + +#### 11. **t_020_ecs** +- **Generated Code**: + ```csharp + [SpacetimeDB.Table(Name = "Entity", Public = true)] + public partial struct Entity { [SpacetimeDB.PrimaryKey] public int Id; } + ``` + +- **Golden Example**: + ```csharp + [Table(Name = "Entity")] + public partial struct Entity { [PrimaryKey] public int Id; } + ``` + +- **Error**: Errors related to missing tables. + +- **Explanation**: Public attributes were misused in creating struct definitions for the tables. + +- **Root Cause**: Attribute usage may be causing confusion in use cases. + +- **Recommendation**: Ensure documentation includes proper usage guidelines for attributes in defining entities. + +--- -By addressing the above gaps in documentation and ensuring that generated samples adhere to the expected outcomes, we can significantly reduce the number of failures in future benchmarks. +By addressing the aforementioned discrepancies and gaps in documentation, developers can improve their implementation of SpacetimeDB, leading to smoother integrations and reduced error rates during execution. diff --git a/docs/llms/docs-benchmark-comment.md b/docs/llms/docs-benchmark-comment.md index b26d4820585..37272389e0d 100644 --- a/docs/llms/docs-benchmark-comment.md +++ b/docs/llms/docs-benchmark-comment.md @@ -2,16 +2,16 @@ | Language | Mode | Category | Tests Passed | Task Pass % | |----------|------|----------|--------------|-------------| -| Rust | rustdoc_json | basics | 26/27 | 91.7% ⬆️ +8.3% | -| Rust | rustdoc_json | schema | 23/34 | 65.3% ⬆️ +10.0% | -| Rust | rustdoc_json | **total** | 49/61 | **79.7%** ⬆️ +9.1% | +| Rust | rustdoc_json | basics | 25/27 | 83.3% ⬆️ +9.0% | +| Rust | rustdoc_json | schema | 26/34 | 75.3% ⬆️ +10.0% | +| Rust | rustdoc_json | **total** | 51/61 | **79.7%** ⬆️ +9.5% | | Rust | docs | basics | 5/27 | 11.1% | -| Rust | docs | schema | 8/32 | 20.5% ⬆️ +8.0% | -| Rust | docs | **total** | 13/59 | **15.4%** ⬆️ +3.6% | +| Rust | docs | schema | 0/14 | 0.0% ⬇️ -20.5% | +| Rust | docs | **total** | 5/41 | **6.1%** ⬇️ -9.3% | | C# | docs | basics | 27/27 | 100.0% | | C# | docs | schema | 25/34 | 73.7% | | C# | docs | **total** | 52/61 | **88.0%** | _Compared against master branch baseline_ -Generated at: 2026-01-27T20:01:19.767Z +Generated at: 2026-01-23T20:21:59.670Z diff --git a/docs/llms/docs-benchmark-details.json b/docs/llms/docs-benchmark-details.json index 5d08c34e832..1a8a6449ec1 100644 --- a/docs/llms/docs-benchmark-details.json +++ b/docs/llms/docs-benchmark-details.json @@ -5,21 +5,21 @@ "modes": [ { "mode": "rustdoc_json", - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_000_empty_reducers", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &ReducerContext, count: i32) {\n let _ = count;\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &ReducerContext, name: String) {\n let _ = name;\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &ReducerContext, count: i32, name: String) {\n let _ = (count, name);\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &ReducerContext, active: bool, ratio: f32, label: String) {\n let _ = (active, ratio, label);\n}", + "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\nfn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_int(_ctx: &ReducerContext, _count: i32) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_string(_ctx: &ReducerContext, _name: String) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_two_args(_ctx: &ReducerContext, _count: i32, _name: String) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_three_args(_ctx: &ReducerContext, _active: bool, _ratio: f32, _label: String) {\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-000-empty-reducers-golden", @@ -35,18 +35,18 @@ "llm_db": "basics-t-000-empty-reducers-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:33.923590167Z", - "finished_at": "2026-01-27T19:51:02.622615452Z" + "started_at": "2026-01-23T20:09:12.144740177Z", + "finished_at": "2026-01-23T20:09:46.065291337Z" }, "t_001_basic_tables": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_001_basic_tables", "lang": "rust", "golden_published": true, @@ -69,25 +69,25 @@ "llm_db": "basics-t-001-basic-tables-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:58.838771838Z", - "finished_at": "2026-01-27T19:51:33.707208916Z" + "started_at": "2026-01-23T20:09:14.464369753Z", + "finished_at": "2026-01-23T20:09:44.014749235Z" }, "t_002_scheduled_table": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_002_scheduled_table", "lang": "rust", "golden_published": false, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db\n .tick_timer()\n .insert(TickTimer { scheduled_id: 0, scheduled_at: ScheduleAt::repeat_micros(50_000) });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext) {\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, ScheduleAt, Table};\n\n#[table(name = tick_timer, schedule(column = scheduled_at, reducer = tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext) {}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -99,24 +99,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling shlex v1.3.0\n Compiling either v1.15.0\n Compiling serde v1.0.228\n Compiling find-msvc-tools v0.1.8\n Compiling zerocopy v0.8.34\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling keccak v0.1.5\n Compiling bytes v1.11.0\n Compiling humantime v2.3.0\n Compiling convert_case v0.4.0\n Compiling zmij v1.0.17\n Compiling heck v0.4.1\n Compiling arrayvec v0.7.6\n Compiling second-stack v0.3.5\n Compiling serde_json v1.0.149\n Compiling hex v0.4.3\n Compiling bytemuck v1.24.0\n Compiling getrandom v0.2.17\n Compiling itoa v1.0.17\n Compiling smallvec v1.15.1\n Compiling arrayref v0.3.9\n Compiling itertools v0.12.1\n Compiling spacetimedb-lib v1.11.1\n Compiling constant_time_eq v0.4.2\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling rand_core v0.6.4\n Compiling cc v1.2.54\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling syn v2.0.114\n Compiling http v1.4.0\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling ethnum v1.5.2\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_002_scheduled_table/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:17:21\n |\n17 | .insert(TickTimer { scheduled_id: 0, scheduled_at: ScheduleAt::repeat_micros(50_000) });\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:16:14\n |\n15 | / ctx.db\n16 | | .tick_timer()\n | | -^^^^^^^^^^ method not found in `Local`\n | |_____________|\n |\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:76\n |\n17 | .insert(TickTimer { scheduled_id: 0, scheduled_at: ScheduleAt::repeat_micros(50_000) });\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nSome errors have detailed explanations: E0422, E0599.\nFor more information about an error, try `rustc --explain E0422`.\nerror: could not compile `spacetime-module` (lib) due to 5 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling serde v1.0.228\n Compiling zerocopy v0.8.33\n Compiling either v1.15.0\n Compiling shlex v1.3.0\n Compiling find-msvc-tools v0.1.8\n Compiling bitflags v2.10.0\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling thiserror v1.0.69\n Compiling zmij v1.0.16\n Compiling keccak v0.1.5\n Compiling heck v0.4.1\n Compiling arrayvec v0.7.6\n Compiling bytes v1.11.0\n Compiling humantime v2.3.0\n Compiling convert_case v0.4.0\n Compiling itoa v1.0.17\n Compiling second-stack v0.3.5\n Compiling serde_json v1.0.149\n Compiling constant_time_eq v0.4.2\n Compiling getrandom v0.2.17\n Compiling smallvec v1.15.1\n Compiling hex v0.4.3\n Compiling cc v1.2.54\n Compiling bytemuck v1.24.0\n Compiling arrayref v0.3.9\n Compiling spacetimedb-lib v1.11.1\n Compiling itertools v0.12.1\n Compiling memchr v2.7.6\n Compiling log v0.4.29\n Compiling rand_core v0.6.4\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling blake3 v1.8.3\n Compiling decorum v0.3.1\n Compiling block-buffer v0.10.4\n Compiling crypto-common v0.1.7\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling ethnum v1.5.2\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_002_scheduled_table/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(column = scheduled_at, reducer = tick))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:18:36\n |\n18 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:17:15\n |\n17 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:18:16\n |\n18 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:20:39\n |\n20 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nSome errors have detailed explanations: E0422, E0599.\nFor more information about an error, try `rustc --explain E0422`.\nerror: could not compile `spacetime-module` (lib) due to 5 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:00.465423417Z", - "finished_at": "2026-01-27T19:51:47.339587032Z" + "started_at": "2026-01-23T20:09:35.992436277Z", + "finished_at": "2026-01-23T20:10:39.770857477Z" }, "t_003_struct_in_table": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_003_struct_in_table", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", "total_tests": 1, - "passed_tests": 1, - "llm_output": "use spacetimedb::SpacetimeType;\n\n#[derive(SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n pos: Position,\n}", + "passed_tests": 0, + "llm_output": "use spacetimedb::ReducerContext;\n\n#[derive(spacetimedb::SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n pos: Position,\n}\n\n#[spacetimedb::reducer]\npub fn add_entity(ctx: &ReducerContext, id: i32, x: i32, y: i32) {\n let pos = Position { x, y };\n ctx.db.entity().insert(Entity { id, pos });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-003-struct-in-table-golden", @@ -124,26 +124,21 @@ "work_dir_golden": "target/llm-runs/basics/t_003_struct_in_table/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_003_struct_in_table/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, + "publish_error": { + "pass": false, + "partial": 0.0, "notes": { - "golden_db": "basics-t-003-struct-in-table-golden", - "llm_db": "basics-t-003-struct-in-table-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling unicode-ident v1.0.22\n Compiling quote v1.0.44\n Compiling version_check v0.9.5\n Compiling typenum v1.19.0\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling zerocopy v0.8.33\n Compiling serde v1.0.228\n Compiling shlex v1.3.0\n Compiling either v1.15.0\n Compiling find-msvc-tools v0.1.8\n Compiling anyhow v1.0.100\n Compiling nohash-hasher v0.2.0\n Compiling bitflags v2.10.0\n Compiling thiserror v1.0.69\n Compiling bytes v1.11.0\n Compiling heck v0.4.1\n Compiling humantime v2.3.0\n Compiling zmij v1.0.16\n Compiling keccak v0.1.5\n Compiling arrayvec v0.7.6\n Compiling convert_case v0.4.0\n Compiling hex v0.4.3\n Compiling bytemuck v1.24.0\n Compiling second-stack v0.3.5\n Compiling arrayref v0.3.9\n Compiling getrandom v0.2.17\n Compiling spacetimedb-lib v1.11.1\n Compiling itoa v1.0.17\n Compiling itertools v0.12.1\n Compiling constant_time_eq v0.4.2\n Compiling smallvec v1.15.1\n Compiling serde_json v1.0.149\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling rand_core v0.6.4\n Compiling scoped-tls v1.0.1\n Compiling cc v1.2.54\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling blake3 v1.8.3\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling block-buffer v0.10.4\n Compiling crypto-common v0.1.7\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling ethnum v1.5.2\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_003_struct_in_table/rust/server/gpt-5/llm)\nerror[E0599]: no method named `insert` found for reference `&entity__TableHandle` in the current scope\n --> src/lib.rs:20:21\n |\n20 | ctx.db.entity().insert(Entity { id, pos });\n | ^^^^^^\n |\n = help: items from traits can only be used if the trait is in scope\nhelp: trait `Table` which provides `insert` is implemented but not in scope; perhaps you want to import it\n |\n 2 + use spacetimedb::Table;\n |\nhelp: there is a method `try_insert` with a similar name\n |\n20 | ctx.db.entity().try_insert(Entity { id, pos });\n | ++++\n\nFor more information about this error, try `rustc --explain E0599`.\nerror: could not compile `spacetime-module` (lib) due to 1 previous error\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:43.120116357Z", - "finished_at": "2026-01-27T19:51:34.789700080Z" + "started_at": "2026-01-23T20:09:14.464130029Z", + "finished_at": "2026-01-23T20:09:54.314351498Z" }, "t_004_insert": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_004_insert", "lang": "rust", "golden_published": true, @@ -158,19 +153,6 @@ "work_dir_golden": "target/llm-runs/basics/t_004_insert/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_004_insert/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-004-insert-golden", - "llm_db": "basics-t-004-insert-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true - } - }, "data_parity_insert_user": { "pass": true, "partial": 1.0, @@ -187,16 +169,29 @@ "llm_out": "id | name | age | active ----+---------+-----+-------- 1 | \"Alice\" | 30 | true", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "insert_user", - "server": "http://127.0.0.1:33615" + "server": "http://127.0.0.1:41115" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-004-insert-golden", + "llm_db": "basics-t-004-insert-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41115", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:00.012104606Z", - "finished_at": "2026-01-27T19:51:27.169795394Z" + "started_at": "2026-01-23T20:09:14.983974693Z", + "finished_at": "2026-01-23T20:09:35.992396086Z" }, "t_005_update": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_005_update", "lang": "rust", "golden_published": true, @@ -211,17 +206,11 @@ "work_dir_golden": "target/llm-runs/basics/t_005_update/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_005_update/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { + "seed_users_row": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "basics-t-005-update-golden", - "llm_db": "basics-t-005-update-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } }, "data_parity_update_user": { @@ -240,30 +229,36 @@ "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "update_user", - "server": "http://127.0.0.1:33615" + "server": "http://127.0.0.1:41115" } }, - "seed_users_row": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + "golden_db": "basics-t-005-update-golden", + "llm_db": "basics-t-005-update-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41115", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:22.268945837Z", - "finished_at": "2026-01-27T19:51:01.660325703Z" + "started_at": "2026-01-23T20:08:57.792213429Z", + "finished_at": "2026-01-23T20:09:53.091667873Z" }, "t_006_delete": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_006_delete", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn delete_user(ctx: &ReducerContext, id: i32) {\n ctx.db.user().id().delete(&id);\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn delete_user(ctx: &ReducerContext, id: i32) {\n ctx.db.user().id().delete(&id);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-006-delete-golden", @@ -271,11 +266,13 @@ "work_dir_golden": "target/llm-runs/basics/t_006_delete/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_006_delete/rust/server/gpt-5/llm", "scorer_details": { - "seed_users_row": { + "delete_user_count_zero": { "pass": true, "partial": 1.0, "notes": { - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" } }, "schema_parity": { @@ -286,34 +283,32 @@ "llm_db": "basics-t-006-delete-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } }, - "delete_user_count_zero": { + "seed_users_row": { "pass": true, "partial": 1.0, "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:18.814239252Z", - "finished_at": "2026-01-27T19:51:00.465380864Z" + "started_at": "2026-01-23T20:08:35.084889228Z", + "finished_at": "2026-01-23T20:09:14.643664761Z" }, "t_007_crud": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_007_crud", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn crud(ctx: &ReducerContext) {\n let users = ctx.db.user();\n\n // insert (id=1, name=\"Alice\", age=30, active=true)\n users.insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n\n // insert (id=2, name=\"Bob\", age=22, active=false)\n users.insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n\n // update (id=1, name=\"Alice2\", age=31, active=false)\n users.id().update(User {\n id: 1,\n name: \"Alice2\".to_string(),\n age: 31,\n active: false,\n });\n\n // delete id=2\n users.id().delete(&2);\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, UniqueColumn};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn crud(ctx: &ReducerContext) {\n let users = ctx.db.user();\n\n let mut u1 = users.insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n\n let _u2 = users.insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n\n u1.name = \"Alice2\".to_string();\n u1.age = 31;\n u1.active = false;\n let _u1_updated = users.id().update(u1);\n\n users.id().delete(&2);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -330,17 +325,18 @@ "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" } }, - "schema_parity": { + "crud_row_id1_parity": { "pass": true, "partial": 1.0, "notes": { + "args": [], "golden_db": "basics-t-007-crud-golden", + "golden_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "llm_db": "basics-t-007-crud-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true + "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", + "query": "SELECT id, name, age, active FROM user WHERE id=1", + "reducer": "crud", + "server": "http://127.0.0.1:41115" } }, "crud_total_count_one": { @@ -352,34 +348,33 @@ "sql": "SELECT COUNT(*) AS n FROM user" } }, - "crud_row_id1_parity": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "args": [], "golden_db": "basics-t-007-crud-golden", - "golden_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "llm_db": "basics-t-007-crud-gpt-5-llm", - "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", - "query": "SELECT id, name, age, active FROM user WHERE id=1", - "reducer": "crud", - "server": "http://127.0.0.1:33615" + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41115", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:19.572189963Z", - "finished_at": "2026-01-27T19:51:00.012056746Z" + "started_at": "2026-01-23T20:08:56.057273916Z", + "finished_at": "2026-01-23T20:09:48.569368820Z" }, "t_008_index_lookup": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_008_index_lookup", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(user) = ctx.db.user().id().find(id) {\n let _ = ctx.db.result().try_insert(ResultRow {\n id: user.id,\n name: user.name.clone(),\n });\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(u) = ctx.db.user().id().find(id) {\n let User { id, name, .. } = u;\n ctx.db.result().id().delete(&id);\n ctx.db.result().insert(ResultRow { id, name });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -394,19 +389,6 @@ "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-008-index-lookup-golden", - "llm_db": "basics-t-008-index-lookup-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true - } - }, "index_lookup_projection_parity": { "pass": true, "partial": 1.0, @@ -420,23 +402,36 @@ "llm_out": "id | name ----+--------- 1 | \"Alice\"", "query": "SELECT id, name FROM result WHERE id=1", "reducer": "lookup_user_name", - "server": "http://127.0.0.1:33615" + "server": "http://127.0.0.1:41115" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-008-index-lookup-golden", + "llm_db": "basics-t-008-index-lookup-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41115", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:59.032238062Z", - "finished_at": "2026-01-27T19:51:34.520084103Z" + "started_at": "2026-01-23T20:09:14.643699808Z", + "finished_at": "2026-01-23T20:09:52.566672855Z" }, "t_009_init": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_009_init", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) {\n ctx.db.user().insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n ctx.db.user().insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n let user = ctx.db.user();\n user.insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n user.insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -470,7 +465,7 @@ "llm_db": "basics-t-009-init-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } @@ -486,11 +481,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:21.549783Z", - "finished_at": "2026-01-27T19:50:59.032183836Z" + "started_at": "2026-01-23T20:08:57.046090650Z", + "finished_at": "2026-01-23T20:09:23.724177316Z" }, "t_010_connect": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_010_connect", "lang": "rust", "golden_published": true, @@ -513,25 +508,25 @@ "llm_db": "basics-t-010-connect-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:19.565630879Z", - "finished_at": "2026-01-27T19:50:43.120012892Z" + "started_at": "2026-01-23T20:08:35.620982701Z", + "finished_at": "2026-01-23T20:09:12.144710803Z" }, "t_011_helper_function": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_011_helper_function", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let sum = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n ctx.db.result().insert(ResultRow { id, sum: add(a, b) });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -539,6 +534,15 @@ "work_dir_golden": "target/llm-runs/basics/t_011_helper_function/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_011_helper_function/rust/server/gpt-5/llm", "scorer_details": { + "helper_func_sum_abs": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" + } + }, "helper_func_sum_parity": { "pass": true, "partial": 1.0, @@ -554,16 +558,7 @@ "llm_out": "id | sum ----+----- 1 | 5", "query": "SELECT id, sum FROM result WHERE id=1", "reducer": "compute_sum", - "server": "http://127.0.0.1:33615" - } - }, - "helper_func_sum_abs": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" + "server": "http://127.0.0.1:41115" } }, "schema_parity": { @@ -574,25 +569,25 @@ "llm_db": "basics-t-011-helper-function-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:00.227420335Z", - "finished_at": "2026-01-27T19:51:29.538171947Z" + "started_at": "2026-01-23T20:09:23.724208808Z", + "finished_at": "2026-01-23T20:09:51.292524674Z" }, "t_012_spacetime_product_type": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_012_spacetime_product_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[reducer]\nfn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -617,7 +612,7 @@ "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } @@ -637,23 +632,23 @@ "llm_out": "id | value ----+----------------------- 1 | (left = 2, right = 3)", "query": "SELECT id, value FROM result WHERE id=1", "reducer": "set_score", - "server": "http://127.0.0.1:33615" + "server": "http://127.0.0.1:41115" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:17.029809591Z", - "finished_at": "2026-01-27T19:50:58.838714798Z" + "started_at": "2026-01-23T20:08:32.450266496Z", + "finished_at": "2026-01-23T20:09:14.310539584Z" }, "t_013_spacetime_sum_type": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_013_spacetime_sum_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, - "passed_tests": 2, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[reducer]\npub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Shape::Circle(radius),\n });\n}", + "passed_tests": 3, + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\nstruct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\nenum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = result)]\nstruct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[reducer]\nfn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {\n ctx.db.result().insert(ResultRow { id, value: Shape::Circle(radius) });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-013-spacetime-sum-type-golden", @@ -661,12 +656,13 @@ "work_dir_golden": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/gpt-5/llm", "scorer_details": { - "sum_type_row_parity": { - "pass": false, - "partial": 0.0, + "sum_type_row_count": { + "pass": true, + "partial": 1.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `result`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef5026b116b67d90edbd0acaca12a273f2a7e6e888cc7265a5d4a4fe7173/sql)\n", - "phase": "sql_golden" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" } }, "schema_parity": { @@ -677,27 +673,35 @@ "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } }, - "sum_type_row_count": { - "pass": true, - "partial": 1.0, + "sum_type_row_parity": { + "pass": false, + "partial": 0.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" + "args": [ + 1, + 10 + ], + "golden_db": "schema-t-013-spacetime-sum-type-golden", + "golden_out": "id | value ----+--------------- 1 | (Circle = 10)", + "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", + "llm_out": "id | value ----+--------------- 1 | (Circle = 10)", + "query": "SELECT id, value FROM result WHERE id=1", + "reducer": "set_circle", + "server": "http://127.0.0.1:41115" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.665478058Z", - "finished_at": "2026-01-27T19:50:21.549671530Z" + "started_at": "2026-01-23T20:07:57.743148689Z", + "finished_at": "2026-01-23T20:08:32.450224286Z" }, "t_014_elementary_columns": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_014_elementary_columns", "lang": "rust", "golden_published": true, @@ -712,31 +716,31 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/rust/server/gpt-5/llm", "scorer_details": { - "elementary_columns_row_parity": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "args": [], "golden_db": "schema-t-014-elementary-columns-golden", - "golden_out": "id | count | total | price | ratio | active | name ----+-------+------------+-------+-------+--------+--------- 1 | 2 | 3000000000 | 1.5 | 2.25 | true | \"Alice\"", "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", - "llm_out": "id | count | total | price | ratio | active | name ----+-------+------------+-------+-------+--------+--------- 1 | 2 | 3000000000 | 1.5 | 2.25 | true | \"Alice\"", - "query": "SELECT id, count, total, price, ratio, active, name FROM primitive WHERE id=1", - "reducer": "seed", - "server": "http://127.0.0.1:33615" + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41115", + "tables_diff": null, + "tables_equal": true } }, - "schema_parity": { + "elementary_columns_row_parity": { "pass": true, "partial": 1.0, "notes": { + "args": [], "golden_db": "schema-t-014-elementary-columns-golden", + "golden_out": "id | count | total | price | ratio | active | name ----+-------+------------+-------+-------+--------+--------- 1 | 2 | 3000000000 | 1.5 | 2.25 | true | \"Alice\"", "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true + "llm_out": "id | count | total | price | ratio | active | name ----+-------+------------+-------+-------+--------+--------- 1 | 2 | 3000000000 | 1.5 | 2.25 | true | \"Alice\"", + "query": "SELECT id, count, total, price, ratio, active, name FROM primitive WHERE id=1", + "reducer": "seed", + "server": "http://127.0.0.1:41115" } }, "elementary_columns_row_count": { @@ -750,18 +754,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:50:12.818589409Z", - "finished_at": "2026-01-27T19:51:00.227383147Z" + "started_at": "2026-01-23T20:08:30.379293605Z", + "finished_at": "2026-01-23T20:09:14.464089675Z" }, "t_015_product_type_columns": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_015_product_type_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, - "passed_tests": 2, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType, Clone)]\nstruct Address {\n street: String,\n zip: i32,\n}\n\n#[derive(SpacetimeType, Clone)]\nstruct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = profile)]\nstruct Profile {\n #[primary_key]\n id: i32,\n home: Address,\n work: Address,\n pos: Position,\n}\n\n#[reducer]\nfn seed(ctx: &ReducerContext) {\n let tbl = ctx.db.profile();\n if tbl.count() == 0 {\n let home = Address { street: \"1 Main\".to_string(), zip: 11111 };\n let work = Address { street: \"2 Broad\".to_string(), zip: 22222 };\n let pos = Position { x: 7, y: 9 };\n tbl.insert(Profile { id: 1, home, work, pos });\n }\n}", + "passed_tests": 3, + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\nstruct Address {\n street: String,\n zip: i32,\n}\n\n#[derive(SpacetimeType)]\nstruct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = profile)]\nstruct Profile {\n #[primary_key]\n id: i32,\n home: Address,\n work: Address,\n pos: Position,\n}\n\n#[reducer]\nfn seed(ctx: &ReducerContext) {\n let home = Address { street: \"1 Main\".to_string(), zip: 11111 };\n let work = Address { street: \"2 Broad\".to_string(), zip: 22222 };\n let pos = Position { x: 7, y: 9 };\n match ctx.db.profile().id().find(1) {\n Some(mut row) => {\n row.home = home;\n row.work = work;\n row.pos = pos;\n ctx.db.profile().id().update(row);\n }\n None => {\n ctx.db.profile().insert(Profile { id: 1, home, work, pos });\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-015-product-type-columns-golden", @@ -769,21 +773,18 @@ "work_dir_golden": "target/llm-runs/schema/t_015_product_type_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_015_product_type_columns/rust/server/gpt-5/llm", "scorer_details": { - "product_type_columns_row_count": { + "product_type_columns_row_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM profile WHERE id=1" - } - }, - "product_type_columns_row_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `profile`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200171a9841d8ed2a9c762ac4e081fe93ed52fe5c9e32ae9bbd874bb7e1a8b5/sql)\n", - "phase": "sql_golden" + "args": [], + "golden_db": "schema-t-015-product-type-columns-golden", + "golden_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", + "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", + "llm_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", + "query": "SELECT id, home, work, pos FROM profile WHERE id=1", + "reducer": "seed", + "server": "http://127.0.0.1:41115" } }, "schema_parity": { @@ -794,25 +795,34 @@ "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } + }, + "product_type_columns_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM profile WHERE id=1" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.666090278Z", - "finished_at": "2026-01-27T19:50:19.565536981Z" + "started_at": "2026-01-23T20:07:57.743649083Z", + "finished_at": "2026-01-23T20:08:57.046048716Z" }, "t_016_sum_type_columns": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_016_sum_type_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 1, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n if ctx.db.drawing().id().find(1i32).is_none() {\n ctx.db.drawing().insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n }\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[derive(spacetimedb::SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(spacetimedb::SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[spacetimedb::table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n if ctx.db.drawing().id().find(1).is_none() {\n ctx.db.drawing().insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-016-sum-type-columns-golden", @@ -824,7 +834,7 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200881b5220df4b060ef4c2656171f2f8326cecff55db6c3c11d3ebbd2f5cec/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c200be63a5c073cb57163fbe420fbf96d0ca1c24fb78e5d67bbed19841d5eeee/sql)\n", "phase": "sql_golden" } }, @@ -836,7 +846,7 @@ "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } @@ -845,24 +855,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c20074c3ee57884fdd34989755bdcfa11644a8f79ecbbdbf8f5182f2be46b5ec/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c2001257ca4ff5c673696324b8a29b10931896a2877a4425230bec1856988aad/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.665270093Z", - "finished_at": "2026-01-27T19:50:17.767945290Z" + "started_at": "2026-01-23T20:07:57.742955241Z", + "finished_at": "2026-01-23T20:08:35.620943048Z" }, "t_017_scheduled_columns": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_017_scheduled_columns", "lang": "rust", "golden_published": false, "model_name": "GPT-5", "total_tests": 2, "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::RepeatMicros(50_000),\n });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -874,24 +884,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling unicode-ident v1.0.22\n Compiling quote v1.0.44\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling heck v0.5.0\n Compiling serde_core v1.0.228\n Compiling cfg-if v1.0.4\n Compiling either v1.15.0\n Compiling serde v1.0.228\n Compiling find-msvc-tools v0.1.8\n Compiling shlex v1.3.0\n Compiling zerocopy v0.8.34\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling keccak v0.1.5\n Compiling convert_case v0.4.0\n Compiling zmij v1.0.17\n Compiling arrayvec v0.7.6\n Compiling humantime v2.3.0\n Compiling bytes v1.11.0\n Compiling heck v0.4.1\n Compiling second-stack v0.3.5\n Compiling hex v0.4.3\n Compiling serde_json v1.0.149\n Compiling constant_time_eq v0.4.2\n Compiling itoa v1.0.17\n Compiling arrayref v0.3.9\n Compiling getrandom v0.2.17\n Compiling spacetimedb-lib v1.11.1\n Compiling bytemuck v1.24.0\n Compiling smallvec v1.15.1\n Compiling rand_core v0.6.4\n Compiling cc v1.2.54\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling itertools v0.12.1\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ethnum v1.5.2\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:15:36\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0412]: cannot find type `TickTimer` in this scope\n --> src/lib.rs:23:42\n |\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:15:16\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `RepeatMicros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:39\n |\n17 | scheduled_at: ScheduleAt::RepeatMicros(50_000),\n | ^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n 22 | #[reducer]\n | ---------- required by a bound introduced by this call\n 23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `register_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:746:81\n |\n746 | pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) {\n | ^^^^^^^^^^^^^^ required by this bound in `register_reducer`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n22 | #[reducer]\n | ---------- required by a bound introduced by this call\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `invoke_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:45:19\n |\n44 | pub fn invoke_reducer<'a, A: Args<'a>>(\n | -------------- required by a bound in this function\n45 | reducer: impl Reducer<'a, A>,\n | ^^^^^^^^^^^^^^ required by this bound in `invoke_reducer`\n\nSome errors have detailed explanations: E0277, E0412, E0422, E0599.\nFor more information about an error, try `rustc --explain E0277`.\nerror: could not compile `spacetime-module` (lib) due to 8 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling serde v1.0.228\n Compiling either v1.15.0\n Compiling shlex v1.3.0\n Compiling zerocopy v0.8.33\n Compiling find-msvc-tools v0.1.8\n Compiling nohash-hasher v0.2.0\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling anyhow v1.0.100\n Compiling arrayvec v0.7.6\n Compiling zmij v1.0.16\n Compiling heck v0.4.1\n Compiling convert_case v0.4.0\n Compiling humantime v2.3.0\n Compiling bytes v1.11.0\n Compiling keccak v0.1.5\n Compiling constant_time_eq v0.4.2\n Compiling bytemuck v1.24.0\n Compiling second-stack v0.3.5\n Compiling smallvec v1.15.1\n Compiling getrandom v0.2.17\n Compiling hex v0.4.3\n Compiling spacetimedb-lib v1.11.1\n Compiling itertools v0.12.1\n Compiling cc v1.2.54\n Compiling serde_json v1.0.149\n Compiling itoa v1.0.17\n Compiling arrayref v0.3.9\n Compiling rand_core v0.6.4\n Compiling memchr v2.7.6\n Compiling log v0.4.29\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling syn v2.0.114\n Compiling http v1.4.0\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling ethnum v1.5.2\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:15:36\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0412]: cannot find type `TickTimer` in this scope\n --> src/lib.rs:23:42\n |\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:15:16\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:39\n |\n17 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n 22 | #[reducer]\n | ---------- required by a bound introduced by this call\n 23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `register_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:746:81\n |\n746 | pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) {\n | ^^^^^^^^^^^^^^ required by this bound in `register_reducer`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n22 | #[reducer]\n | ---------- required by a bound introduced by this call\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `invoke_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:45:19\n |\n44 | pub fn invoke_reducer<'a, A: Args<'a>>(\n | -------------- required by a bound in this function\n45 | reducer: impl Reducer<'a, A>,\n | ^^^^^^^^^^^^^^ required by this bound in `invoke_reducer`\n\nSome errors have detailed explanations: E0277, E0412, E0422, E0599.\nFor more information about an error, try `rustc --explain E0277`.\nerror: could not compile `spacetime-module` (lib) due to 8 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.664841535Z", - "finished_at": "2026-01-27T19:50:33.923572352Z" + "started_at": "2026-01-23T20:07:57.742610502Z", + "finished_at": "2026-01-23T20:08:56.057254318Z" }, "t_018_constraints": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_018_constraints", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, - "passed_tests": 2, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let accounts = ctx.db.account();\n let _ = accounts.try_insert(Account { id: 1, email: \"a@example.com\".to_string(), name: \"Alice\".to_string() });\n let _ = accounts.try_insert(Account { id: 2, email: \"b@example.com\".to_string(), name: \"Bob\".to_string() });\n}", + "passed_tests": 3, + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db\n .account()\n .insert(Account {\n id: 1,\n email: \"a@example.com\".to_string(),\n name: \"Alice\".to_string(),\n });\n ctx.db\n .account()\n .insert(Account {\n id: 2,\n email: \"b@example.com\".to_string(),\n name: \"Bob\".to_string(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-018-constraints-golden", @@ -925,24 +935,43 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `account`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c2002f3e10afac17bd0350f8d8feb90d1ae94d73c7c44c6824e7324679a8e5b9/sql)\n", - "phase": "sql_golden" + "args": [], + "golden_db": "schema-t-018-constraints-golden", + "golden_out": "id | email | name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", + "llm_db": "schema-t-018-constraints-gpt-5-llm", + "llm_out": "id | email | name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", + "query": "SELECT id, email, name FROM account WHERE id=1", + "reducer": "seed", + "server": "http://127.0.0.1:41115" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-018-constraints-golden", + "llm_db": "schema-t-018-constraints-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41115", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.664543506Z", - "finished_at": "2026-01-27T19:50:17.029704757Z" + "started_at": "2026-01-23T20:07:57.742384971Z", + "finished_at": "2026-01-23T20:08:30.379256146Z" }, "t_019_many_to_many": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_019_many_to_many", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 5, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[spacetimedb::table(name = group)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[spacetimedb::table(\n name = membership,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n // Clear existing rows to ensure the database contains exactly the specified rows.\n let membership_ids: Vec = ctx.db.membership().iter().map(|m| m.id).collect();\n for id in membership_ids {\n ctx.db.membership().id().delete(&id);\n }\n\n let user_ids: Vec = ctx.db.user().iter().map(|u| u.user_id).collect();\n for id in user_ids {\n ctx.db.user().user_id().delete(&id);\n }\n\n let group_ids: Vec = ctx.db.group().iter().map(|g| g.group_id).collect();\n for id in group_ids {\n ctx.db.group().group_id().delete(&id);\n }\n\n // Insert users\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".to_string() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".to_string() });\n\n // Insert groups\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".to_string() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".to_string() });\n\n // Insert memberships\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[table(name = group)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[table(\n name = membership,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n // Clear existing rows to ensure exactly the requested rows exist after seeding\n let membership_ids: Vec = ctx.db.membership().iter().map(|m| m.id).collect();\n for id in membership_ids {\n ctx.db.membership().id().delete(&id);\n }\n\n let user_ids: Vec = ctx.db.user().iter().map(|u| u.user_id).collect();\n for id in user_ids {\n ctx.db.user().user_id().delete(&id);\n }\n\n let group_ids: Vec = ctx.db.group().iter().map(|g| g.group_id).collect();\n for id in group_ids {\n ctx.db.group().group_id().delete(&id);\n }\n\n // Insert users\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".to_string() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".to_string() });\n\n // Insert groups\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".to_string() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".to_string() });\n\n // Insert memberships\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-019-many-to-many-golden", @@ -950,15 +979,6 @@ "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/rust/server/gpt-5/llm", "scorer_details": { - "m2m_has_2_20": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -967,7 +987,7 @@ "llm_db": "schema-t-019-many-to-many-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } @@ -981,13 +1001,13 @@ "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" } }, - "m2m_has_1_10": { + "m2m_has_2_20": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=10" + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" } }, "memberships_three_rows": { @@ -998,21 +1018,30 @@ "expected": 3, "sql": "SELECT COUNT(*) AS n FROM membership" } + }, + "m2m_has_1_10": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=10" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.665682949Z", - "finished_at": "2026-01-27T19:50:22.268882588Z" + "started_at": "2026-01-23T20:07:57.743323315Z", + "finished_at": "2026-01-23T20:08:57.792175612Z" }, "t_020_ecs": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_020_ecs", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 1, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let _ = ctx.db.entity().try_insert(Entity { id: 1 });\n let _ = ctx.db.entity().try_insert(Entity { id: 2 });\n\n let _ = ctx.db.position().try_insert(Position { entity_id: 1, x: 0, y: 0 });\n let _ = ctx.db.velocity().try_insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n let _ = ctx.db.position().try_insert(Position { entity_id: 2, x: 10, y: 0 });\n let _ = ctx.db.velocity().try_insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n}\n\n#[reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let nx = pos.x + vel.vx;\n let ny = pos.y + vel.vy;\n\n if let Some(mut existing) = ctx.db.next_position().entity_id().find(pos.entity_id) {\n existing.x = nx;\n existing.y = ny;\n let _ = ctx.db.next_position().entity_id().update(existing);\n } else {\n let _ = ctx.db.next_position().try_insert(NextPosition {\n entity_id: pos.entity_id,\n x: nx,\n y: ny,\n });\n }\n }\n }\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[spacetimedb::table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[spacetimedb::table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n // Clear and insert entities\n for &id in &[1, 2] {\n if ctx.db.entity().id().find(id).is_some() {\n ctx.db.entity().id().delete(&id);\n }\n ctx.db.entity().insert(Entity { id });\n }\n\n // Clear existing positions/velocities for these entities and insert new values\n // Entity 1: pos=(0,0), vel=(1,0)\n if ctx.db.position().entity_id().find(1).is_some() {\n ctx.db.position().entity_id().delete(&1);\n }\n ctx.db.position().insert(Position { entity_id: 1, x: 0, y: 0 });\n if ctx.db.velocity().entity_id().find(1).is_some() {\n ctx.db.velocity().entity_id().delete(&1);\n }\n ctx.db.velocity().insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n // Entity 2: pos=(10,0), vel=(-2,3)\n if ctx.db.position().entity_id().find(2).is_some() {\n ctx.db.position().entity_id().delete(&2);\n }\n ctx.db.position().insert(Position { entity_id: 2, x: 10, y: 0 });\n if ctx.db.velocity().entity_id().find(2).is_some() {\n ctx.db.velocity().entity_id().delete(&2);\n }\n ctx.db.velocity().insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n\n // Clean any existing next_position rows for these entities\n for &id in &[1, 2] {\n if ctx.db.next_position().entity_id().find(id).is_some() {\n ctx.db.next_position().entity_id().delete(&id);\n }\n }\n}\n\n#[spacetimedb::reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let nx = pos.x + vel.vx;\n let ny = pos.y + vel.vy;\n let next = NextPosition {\n entity_id: pos.entity_id,\n x: nx,\n y: ny,\n };\n\n if ctx.db.next_position().entity_id().find(pos.entity_id).is_some() {\n let _ = ctx.db.next_position().entity_id().update(next);\n } else {\n let _ = ctx.db.next_position().insert(next);\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-020-ecs-golden", @@ -1024,15 +1053,15 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", "phase": "sql" } }, - "ecs_next_pos_entity2": { + "ecs_seed_positions_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", "phase": "sql" } }, @@ -1044,7 +1073,7 @@ "llm_db": "schema-t-020-ecs-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } @@ -1053,25 +1082,25 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", "phase": "sql" } }, - "ecs_seed_positions_count": { + "ecs_next_pos_entity2": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.665885964Z", - "finished_at": "2026-01-27T19:50:18.814108696Z" + "started_at": "2026-01-23T20:07:57.743495455Z", + "finished_at": "2026-01-23T20:09:14.983916389Z" }, "t_021_multi_column_index": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_021_multi_column_index", "lang": "rust", "golden_published": true, @@ -1086,6 +1115,15 @@ "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/rust/server/gpt-5/llm", "scorer_details": { + "mcindex_lookup_u7_d1": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -1094,7 +1132,7 @@ "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:33615", + "server": "http://127.0.0.1:41115", "tables_diff": null, "tables_equal": true } @@ -1108,16 +1146,7 @@ "sql": "SELECT COUNT(*) AS n FROM log" } }, - "mcindex_lookup_u7_d1": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" - } - }, - "mcindex_lookup_u7_d2": { + "mcindex_seed_count": { "pass": true, "partial": 1.0, "notes": { @@ -1128,8 +1157,8 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:49:28.665048738Z", - "finished_at": "2026-01-27T19:50:12.818516478Z" + "started_at": "2026-01-23T20:07:57.742772776Z", + "finished_at": "2026-01-23T20:08:35.084850930Z" } } } @@ -1137,21 +1166,21 @@ }, { "mode": "docs", - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_000_empty_reducers", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(ctx: &ReducerContext) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(ctx: &ReducerContext, count: i32) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(ctx: &ReducerContext, name: String) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(ctx: &ReducerContext, count: i32, name: String) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(ctx: &ReducerContext, active: bool, ratio: f32, label: String) {}", + "llm_output": "#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &spacetimedb::ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &spacetimedb::ReducerContext, _count: i32) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &spacetimedb::ReducerContext, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &spacetimedb::ReducerContext, _count: i32, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &spacetimedb::ReducerContext, _active: bool, _ratio: f32, _label: String) {\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-000-empty-reducers-golden", @@ -1169,11 +1198,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:02.635478741Z", - "finished_at": "2026-01-27T19:53:40.787269737Z" + "started_at": "2026-01-23T20:12:10.018237719Z", + "finished_at": "2026-01-23T20:12:41.638729168Z" }, "t_001_basic_tables": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_001_basic_tables", "lang": "rust", "golden_published": true, @@ -1198,18 +1227,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:04.338845678Z", - "finished_at": "2026-01-27T19:53:39.243226783Z" + "started_at": "2026-01-23T20:12:46.725514922Z", + "finished_at": "2026-01-23T20:13:51.799945305Z" }, "t_002_scheduled_table": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_002_scheduled_table", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) -> Result<(), String> {\n Ok(())\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n if ctx.db.tick_timer().count() == 0 {\n use std::time::Duration;\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n });\n }\n Ok(())\n}", + "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {\n // No-op scheduled tick.\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n });\n Ok(())\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -1227,11 +1256,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:38.403872273Z", - "finished_at": "2026-01-27T19:54:31.831288022Z" + "started_at": "2026-01-23T20:13:28.197750258Z", + "finished_at": "2026-01-23T20:14:26.307958881Z" }, "t_003_struct_in_table": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_003_struct_in_table", "lang": "rust", "golden_published": true, @@ -1256,11 +1285,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:02.638916802Z", - "finished_at": "2026-01-27T19:53:40.055864699Z" + "started_at": "2026-01-23T20:12:41.638758353Z", + "finished_at": "2026-01-23T20:13:47.479970679Z" }, "t_004_insert": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_004_insert", "lang": "rust", "golden_published": true, @@ -1275,29 +1304,29 @@ "work_dir_golden": "target/llm-runs/basics/t_004_insert/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_004_insert/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { + "data_parity_insert_user": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", - "phase": "describe_golden" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", + "phase": "call_reducer_golden" } }, - "data_parity_insert_user": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", - "phase": "call_reducer_golden" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", + "phase": "describe_golden" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:33.748279444Z", - "finished_at": "2026-01-27T19:53:56.014195443Z" + "started_at": "2026-01-23T20:12:46.734575843Z", + "finished_at": "2026-01-23T20:13:46.613223334Z" }, "t_005_update": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_005_update", "lang": "rust", "golden_published": true, @@ -1328,6 +1357,14 @@ "phase": "describe_golden" } }, + "data_parity_update_user": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", + "phase": "call_reducer_golden" + } + }, "seed_users_row": { "pass": false, "partial": 0.0, @@ -1339,11 +1376,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:00.578961998Z", - "finished_at": "2026-01-27T19:53:38.403844461Z" + "started_at": "2026-01-23T20:12:10.015338220Z", + "finished_at": "2026-01-23T20:13:14.713691221Z" }, "t_006_delete": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_006_delete", "lang": "rust", "golden_published": true, @@ -1366,15 +1403,6 @@ "phase": "describe_golden" } }, - "seed_users_row": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-006-delete-golden`.\n", - "phase": "sql_golden", - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" - } - }, "delete_user_count_zero": { "pass": true, "partial": 1.0, @@ -1383,21 +1411,30 @@ "expected": 0, "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" } + }, + "seed_users_row": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-006-delete-golden`.\n", + "phase": "sql_golden", + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:52:31.910165978Z", - "finished_at": "2026-01-27T19:52:58.192517311Z" + "started_at": "2026-01-23T20:12:09.994528341Z", + "finished_at": "2026-01-23T20:12:46.205776277Z" }, "t_007_crud": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_007_crud", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 1, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer]\npub fn crud(ctx: &ReducerContext) {\n ctx.db.user().insert(User { id: 1, name: \"Alice\".into(), age: 30, active: true });\n ctx.db.user().insert(User { id: 2, name: \"Bob\".into(), age: 22, active: false });\n ctx.db.user().id().update(User { id: 1, name: \"Alice2\".into(), age: 31, active: false });\n ctx.db.user().id().delete(2);\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer]\npub fn crud(ctx: &ReducerContext) {\n // insert (id=1, name=\"Alice\", age=30, active=true)\n ctx.db.user().insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n\n // insert (id=2, name=\"Bob\", age=22, active=false)\n ctx.db.user().insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n\n // update (id=1, name=\"Alice2\", age=31, active=false)\n if let Some(mut u1) = ctx.db.user().id().find(1) {\n u1.name = \"Alice2\".to_string();\n u1.age = 31;\n u1.active = false;\n ctx.db.user().id().update(u1);\n }\n\n // delete id=2\n ctx.db.user().id().delete(2);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -1413,6 +1450,15 @@ "phase": "call_reducer_golden" } }, + "crud_row_id2_deleted": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" + } + }, "crud_total_count_one": { "pass": false, "partial": 0.0, @@ -1429,30 +1475,21 @@ "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", "phase": "describe_golden" } - }, - "crud_row_id2_deleted": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" - } } }, "vendor": "openai", - "started_at": "2026-01-27T19:52:42.328837521Z", - "finished_at": "2026-01-27T19:53:33.740284067Z" + "started_at": "2026-01-23T20:12:10.004797508Z", + "finished_at": "2026-01-23T20:13:37.162002816Z" }, "t_008_index_lookup": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_008_index_lookup", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(user) = ctx.db.user().id().find(id) {\n let row = ResultRow { id: user.id, name: user.name.clone() };\n if ctx.db.result().id().find(user.id).is_some() {\n ctx.db.result().id().update(row);\n } else {\n ctx.db.result().insert(row);\n }\n }\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) -> Result<(), String> {\n if let Some(user) = ctx.db.user().id().find(id) {\n ctx.db\n .result()\n .try_insert(ResultRow { id: user.id, name: user.name.clone() })?;\n Ok(())\n } else {\n Err(\"User not found\".to_string())\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -1487,11 +1524,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:17.657026192Z", - "finished_at": "2026-01-27T19:53:54.093778910Z" + "started_at": "2026-01-23T20:12:46.729438058Z", + "finished_at": "2026-01-23T20:13:54.235945228Z" }, "t_009_init": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_009_init", "lang": "rust", "golden_published": true, @@ -1543,11 +1580,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:52:58.192552680Z", - "finished_at": "2026-01-27T19:53:38.342926441Z" + "started_at": "2026-01-23T20:12:10.009828612Z", + "finished_at": "2026-01-23T20:12:45.617807272Z" }, "t_010_connect": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_010_connect", "lang": "rust", "golden_published": true, @@ -1572,18 +1609,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:52:35.522740907Z", - "finished_at": "2026-01-27T19:53:02.635440935Z" + "started_at": "2026-01-23T20:12:09.998960857Z", + "finished_at": "2026-01-23T20:13:28.197638116Z" }, "t_011_helper_function": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_011_helper_function", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[spacetimedb::reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let sum = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[spacetimedb::reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let s = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum: s });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -1591,21 +1628,29 @@ "work_dir_golden": "target/llm-runs/basics/t_011_helper_function/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_011_helper_function/rust/server/gpt-5/llm", "scorer_details": { - "helper_func_sum_abs": { + "helper_func_sum_parity": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-011-helper-function-golden`.\n", + "phase": "call_reducer_golden" } }, - "helper_func_sum_parity": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-011-helper-function-golden`.\n", - "phase": "call_reducer_golden" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-011-helper-function-golden`.\n", + "phase": "describe_golden" + } + }, + "helper_func_sum_abs": { + "pass": false, + "partial": 0.0, + "notes": { + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" } }, "schema_parity": { @@ -1618,18 +1663,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:53:37.773674958Z", - "finished_at": "2026-01-27T19:53:57.689433966Z" + "started_at": "2026-01-23T20:13:14.723917629Z", + "finished_at": "2026-01-23T20:14:00.225654958Z" }, "t_012_spacetime_product_type": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_012_spacetime_product_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, SpacetimeType, Table};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[spacetimedb::reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[derive(spacetimedb::SpacetimeType, Clone, Debug)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[spacetimedb::reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -1637,12 +1682,13 @@ "work_dir_golden": "target/llm-runs/schema/t_012_spacetime_product_type/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_012_spacetime_product_type/rust/server/gpt-5/llm", "scorer_details": { - "product_type_row_parity": { + "product_type_row_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-012-spacetime-product-type-golden`.\n", - "phase": "call_reducer_golden" + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" } }, "schema_parity": { @@ -1653,75 +1699,57 @@ "phase": "describe_golden" } }, - "product_type_row_count": { + "product_type_row_parity": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-012-spacetime-product-type-golden`.\n", + "phase": "call_reducer_golden" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:52:29.436388253Z", - "finished_at": "2026-01-27T19:53:04.338818518Z" + "started_at": "2026-01-23T20:12:09.991277650Z", + "finished_at": "2026-01-23T20:12:46.725468970Z" }, "t_013_spacetime_sum_type": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_013_spacetime_sum_type", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 3, + "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::Table;\n\n#[derive(spacetimedb::SpacetimeType, Clone, Debug)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(spacetimedb::SpacetimeType, Clone, Debug)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[spacetimedb::reducer]\npub fn set_circle(ctx: &spacetimedb::ReducerContext, id: i32, radius: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Shape::Circle(radius),\n });\n}", + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-013-spacetime-sum-type-golden", - "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "schema_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-013-spacetime-sum-type-golden`.\n", - "phase": "describe_golden" - } - }, - "sum_type_row_count": { - "pass": false, - "partial": 0.0, - "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" - } - }, - "sum_type_row_parity": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-013-spacetime-sum-type-golden`.\n", - "phase": "call_reducer_golden" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.638500741Z", - "finished_at": "2026-01-27T19:53:00.578888253Z" + "started_at": "2026-01-23T20:14:26.308049242Z", + "finished_at": "2026-01-23T20:14:26.308049242Z" }, "t_014_elementary_columns": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_014_elementary_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000i64,\n price: 1.5f32,\n ratio: 2.25f64,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000,\n price: 1.5_f32,\n ratio: 2.25,\n active: true,\n name: \"Alice\".into(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-014-elementary-columns-golden", @@ -1729,14 +1757,6 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/rust/server/gpt-5/llm", "scorer_details": { - "elementary_columns_row_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", - "phase": "call_reducer_golden" - } - }, "elementary_columns_row_count": { "pass": false, "partial": 0.0, @@ -1753,14 +1773,22 @@ "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", "phase": "describe_golden" } + }, + "elementary_columns_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", + "phase": "call_reducer_golden" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:52:27.568323309Z", - "finished_at": "2026-01-27T19:53:02.605112864Z" + "started_at": "2026-01-23T20:12:09.987997099Z", + "finished_at": "2026-01-23T20:13:50.463947582Z" }, "t_015_product_type_columns": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_015_product_type_columns", "lang": "rust", "golden_published": false, @@ -1785,319 +1813,182 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:54:31.831326960Z", - "finished_at": "2026-01-27T19:54:31.831326960Z" + "started_at": "2026-01-23T20:14:26.308063959Z", + "finished_at": "2026-01-23T20:14:26.308063959Z" }, "t_016_sum_type_columns": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_016_sum_type_columns", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 3, + "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, SpacetimeType, Table};\n\n#[derive(SpacetimeType, Clone, Debug)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType, Clone, Debug)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[spacetimedb::table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n if ctx.db.drawing().count() == 0 {\n ctx.db.drawing().insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n }\n}", + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-016-sum-type-columns-golden", - "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "schema_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-016-sum-type-columns-golden`.\n", - "phase": "describe_golden" - } - }, - "sum_type_columns_row_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-016-sum-type-columns-golden`.\n", - "phase": "call_reducer_golden" - } - }, - "sum_type_columns_row_count": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c200596b7e7f2350abeb00119177ef3448e7673481a61aeaa7c22e4dd952cb52/sql)\n", - "phase": "sql" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.634170474Z", - "finished_at": "2026-01-27T19:52:27.568235316Z" + "started_at": "2026-01-23T20:14:26.308044663Z", + "finished_at": "2026-01-23T20:14:26.308044663Z" }, "t_017_scheduled_columns": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_017_scheduled_columns", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 2, - "passed_tests": 1, - "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _tick_timer: TickTimer) -> Result<(), String> {\n Ok(())\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().try_insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n })?;\n }\n Ok(())\n}", + "total_tests": 1, + "passed_tests": 0, + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-017-scheduled-columns-golden", - "llm_db": "schema-t-017-scheduled-columns-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_017_scheduled_columns/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "schema_parity": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-017-scheduled-columns-golden`.\n", - "phase": "describe_golden" - } - }, - "scheduled_seeded_one_row": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM tick_timer WHERE scheduled_id>=0" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.625840249Z", - "finished_at": "2026-01-27T19:52:35.522695487Z" + "started_at": "2026-01-23T20:14:26.308033084Z", + "finished_at": "2026-01-23T20:14:26.308033084Z" }, "t_018_constraints": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_018_constraints", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 3, + "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let ids: Vec = ctx.db.account().iter().map(|a| a.id).collect();\n for id in ids {\n ctx.db.account().id().delete(id);\n }\n\n ctx.db.account().insert(Account {\n id: 1,\n email: \"a@example.com\".into(),\n name: \"Alice\".into(),\n });\n ctx.db.account().insert(Account {\n id: 2,\n email: \"b@example.com\".into(),\n name: \"Bob\".into(),\n });\n}", + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-018-constraints-golden", - "llm_db": "schema-t-018-constraints-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_018_constraints/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_018_constraints/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "constraints_row_parity_after_seed": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-018-constraints-golden`.\n", - "phase": "call_reducer_golden" - } - }, - "schema_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-018-constraints-golden`.\n", - "phase": "describe_golden" - } - }, - "constraints_seed_two_rows": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM account WHERE id=2" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.622424031Z", - "finished_at": "2026-01-27T19:53:37.773579225Z" + "started_at": "2026-01-23T20:14:26.308021447Z", + "finished_at": "2026-01-23T20:14:26.308021447Z" }, "t_019_many_to_many": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_019_many_to_many", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 5, - "passed_tests": 4, - "llm_output": "use spacetimedb::Table;\n\n#[spacetimedb::table(name = user, public)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[spacetimedb::table(name = group, public)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[spacetimedb::table(\n name = membership,\n public,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &spacetimedb::ReducerContext) {\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".into() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".into() });\n\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".into() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".into() });\n\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", + "total_tests": 1, + "passed_tests": 0, + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-019-many-to-many-golden", - "llm_db": "schema-t-019-many-to-many-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "memberships_three_rows": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM membership" - } - }, - "schema_parity": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-019-many-to-many-golden`.\n", - "phase": "describe_golden" - } - }, - "m2m_has_1_20": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" - } - }, - "m2m_has_1_10": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=10" - } - }, - "m2m_has_2_20": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.642788029Z", - "finished_at": "2026-01-27T19:52:31.910080797Z" + "started_at": "2026-01-23T20:14:26.308054994Z", + "finished_at": "2026-01-23T20:14:26.308054994Z" }, "t_020_ecs": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_020_ecs", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 5, + "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[spacetimedb::table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[spacetimedb::table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n // First entity: id=1, pos=(0,0), vel=(1,0)\n ctx.db.entity().id().delete(1);\n ctx.db.position().entity_id().delete(1);\n ctx.db.velocity().entity_id().delete(1);\n ctx.db.entity().insert(Entity { id: 1 });\n ctx.db.position().insert(Position { entity_id: 1, x: 0, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n // Second entity: id=2, pos=(10,0), vel=(-2,3)\n ctx.db.entity().id().delete(2);\n ctx.db.position().entity_id().delete(2);\n ctx.db.velocity().entity_id().delete(2);\n ctx.db.entity().insert(Entity { id: 2 });\n ctx.db.position().insert(Position { entity_id: 2, x: 10, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n}\n\n#[spacetimedb::reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let nx = pos.x + vel.vx;\n let ny = pos.y + vel.vy;\n if let Some(_existing) = ctx.db.next_position().entity_id().find(pos.entity_id) {\n ctx.db\n .next_position()\n .entity_id()\n .update(NextPosition { entity_id: pos.entity_id, x: nx, y: ny });\n } else {\n ctx.db\n .next_position()\n .insert(NextPosition { entity_id: pos.entity_id, x: nx, y: ny });\n }\n }\n }\n}", + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-020-ecs-golden", - "llm_db": "schema-t-020-ecs-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_020_ecs/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_020_ecs/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "schema_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-020-ecs-golden`.\n", - "phase": "describe_golden" - } - }, - "ecs_step_next_positions_count": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", - "phase": "sql" - } - }, - "ecs_next_pos_entity1": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", - "phase": "sql" - } - }, - "ecs_seed_positions_count": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", - "phase": "sql" - } - }, - "ecs_next_pos_entity2": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", - "phase": "sql" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.647113172Z", - "finished_at": "2026-01-27T19:52:42.328754582Z" + "started_at": "2026-01-23T20:14:26.308059854Z", + "finished_at": "2026-01-23T20:14:26.308059854Z" }, "t_021_multi_column_index": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "task": "t_021_multi_column_index", "lang": "rust", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 4, - "passed_tests": 3, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = log, index(name = by_user_day, btree(columns = [user_id, day])))]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.log().insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".into() });\n ctx.db.log().insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".into() });\n ctx.db.log().insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".into() });\n}", + "total_tests": 1, + "passed_tests": 0, + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-021-multi-column-index-golden", - "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/rust/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/rust/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "schema_parity": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-021-multi-column-index-golden`.\n", - "phase": "describe_golden" - } - }, - "mcindex_seed_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM log" - } - }, - "mcindex_lookup_u7_d1": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" - } - }, - "mcindex_lookup_u7_d2": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:51:47.629929093Z", - "finished_at": "2026-01-27T19:52:29.436282461Z" + "started_at": "2026-01-23T20:14:26.308040547Z", + "finished_at": "2026-01-23T20:14:26.308040547Z" } } } @@ -2288,14 +2179,14 @@ "modes": [ { "mode": "docs", - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_000_empty_reducers", "lang": "csharp", "golden_published": true, @@ -2318,18 +2209,18 @@ "llm_db": "basics-t-000-empty-reducers-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:59:45.341740044Z", - "finished_at": "2026-01-27T20:00:17.110354447Z" + "started_at": "2026-01-23T20:20:05.908071Z", + "finished_at": "2026-01-23T20:21:02.544054377Z" }, "t_001_basic_tables": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_001_basic_tables", "lang": "csharp", "golden_published": true, @@ -2352,25 +2243,25 @@ "llm_db": "basics-t-001-basic-tables-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T20:00:10.594319009Z", - "finished_at": "2026-01-27T20:00:39.454473930Z" + "started_at": "2026-01-23T20:20:17.520008030Z", + "finished_at": "2026-01-23T20:21:03.652127542Z" }, "t_002_scheduled_table": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_002_scheduled_table", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n foreach (var row in ctx.Db.TickTimer.Iter())\n {\n ctx.Db.TickTimer.ScheduledId.Delete(row.ScheduledId);\n }\n\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledId = 0,\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n // Tick scheduled reducer. Intentionally left blank.\n }\n}", + "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey, SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer timer)\n {\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -2386,18 +2277,18 @@ "llm_db": "basics-t-002-scheduled-table-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T20:00:39.454500245Z", - "finished_at": "2026-01-27T20:01:19.695962602Z" + "started_at": "2026-01-23T20:21:05.396968262Z", + "finished_at": "2026-01-23T20:21:59.590160864Z" }, "t_003_struct_in_table": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_003_struct_in_table", "lang": "csharp", "golden_published": true, @@ -2420,18 +2311,18 @@ "llm_db": "basics-t-003-struct-in-table-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T20:00:06.267861248Z", - "finished_at": "2026-01-27T20:00:37.823969244Z" + "started_at": "2026-01-23T20:20:12.029574819Z", + "finished_at": "2026-01-23T20:20:58.944028610Z" }, "t_004_insert": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_004_insert", "lang": "csharp", "golden_published": true, @@ -2446,19 +2337,6 @@ "work_dir_golden": "target/llm-runs/basics/t_004_insert/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_004_insert/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-004-insert-golden", - "llm_db": "basics-t-004-insert-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true - } - }, "data_parity_insert_user": { "pass": true, "partial": 1.0, @@ -2475,23 +2353,36 @@ "llm_out": "Id | Name | Age | Active ----+---------+-----+-------- 1 | \"Alice\" | 30 | true", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "InsertUser", - "server": "http://127.0.0.1:34379" + "server": "http://127.0.0.1:41045" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-004-insert-golden", + "llm_db": "basics-t-004-insert-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T20:00:17.336276015Z", - "finished_at": "2026-01-27T20:00:48.236577365Z" + "started_at": "2026-01-23T20:21:02.544101204Z", + "finished_at": "2026-01-23T20:21:46.575966420Z" }, "t_005_update": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_005_update", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void UpdateUser(ReducerContext ctx, int id, string name, int age, bool active)\n {\n var user = ctx.Db.User.Id.Find(id) ?? throw new System.Exception(\"User not found\");\n user.Name = name;\n user.Age = age;\n user.Active = active;\n user.Id = id;\n ctx.Db.User.Id.Update(user);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void UpdateUser(ReducerContext ctx, int id, string name, int age, bool active)\n {\n ctx.Db.User.Id.Update(new User\n {\n Id = id,\n Name = name,\n Age = age,\n Active = active\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-005-update-golden", @@ -2499,25 +2390,6 @@ "work_dir_golden": "target/llm-runs/basics/t_005_update/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_005_update/csharp/server/gpt-5/llm", "scorer_details": { - "data_parity_update_user": { - "pass": true, - "partial": 1.0, - "notes": { - "args": [ - 1, - "Alice2", - 31, - false - ], - "golden_db": "basics-t-005-update-golden", - "golden_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", - "llm_db": "basics-t-005-update-gpt-5-llm", - "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", - "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", - "reducer": "UpdateUser", - "server": "http://127.0.0.1:34379" - } - }, "seed_users_row": { "pass": true, "partial": 1.0, @@ -2533,25 +2405,44 @@ "llm_db": "basics-t-005-update-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } + }, + "data_parity_update_user": { + "pass": true, + "partial": 1.0, + "notes": { + "args": [ + 1, + "Alice2", + 31, + false + ], + "golden_db": "basics-t-005-update-golden", + "golden_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", + "llm_db": "basics-t-005-update-gpt-5-llm", + "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", + "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", + "reducer": "UpdateUser", + "server": "http://127.0.0.1:41045" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:59:43.681559749Z", - "finished_at": "2026-01-27T20:00:17.332627669Z" + "started_at": "2026-01-23T20:19:53.867992725Z", + "finished_at": "2026-01-23T20:21:05.391950708Z" }, "t_006_delete": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_006_delete", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void DeleteUser(ReducerContext ctx, int id)\n {\n ctx.Db.User.Id.Delete(id);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void DeleteUser(ReducerContext ctx, int id)\n {\n ctx.Db.User.Id.Delete(id);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-006-delete-golden", @@ -2559,13 +2450,6 @@ "work_dir_golden": "target/llm-runs/basics/t_006_delete/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_006_delete/csharp/server/gpt-5/llm", "scorer_details": { - "seed_users_row": { - "pass": true, - "partial": 1.0, - "notes": { - "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" - } - }, "delete_user_count_zero": { "pass": true, "partial": 1.0, @@ -2583,25 +2467,32 @@ "llm_db": "basics-t-006-delete-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } + }, + "seed_users_row": { + "pass": true, + "partial": 1.0, + "notes": { + "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:58:58.264033858Z", - "finished_at": "2026-01-27T19:59:39.007925686Z" + "started_at": "2026-01-23T20:19:10.793697386Z", + "finished_at": "2026-01-23T20:19:53.867926470Z" }, "t_007_crud": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_007_crud", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void Crud(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n\n var found = ctx.Db.User.Id.Find(1);\n if (found is User user)\n {\n user.Name = \"Alice2\";\n user.Age = 31;\n user.Active = false;\n ctx.Db.User.Id.Update(user);\n }\n\n ctx.Db.User.Id.Delete(2);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void Crud(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n\n var found = ctx.Db.User.Id.Find(1);\n if (found is User user1)\n {\n user1.Name = \"Alice2\";\n user1.Age = 31;\n user1.Active = false;\n ctx.Db.User.Id.Update(user1);\n }\n\n ctx.Db.User.Id.Delete(2);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -2609,6 +2500,24 @@ "work_dir_golden": "target/llm-runs/basics/t_007_crud/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_007_crud/csharp/server/gpt-5/llm", "scorer_details": { + "crud_total_count_one": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM User" + } + }, + "crud_row_id2_deleted": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2617,7 +2526,7 @@ "llm_db": "basics-t-007-crud-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } @@ -2651,23 +2560,23 @@ "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "Crud", - "server": "http://127.0.0.1:34379" + "server": "http://127.0.0.1:41045" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:59:29.414134061Z", - "finished_at": "2026-01-27T20:00:06.267814536Z" + "started_at": "2026-01-23T20:19:29.508011285Z", + "finished_at": "2026-01-23T20:20:17.519940667Z" }, "t_008_index_lookup": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_008_index_lookup", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial class User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial class Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void LookupUserName(ReducerContext ctx, int id)\n {\n var user = ctx.Db.User.Id.Find(id);\n if (user != null)\n {\n ctx.Db.Result.Insert(new Result { Id = user.Id, Name = user.Name });\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial class User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name = \"\";\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial class Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name = \"\";\n }\n\n [SpacetimeDB.Reducer]\n public static void LookupUserName(ReducerContext ctx, int id)\n {\n if (ctx.Db.User.Id.Find(id) is User u)\n {\n ctx.Db.Result.Insert(new Result { Id = u.Id, Name = u.Name });\n }\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -2675,22 +2584,6 @@ "work_dir_golden": "target/llm-runs/basics/t_008_index_lookup/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_008_index_lookup/csharp/server/gpt-5/llm", "scorer_details": { - "index_lookup_projection_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "args": [ - 1 - ], - "golden_db": "basics-t-008-index-lookup-golden", - "golden_out": "Id | Name ----+--------- 1 | \"Alice\"", - "llm_db": "basics-t-008-index-lookup-gpt-5-llm", - "llm_out": "Id | Name ----+--------- 1 | \"Alice\"", - "query": "SELECT Id, Name FROM Result WHERE Id=1", - "reducer": "LookupUserName", - "server": "http://127.0.0.1:34379" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2699,7 +2592,7 @@ "llm_db": "basics-t-008-index-lookup-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } @@ -2710,21 +2603,37 @@ "notes": { "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" } + }, + "index_lookup_projection_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "args": [ + 1 + ], + "golden_db": "basics-t-008-index-lookup-golden", + "golden_out": "Id | Name ----+--------- 1 | \"Alice\"", + "llm_db": "basics-t-008-index-lookup-gpt-5-llm", + "llm_out": "Id | Name ----+--------- 1 | \"Alice\"", + "query": "SELECT Id, Name FROM Result WHERE Id=1", + "reducer": "LookupUserName", + "server": "http://127.0.0.1:41045" + } } }, "vendor": "openai", - "started_at": "2026-01-27T20:00:17.332669093Z", - "finished_at": "2026-01-27T20:00:55.597420674Z" + "started_at": "2026-01-23T20:20:58.944081428Z", + "finished_at": "2026-01-23T20:21:57.704447793Z" }, "t_009_init": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_009_init", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer(SpacetimeDB.ReducerKind.Init)]\n public static void Init(SpacetimeDB.ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -2732,17 +2641,13 @@ "work_dir_golden": "target/llm-runs/basics/t_009_init/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_009_init/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { + "init_total_two": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "basics-t-009-init-golden", - "llm_db": "basics-t-009-init-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true + "actual": 2, + "expected": 2, + "sql": "SELECT COUNT(*) AS n FROM User" } }, "init_seed_bob": { @@ -2763,22 +2668,26 @@ "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1 AND Name='Alice' AND Age=30 AND Active=true" } }, - "init_total_two": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 2, - "expected": 2, - "sql": "SELECT COUNT(*) AS n FROM User" + "golden_db": "basics-t-009-init-golden", + "llm_db": "basics-t-009-init-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:59:39.007990909Z", - "finished_at": "2026-01-27T20:00:10.594272918Z" + "started_at": "2026-01-23T20:19:36.893890047Z", + "finished_at": "2026-01-23T20:20:12.029514649Z" }, "t_010_connect": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_010_connect", "lang": "csharp", "golden_published": true, @@ -2801,25 +2710,25 @@ "llm_db": "basics-t-010-connect-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:59:08.068058110Z", - "finished_at": "2026-01-27T19:59:45.341706421Z" + "started_at": "2026-01-23T20:19:23.574032624Z", + "finished_at": "2026-01-23T20:20:05.908027898Z" }, "t_011_helper_function": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_011_helper_function", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int Sum;\n }\n\n public static int Add(int a, int b)\n {\n return a + b;\n }\n\n [SpacetimeDB.Reducer]\n public static void ComputeSum(ReducerContext ctx, int id, int a, int b)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Sum = Add(a, b),\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int Sum;\n }\n\n public static int Add(int a, int b)\n {\n return a + b;\n }\n\n [SpacetimeDB.Reducer]\n public static void ComputeSum(ReducerContext ctx, int id, int a, int b)\n {\n ctx.Db.Result.Insert(new Result { Id = id, Sum = Add(a, b) });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -2836,6 +2745,19 @@ "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1 AND Sum=5" } }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-011-helper-function-golden", + "llm_db": "basics-t-011-helper-function-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true + } + }, "helper_func_sum_parity": { "pass": true, "partial": 1.0, @@ -2851,29 +2773,16 @@ "llm_out": "Id | Sum ----+----- 1 | 5", "query": "SELECT Id, Sum FROM Result WHERE Id=1", "reducer": "ComputeSum", - "server": "http://127.0.0.1:34379" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-011-helper-function-golden", - "llm_db": "basics-t-011-helper-function-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:41045" } } }, "vendor": "openai", - "started_at": "2026-01-27T20:00:37.824007777Z", - "finished_at": "2026-01-27T20:01:12.698364118Z" + "started_at": "2026-01-23T20:21:05.392014348Z", + "finished_at": "2026-01-23T20:21:51.189712882Z" }, "t_012_spacetime_product_type": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_012_spacetime_product_type", "lang": "csharp", "golden_published": true, @@ -2888,6 +2797,19 @@ "work_dir_golden": "target/llm-runs/schema/t_012_spacetime_product_type/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_012_spacetime_product_type/csharp/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-012-spacetime-product-type-golden", + "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true + } + }, "product_type_row_parity": { "pass": true, "partial": 1.0, @@ -2903,20 +2825,7 @@ "llm_out": "Id | Value ----+----------------------- 1 | (Left = 2, Right = 3)", "query": "SELECT Id, Value FROM Result WHERE Id=1", "reducer": "SetScore", - "server": "http://127.0.0.1:34379" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-012-spacetime-product-type-golden", - "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:41045" } }, "product_type_row_count": { @@ -2930,18 +2839,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:58:50.225754898Z", - "finished_at": "2026-01-27T19:59:29.413988946Z" + "started_at": "2026-01-23T20:18:54.161733902Z", + "finished_at": "2026-01-23T20:19:36.893826573Z" }, "t_013_spacetime_sum_type": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_013_spacetime_sum_type", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetCircle(ReducerContext ctx, int id, int radius)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = new Shape.Circle(new Circle { Radius = radius })\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetCircle(ReducerContext ctx, int id, int radius)\n {\n var value = new Shape.Circle(new Circle { Radius = radius });\n ctx.Db.Result.Insert(new Result { Id = id, Value = value });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-013-spacetime-sum-type-golden", @@ -2985,16 +2894,38 @@ "llm_out": "Id | Value ----+-------------------------- 1 | (Circle = (Radius = 10))", "query": "SELECT Id, Value FROM Result WHERE Id=1", "reducer": "SetCircle", - "server": "http://127.0.0.1:34379" + "server": "http://127.0.0.1:41045" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-013-spacetime-sum-type-golden", + "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true + } + }, + "sum_type_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:57:55.737450825Z", - "finished_at": "2026-01-27T19:58:46.370198569Z" + "started_at": "2026-01-23T20:17:49.057528012Z", + "finished_at": "2026-01-23T20:18:46.199910007Z" }, "t_014_elementary_columns": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_014_elementary_columns", "lang": "csharp", "golden_published": true, @@ -3017,7 +2948,7 @@ "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } @@ -3026,7 +2957,7 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c2006db3efe118f9e2be4d0996245799216709f62c09af27307321501d4ca96f/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c200c583183a5879f79de7a06c7395893137fa8a834f830859f2ee7a4c9e10d4/sql)\n", "phase": "sql" } }, @@ -3034,17 +2965,17 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c2008bda321ec5b24f06db6690e57eaa2c1b3a9bada2318accf99feb7910837d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2008dfd963859de34e7ba657c3416cbcee034a702128f54b0cb0b0b03aa914f/sql)\n", "phase": "sql_golden" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:58:46.370277696Z", - "finished_at": "2026-01-27T19:59:43.681502253Z" + "started_at": "2026-01-23T20:18:46.199983893Z", + "finished_at": "2026-01-23T20:19:29.507804243Z" }, "t_015_product_type_columns": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_015_product_type_columns", "lang": "csharp", "golden_published": true, @@ -3059,17 +2990,13 @@ "work_dir_golden": "target/llm-runs/schema/t_015_product_type_columns/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_015_product_type_columns/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { + "product_type_columns_row_count": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "schema-t-015-product-type-columns-golden", - "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Profile WHERE Id=1" } }, "product_type_columns_row_parity": { @@ -3083,25 +3010,29 @@ "llm_out": "Id | Home | Work | Pos ----+----------------------------------+-----------------------------------+---------------- 1 | (Street = \"1 Main\", Zip = 11111) | (Street = \"2 Broad\", Zip = 22222) | (X = 7, Y = 9)", "query": "SELECT Id, Home, Work, Pos FROM Profile WHERE Id=1", "reducer": "Seed", - "server": "http://127.0.0.1:34379" + "server": "http://127.0.0.1:41045" } }, - "product_type_columns_row_count": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Profile WHERE Id=1" + "golden_db": "schema-t-015-product-type-columns-golden", + "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-27T19:58:04.285909374Z", - "finished_at": "2026-01-27T19:58:50.225511855Z" + "started_at": "2026-01-23T20:18:11.292039093Z", + "finished_at": "2026-01-23T20:18:54.161647622Z" }, "t_016_sum_type_columns": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_016_sum_type_columns", "lang": "csharp", "golden_published": true, @@ -3120,7 +3051,7 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c200a38bd5eaec739ca1bb5f49423cf455fb484e997f330a37dbe10a2f09faac/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c200b1fbaa5b44721798298318bab63a7fcd80d50f6e47060d881bfa066b8642/sql)\n", "phase": "sql" } }, @@ -3132,7 +3063,7 @@ "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } @@ -3141,24 +3072,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20028da21a53491f84d8895dbcf4906c6c844846426c39ae32b5fd1689a2641/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2003b0da13c17c6220fd590cdb5d23015a0e698b01b6c6ecbfd10b5aabbbf4c/sql)\n", "phase": "sql_golden" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:57:09.422528630Z", - "finished_at": "2026-01-27T19:58:04.281919840Z" + "started_at": "2026-01-23T20:16:40.802337426Z", + "finished_at": "2026-01-23T20:18:08.899029179Z" }, "t_017_scheduled_columns": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_017_scheduled_columns", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 2, "passed_tests": 1, - "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n}", + "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [PrimaryKey, AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [Reducer]\n public static void Tick(ReducerContext ctx, TickTimer timer)\n {\n // Scheduled tick handler (no-op)\n }\n\n [Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n if (ctx.Db.TickTimer.Count == 0)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -3166,14 +3097,6 @@ "work_dir_golden": "target/llm-runs/schema/t_017_scheduled_columns/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_017_scheduled_columns/csharp/server/gpt-5/llm", "scorer_details": { - "scheduled_seeded_one_row": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `tick_timer`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c200bf2221f01a62dfa1acb5a397b4271a57cfc2f171562204bb3bcee2259214/sql)\n", - "phase": "sql" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -3182,18 +3105,26 @@ "llm_db": "schema-t-017-scheduled-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } + }, + "scheduled_seeded_one_row": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `tick_timer`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2000932373ef07be1f77db87f24b98a9819f6033c40da69c914e654c807ead2/sql)\n", + "phase": "sql" + } } }, "vendor": "openai", - "started_at": "2026-01-27T19:57:09.413847953Z", - "finished_at": "2026-01-27T19:57:55.737395054Z" + "started_at": "2026-01-23T20:16:40.797164170Z", + "finished_at": "2026-01-23T20:18:08.735264338Z" }, "t_018_constraints": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_018_constraints", "lang": "csharp", "golden_published": true, @@ -3208,6 +3139,19 @@ "work_dir_golden": "target/llm-runs/schema/t_018_constraints/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_018_constraints/csharp/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-018-constraints-golden", + "llm_db": "schema-t-018-constraints-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true + } + }, "constraints_row_parity_after_seed": { "pass": true, "partial": 1.0, @@ -3219,7 +3163,7 @@ "llm_out": "Id | Email | Name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", "query": "SELECT Id, Email, Name FROM Account WHERE Id=1", "reducer": "Seed", - "server": "http://127.0.0.1:34379" + "server": "http://127.0.0.1:41045" } }, "constraints_seed_two_rows": { @@ -3246,18 +3190,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:57:09.410769526Z", - "finished_at": "2026-01-27T19:58:03.584746288Z" + "started_at": "2026-01-23T20:16:40.794071431Z", + "finished_at": "2026-01-23T20:18:11.291994106Z" }, "t_019_many_to_many": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_019_many_to_many", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 5, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int UserId;\n public string Name;\n }\n\n [SpacetimeDB.Table(Name = \"Group\")]\n public partial struct Group\n {\n [SpacetimeDB.PrimaryKey]\n public int GroupId;\n public string Title;\n }\n\n [SpacetimeDB.Table(Name = \"Membership\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user\", Columns = new[] { \"UserId\" })]\n [SpacetimeDB.Index.BTree(Name = \"by_group\", Columns = new[] { \"GroupId\" })]\n public partial struct Membership\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int GroupId;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n foreach (var m in ctx.Db.Membership.Iter())\n {\n ctx.Db.Membership.Id.Delete(m.Id);\n }\n\n foreach (var g in ctx.Db.Group.Iter())\n {\n ctx.Db.Group.GroupId.Delete(g.GroupId);\n }\n\n foreach (var u in ctx.Db.User.Iter())\n {\n ctx.Db.User.UserId.Delete(u.UserId);\n }\n\n ctx.Db.User.Insert(new User { UserId = 1, Name = \"Alice\" });\n ctx.Db.User.Insert(new User { UserId = 2, Name = \"Bob\" });\n\n ctx.Db.Group.Insert(new Group { GroupId = 10, Title = \"Admin\" });\n ctx.Db.Group.Insert(new Group { GroupId = 20, Title = \"Dev\" });\n\n ctx.Db.Membership.Insert(new Membership { Id = 1, UserId = 1, GroupId = 10 });\n ctx.Db.Membership.Insert(new Membership { Id = 2, UserId = 1, GroupId = 20 });\n ctx.Db.Membership.Insert(new Membership { Id = 3, UserId = 2, GroupId = 20 });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int UserId;\n public string Name;\n }\n\n [SpacetimeDB.Table(Name = \"Group\")]\n public partial struct Group\n {\n [SpacetimeDB.PrimaryKey]\n public int GroupId;\n public string Title;\n }\n\n [SpacetimeDB.Table(Name = \"Membership\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user\", Columns = new[] { \"UserId\" })]\n [SpacetimeDB.Index.BTree(Name = \"by_group\", Columns = new[] { \"GroupId\" })]\n public partial struct Membership\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int GroupId;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n foreach (var m in ctx.Db.Membership.Iter())\n {\n ctx.Db.Membership.Id.Delete(m.Id);\n }\n foreach (var u in ctx.Db.User.Iter())\n {\n ctx.Db.User.UserId.Delete(u.UserId);\n }\n foreach (var g in ctx.Db.Group.Iter())\n {\n ctx.Db.Group.GroupId.Delete(g.GroupId);\n }\n\n ctx.Db.User.Insert(new User { UserId = 1, Name = \"Alice\" });\n ctx.Db.User.Insert(new User { UserId = 2, Name = \"Bob\" });\n\n ctx.Db.Group.Insert(new Group { GroupId = 10, Title = \"Admin\" });\n ctx.Db.Group.Insert(new Group { GroupId = 20, Title = \"Dev\" });\n\n ctx.Db.Membership.Insert(new Membership { Id = 1, UserId = 1, GroupId = 10 });\n ctx.Db.Membership.Insert(new Membership { Id = 2, UserId = 1, GroupId = 20 });\n ctx.Db.Membership.Insert(new Membership { Id = 3, UserId = 2, GroupId = 20 });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-019-many-to-many-golden", @@ -3265,6 +3209,19 @@ "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/csharp/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-019-many-to-many-golden", + "llm_db": "schema-t-019-many-to-many-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true + } + }, "m2m_has_2_20": { "pass": true, "partial": 1.0, @@ -3283,19 +3240,6 @@ "sql": "SELECT COUNT(*) AS n FROM Membership" } }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-019-many-to-many-golden", - "llm_db": "schema-t-019-many-to-many-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true - } - }, "m2m_has_1_20": { "pass": true, "partial": 1.0, @@ -3316,18 +3260,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-27T19:58:04.046511986Z", - "finished_at": "2026-01-27T19:58:58.263921552Z" + "started_at": "2026-01-23T20:18:08.899074821Z", + "finished_at": "2026-01-23T20:19:10.793593915Z" }, "t_020_ecs": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_020_ecs", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Entity\")]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n }\n\n [SpacetimeDB.Table(Name = \"Position\")]\n public partial struct Position\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Velocity\")]\n public partial struct Velocity\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int VX;\n public int VY;\n }\n\n [SpacetimeDB.Table(Name = \"NextPosition\")]\n public partial struct NextPosition\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n // Entities\n ctx.Db.Entity.Insert(new Entity { Id = 1 });\n ctx.Db.Entity.Insert(new Entity { Id = 2 });\n\n // Positions\n ctx.Db.Position.Insert(new Position { EntityId = 1, X = 0, Y = 0 });\n ctx.Db.Position.Insert(new Position { EntityId = 2, X = 10, Y = 0 });\n\n // Velocities\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 1, VX = 1, VY = 0 });\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 2, VX = -2, VY = 3 });\n }\n\n [SpacetimeDB.Reducer]\n public static void Step(ReducerContext ctx)\n {\n foreach (var pos in ctx.Db.Position.Iter())\n {\n var vel = ctx.Db.Velocity.EntityId.Find(pos.EntityId);\n int vx = 0, vy = 0;\n if (vel != null)\n {\n vx = vel.Value.VX;\n vy = vel.Value.VY;\n }\n\n var next = new NextPosition\n {\n EntityId = pos.EntityId,\n X = pos.X + vx,\n Y = pos.Y + vy\n };\n\n var existing = ctx.Db.NextPosition.EntityId.Find(pos.EntityId);\n if (existing != null)\n {\n ctx.Db.NextPosition.EntityId.Update(next);\n }\n else\n {\n ctx.Db.NextPosition.Insert(next);\n }\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Entity\", Public = true)]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n }\n\n [SpacetimeDB.Table(Name = \"Position\", Public = true)]\n public partial struct Position\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Velocity\", Public = true)]\n public partial struct Velocity\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int VX;\n public int VY;\n }\n\n [SpacetimeDB.Table(Name = \"NextPosition\", Public = true)]\n public partial struct NextPosition\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n // Entity 1\n if (ctx.Db.Entity.Id.Find(1) is not Entity)\n {\n ctx.Db.Entity.Insert(new Entity { Id = 1 });\n }\n if (ctx.Db.Position.EntityId.Find(1) is Position p1)\n {\n p1.X = 0;\n p1.Y = 0;\n ctx.Db.Position.EntityId.Update(p1);\n }\n else\n {\n ctx.Db.Position.Insert(new Position { EntityId = 1, X = 0, Y = 0 });\n }\n if (ctx.Db.Velocity.EntityId.Find(1) is Velocity v1)\n {\n v1.VX = 1;\n v1.VY = 0;\n ctx.Db.Velocity.EntityId.Update(v1);\n }\n else\n {\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 1, VX = 1, VY = 0 });\n }\n\n // Entity 2\n if (ctx.Db.Entity.Id.Find(2) is not Entity)\n {\n ctx.Db.Entity.Insert(new Entity { Id = 2 });\n }\n if (ctx.Db.Position.EntityId.Find(2) is Position p2)\n {\n p2.X = 10;\n p2.Y = 0;\n ctx.Db.Position.EntityId.Update(p2);\n }\n else\n {\n ctx.Db.Position.Insert(new Position { EntityId = 2, X = 10, Y = 0 });\n }\n if (ctx.Db.Velocity.EntityId.Find(2) is Velocity v2)\n {\n v2.VX = -2;\n v2.VY = 3;\n ctx.Db.Velocity.EntityId.Update(v2);\n }\n else\n {\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 2, VX = -2, VY = 3 });\n }\n }\n\n [SpacetimeDB.Reducer]\n public static void Step(ReducerContext ctx)\n {\n foreach (var pos in ctx.Db.Position.Iter())\n {\n var vOpt = ctx.Db.Velocity.EntityId.Find(pos.EntityId);\n if (vOpt is Velocity vel)\n {\n int nx = pos.X + vel.VX;\n int ny = pos.Y + vel.VY;\n\n var npOpt = ctx.Db.NextPosition.EntityId.Find(pos.EntityId);\n if (npOpt is NextPosition np)\n {\n np.X = nx;\n np.Y = ny;\n ctx.Db.NextPosition.EntityId.Update(np);\n }\n else\n {\n ctx.Db.NextPosition.Insert(new NextPosition\n {\n EntityId = pos.EntityId,\n X = nx,\n Y = ny\n });\n }\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-020-ecs-golden", @@ -3335,19 +3279,19 @@ "work_dir_golden": "target/llm-runs/schema/t_020_ecs/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_020_ecs/csharp/server/gpt-5/llm", "scorer_details": { - "ecs_step_next_positions_count": { + "ecs_next_pos_entity1": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", "phase": "sql" } }, - "ecs_next_pos_entity1": { + "ecs_seed_positions_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", "phase": "sql" } }, @@ -3355,7 +3299,15 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", + "phase": "sql" + } + }, + "ecs_step_next_positions_count": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", "phase": "sql" } }, @@ -3367,33 +3319,25 @@ "llm_db": "schema-t-020-ecs-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:34379", + "server": "http://127.0.0.1:41045", "tables_diff": null, "tables_equal": true } - }, - "ecs_seed_positions_count": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", - "phase": "sql" - } } }, "vendor": "openai", - "started_at": "2026-01-27T19:58:04.281975972Z", - "finished_at": "2026-01-27T19:59:08.067949434Z" + "started_at": "2026-01-23T20:18:08.902649901Z", + "finished_at": "2026-01-23T20:19:23.573927579Z" }, "t_021_multi_column_index": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "task": "t_021_multi_column_index", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Log\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user_day\", Columns = new[] { \"UserId\", \"Day\" })]\n public partial struct Log\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int Day;\n public string Message;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Log.Insert(new Log { Id = 1, UserId = 7, Day = 1, Message = \"a\" });\n ctx.Db.Log.Insert(new Log { Id = 2, UserId = 7, Day = 2, Message = \"b\" });\n ctx.Db.Log.Insert(new Log { Id = 3, UserId = 9, Day = 1, Message = \"c\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Log\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user_day\", Columns = [\"UserId\", \"Day\"])]\n public partial struct Log\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int Day;\n public string Message;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Log.Insert(new Log { Id = 1, UserId = 7, Day = 1, Message = \"a\" });\n ctx.Db.Log.Insert(new Log { Id = 2, UserId = 7, Day = 2, Message = \"b\" });\n ctx.Db.Log.Insert(new Log { Id = 3, UserId = 9, Day = 1, Message = \"c\" });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-021-multi-column-index-golden", @@ -3401,22 +3345,26 @@ "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/csharp/server/gpt-5/llm", "scorer_details": { - "mcindex_lookup_u7_d2": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2" + "golden_db": "schema-t-021-multi-column-index-golden", + "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:41045", + "tables_diff": null, + "tables_equal": true } }, - "mcindex_seed_count": { + "mcindex_lookup_u7_d2": { "pass": true, "partial": 1.0, "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM Log" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2" } }, "mcindex_lookup_u7_d1": { @@ -3428,23 +3376,19 @@ "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=1" } }, - "schema_parity": { + "mcindex_seed_count": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "schema-t-021-multi-column-index-golden", - "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM Log" } } }, "vendor": "openai", - "started_at": "2026-01-27T19:57:09.418092225Z", - "finished_at": "2026-01-27T19:58:04.046455117Z" + "started_at": "2026-01-23T20:16:40.799865241Z", + "finished_at": "2026-01-23T20:17:49.057471707Z" } } } diff --git a/docs/llms/docs-benchmark-summary.json b/docs/llms/docs-benchmark-summary.json index bf684185512..8e7f8400b57 100644 --- a/docs/llms/docs-benchmark-summary.json +++ b/docs/llms/docs-benchmark-summary.json @@ -1,11 +1,11 @@ { "version": 1, - "generated_at": "2026-01-27T20:01:19.767Z", + "generated_at": "2026-01-23T20:21:59.670Z", "by_language": { "csharp": { "modes": { "docs": { - "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", + "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", "models": { "GPT-5": { "categories": { @@ -42,7 +42,7 @@ "rust": { "modes": { "docs": { - "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", + "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", "models": { "GPT-5": { "categories": { @@ -56,53 +56,53 @@ }, "schema": { "tasks": 10, - "total_tests": 32, - "passed_tests": 8, - "pass_pct": 25.0, - "task_pass_equiv": 2.05, - "task_pass_pct": 20.5 + "total_tests": 14, + "passed_tests": 0, + "pass_pct": 0.0, + "task_pass_equiv": 0.0, + "task_pass_pct": 0.0 } }, "totals": { "tasks": 22, - "total_tests": 59, - "passed_tests": 13, - "pass_pct": 22.033897, - "task_pass_equiv": 3.3833334, - "task_pass_pct": 15.378788 + "total_tests": 41, + "passed_tests": 5, + "pass_pct": 12.195122, + "task_pass_equiv": 1.3333334, + "task_pass_pct": 6.060606 } } } }, "rustdoc_json": { - "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", + "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "models": { "GPT-5": { "categories": { "basics": { "tasks": 12, "total_tests": 27, - "passed_tests": 26, - "pass_pct": 96.296295, - "task_pass_equiv": 11.0, - "task_pass_pct": 91.66667 + "passed_tests": 25, + "pass_pct": 92.59259, + "task_pass_equiv": 10.0, + "task_pass_pct": 83.33333 }, "schema": { "tasks": 10, "total_tests": 34, - "passed_tests": 23, - "pass_pct": 67.64706, - "task_pass_equiv": 6.5333333, - "task_pass_pct": 65.33333 + "passed_tests": 26, + "pass_pct": 76.47059, + "task_pass_equiv": 7.5333333, + "task_pass_pct": 75.333336 } }, "totals": { "tasks": 22, "total_tests": 61, - "passed_tests": 49, - "pass_pct": 80.327866, - "task_pass_equiv": 17.533335, - "task_pass_pct": 79.696976 + "passed_tests": 51, + "pass_pct": 83.60656, + "task_pass_equiv": 17.533333, + "task_pass_pct": 79.69697 } } } diff --git a/modules/module-test/src/lib.rs b/modules/module-test/src/lib.rs index a5b59720cfd..433796e5b60 100644 --- a/modules/module-test/src/lib.rs +++ b/modules/module-test/src/lib.rs @@ -206,7 +206,7 @@ impl Foo<'_> { #[spacetimedb::view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } // ───────────────────────────────────────────────────────────────────────────── @@ -267,7 +267,7 @@ fn log_module_identity(ctx: &ReducerContext) { #[spacetimedb::reducer] pub fn test(ctx: &ReducerContext, arg: TestAlias, arg2: TestB, arg3: TestC, arg4: TestF) -> anyhow::Result<()> { log::info!("BEGIN"); - log::info!("sender: {:?}", ctx.sender); + log::info!("sender: {:?}", ctx.sender()); log::info!("timestamp: {:?}", ctx.timestamp); log::info!("bar: {:?}", arg2.foo); @@ -468,7 +468,7 @@ fn test_btree_index_args(ctx: &ReducerContext) { #[spacetimedb::reducer] fn assert_caller_identity_is_module_identity(ctx: &ReducerContext) { - let caller = ctx.sender; + let caller = ctx.sender(); let owner = ctx.identity(); if caller != owner { panic!("Caller {caller} is not the owner {owner}"); diff --git a/modules/sdk-test-connect-disconnect/src/lib.rs b/modules/sdk-test-connect-disconnect/src/lib.rs index c89b7af1f3c..4a733969c01 100644 --- a/modules/sdk-test-connect-disconnect/src/lib.rs +++ b/modules/sdk-test-connect-disconnect/src/lib.rs @@ -22,10 +22,10 @@ pub struct Disconnected { #[spacetimedb::reducer(client_connected)] pub fn identity_connected(ctx: &ReducerContext) { - ctx.db.connected().insert(Connected { identity: ctx.sender }); + ctx.db.connected().insert(Connected { identity: ctx.sender() }); } #[spacetimedb::reducer(client_disconnected)] pub fn identity_disconnected(ctx: &ReducerContext) { - ctx.db.disconnected().insert(Disconnected { identity: ctx.sender }); + ctx.db.disconnected().insert(Disconnected { identity: ctx.sender() }); } diff --git a/modules/sdk-test-view/src/lib.rs b/modules/sdk-test-view/src/lib.rs index 10b99a030e1..e00f64bdccc 100644 --- a/modules/sdk-test-view/src/lib.rs +++ b/modules/sdk-test-view/src/lib.rs @@ -52,10 +52,10 @@ fn delete_player(ctx: &ReducerContext, identity: Identity) { #[reducer] pub fn move_player(ctx: &ReducerContext, dx: i32, dy: i32) { - let my_player = ctx.db.player().identity().find(ctx.sender).unwrap_or_else(|| { + let my_player = ctx.db.player().identity().find(ctx.sender()).unwrap_or_else(|| { ctx.db.player().insert(Player { entity_id: 0, - identity: ctx.sender, + identity: ctx.sender(), }) }); match ctx.db.player_location().entity_id().find(my_player.entity_id) { @@ -82,7 +82,7 @@ pub fn move_player(ctx: &ReducerContext, dx: i32, dy: i32) { #[view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } #[view(name = my_player_and_level, public)] @@ -90,7 +90,7 @@ fn my_player_and_level(ctx: &ViewContext) -> Option { ctx.db .player() .identity() - .find(ctx.sender) + .find(ctx.sender()) .and_then(|Player { entity_id, identity }| { ctx.db .player_level() @@ -119,7 +119,7 @@ pub fn nearby_players(ctx: &ViewContext) -> Vec { ctx.db .player() .identity() - .find(ctx.sender) + .find(ctx.sender()) .and_then(|my_player| ctx.db.player_location().entity_id().find(my_player.entity_id)) .iter() .flat_map(|my_loc| { diff --git a/modules/sdk-test/src/lib.rs b/modules/sdk-test/src/lib.rs index 06778f733d5..0a6aed56358 100644 --- a/modules/sdk-test/src/lib.rs +++ b/modules/sdk-test/src/lib.rs @@ -637,25 +637,27 @@ fn delete_pk_u32_insert_pk_u32_two(ctx: &ReducerContext, n: u32, data: i32) -> a #[spacetimedb::reducer] fn insert_caller_one_identity(ctx: &ReducerContext) -> anyhow::Result<()> { - ctx.db.one_identity().insert(OneIdentity { i: ctx.sender }); + ctx.db.one_identity().insert(OneIdentity { i: ctx.sender() }); Ok(()) } #[spacetimedb::reducer] fn insert_caller_vec_identity(ctx: &ReducerContext) -> anyhow::Result<()> { - ctx.db.vec_identity().insert(VecIdentity { i: vec![ctx.sender] }); + ctx.db.vec_identity().insert(VecIdentity { i: vec![ctx.sender()] }); Ok(()) } #[spacetimedb::reducer] fn insert_caller_unique_identity(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { - ctx.db.unique_identity().insert(UniqueIdentity { i: ctx.sender, data }); + ctx.db + .unique_identity() + .insert(UniqueIdentity { i: ctx.sender(), data }); Ok(()) } #[spacetimedb::reducer] fn insert_caller_pk_identity(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { - ctx.db.pk_identity().insert(PkIdentity { i: ctx.sender, data }); + ctx.db.pk_identity().insert(PkIdentity { i: ctx.sender(), data }); Ok(()) } diff --git a/smoketests/tests/rls.py b/smoketests/tests/rls.py index 264f373c479..102c3378a9e 100644 --- a/smoketests/tests/rls.py +++ b/smoketests/tests/rls.py @@ -19,7 +19,7 @@ class Rls(Smoketest): #[spacetimedb::reducer] pub fn add_user(ctx: &ReducerContext, name: String) { - ctx.db.users().insert(Users { name, identity: ctx.sender }); + ctx.db.users().insert(Users { name, identity: ctx.sender() }); } """ @@ -88,7 +88,7 @@ class DisconnectRls(Smoketest): #[spacetimedb::reducer] pub fn add_user(ctx: &ReducerContext, name: String) { - ctx.db.users().insert(Users { name, identity: ctx.sender }); + ctx.db.users().insert(Users { name, identity: ctx.sender() }); } """ diff --git a/smoketests/tests/views.py b/smoketests/tests/views.py index e9d264ffbc7..23b29541789 100644 --- a/smoketests/tests/views.py +++ b/smoketests/tests/views.py @@ -609,12 +609,12 @@ class SubscribeViews(Smoketest): #[spacetimedb::view(name = my_player, public)] pub fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player_state().identity().find(ctx.sender) + ctx.db.player_state().identity().find(ctx.sender()) } #[spacetimedb::reducer] pub fn insert_player(ctx: &ReducerContext, name: String) { - ctx.db.player_state().insert(PlayerState { name, identity: ctx.sender }); + ctx.db.player_state().insert(PlayerState { name, identity: ctx.sender() }); } """ diff --git a/smoketests/tests/zz_docker.py b/smoketests/tests/zz_docker.py index 86816383114..bcfdef16a73 100644 --- a/smoketests/tests/zz_docker.py +++ b/smoketests/tests/zz_docker.py @@ -112,14 +112,14 @@ class DockerRestartAutoDisconnect(Smoketest): #[spacetimedb::reducer(client_connected)] fn on_connect(ctx: &ReducerContext) { ctx.db.connected_client().insert(ConnectedClient { - identity: ctx.sender, + identity: ctx.sender(), connection_id: ctx.connection_id.expect("sender connection id unset"), }); } #[spacetimedb::reducer(client_disconnected)] fn on_disconnect(ctx: &ReducerContext) { - let sender_identity = &ctx.sender; + let sender_identity = &ctx.sender(); let sender_connection_id = ctx.connection_id.as_ref().expect("sender connection id unset"); let match_client = |row: &ConnectedClient| { &row.identity == sender_identity && &row.connection_id == sender_connection_id diff --git a/templates/chat-console-rs/spacetimedb/src/lib.rs b/templates/chat-console-rs/spacetimedb/src/lib.rs index de77f34bde2..d00949f5858 100644 --- a/templates/chat-console-rs/spacetimedb/src/lib.rs +++ b/templates/chat-console-rs/spacetimedb/src/lib.rs @@ -26,8 +26,8 @@ fn validate_name(name: String) -> Result { #[spacetimedb::reducer] pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { let name = validate_name(name)?; - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { - log::info!("User {} sets name to {name}", ctx.sender); + if let Some(user) = ctx.db.user().identity().find(ctx.sender()) { + log::info!("User {} sets name to {name}", ctx.sender()); ctx.db.user().identity().update(User { name: Some(name), ..user @@ -52,9 +52,9 @@ pub fn send_message(ctx: &ReducerContext, text: String) -> Result<(), String> { // - Rate-limit messages per-user. // - Reject messages from unnamed user. let text = validate_message(text)?; - log::info!("User {}: {text}", ctx.sender); + log::info!("User {}: {text}", ctx.sender()); ctx.db.message().insert(Message { - sender: ctx.sender, + sender: ctx.sender(), text, sent: ctx.timestamp, }); @@ -67,7 +67,7 @@ pub fn init(_ctx: &ReducerContext) {} #[spacetimedb::reducer(client_connected)] pub fn identity_connected(ctx: &ReducerContext) { - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender()) { // If this is a returning user, i.e. we already have a `User` with this `Identity`, // set `online: true`, but leave `name` and `identity` unchanged. ctx.db.user().identity().update(User { online: true, ..user }); @@ -76,7 +76,7 @@ pub fn identity_connected(ctx: &ReducerContext) { // which is online, but hasn't set a name. ctx.db.user().insert(User { name: None, - identity: ctx.sender, + identity: ctx.sender(), online: true, }); } @@ -84,11 +84,11 @@ pub fn identity_connected(ctx: &ReducerContext) { #[spacetimedb::reducer(client_disconnected)] pub fn identity_disconnected(ctx: &ReducerContext) { - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender()) { ctx.db.user().identity().update(User { online: false, ..user }); } else { // This branch should be unreachable, // as it doesn't make sense for a client to disconnect without connecting first. - log::warn!("Disconnect event for unknown user with identity {:?}", ctx.sender); + log::warn!("Disconnect event for unknown user with identity {:?}", ctx.sender()); } } From 42bdd9832e934b98953c966235e05faaa922c6d3 Mon Sep 17 00:00:00 2001 From: clockwork-labs-bot Date: Mon, 26 Jan 2026 19:42:31 +0000 Subject: [PATCH 2/8] Update LLM benchmark results --- docs/llms/docs-benchmark-analysis.md | 633 +++++------ docs/llms/docs-benchmark-comment.md | 16 +- docs/llms/docs-benchmark-details.json | 1435 ++++++++++++------------- docs/llms/docs-benchmark-summary.json | 62 +- 4 files changed, 1037 insertions(+), 1109 deletions(-) diff --git a/docs/llms/docs-benchmark-analysis.md b/docs/llms/docs-benchmark-analysis.md index fe284ef576a..f2f69378b8e 100644 --- a/docs/llms/docs-benchmark-analysis.md +++ b/docs/llms/docs-benchmark-analysis.md @@ -4,338 +4,312 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do ## Summary -- **Total failures analyzed**: 31 +- **Total failures analyzed**: 33 --- # Analysis of SpacetimeDB Benchmark Test Failures -## Rust / rustdoc_json Failures - -### Compile/Publish Errors (3 Failures) - -#### 1. **t_002_scheduled_table** -- **Generated Code**: - ```rust - #[table(name = tick_timer, schedule(column = scheduled_at, reducer = tick))] - pub struct TickTimer { - #[primary_key] - #[auto_inc] - scheduled_id: u64, - scheduled_at: ScheduleAt, - } - ``` - -- **Golden Example**: - ```rust - #[table(name = tick_timer, scheduled(tick))] - pub struct TickTimer { - #[primary_key] - #[auto_inc] - pub scheduled_id: u64, - pub scheduled_at: ScheduleAt, - } - ``` +This document analyzes the SpacetimeDB benchmark test failures organized by language and mode. Each section addresses specific failures, providing insights into their causes and recommending actionable solutions. -- **Error**: `publish_error: spacetime publish failed (exit=1)` +## Rust / rustdoc_json Failures -- **Explanation**: - The LLM used incorrect syntax for the `scheduled` attribute. It should be `scheduled(tick)` instead of `schedule(column = scheduled_at, reducer = tick)`. +### Compile/Publish Errors + +#### t_002_scheduled_table & t_017_scheduled_columns + +1. **The generated code**: + ```rust + use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt}; + + #[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))] + pub struct TickTimer { + #[primary_key] + #[auto_inc] + scheduled_id: u64, + scheduled_at: ScheduleAt, + } + + #[reducer(init)] + pub fn init(ctx: &ReducerContext) { + ctx.db.tick_timer().insert(TickTimer { + scheduled_id: 0, + scheduled_at: ScheduleAt::repeat_micros(50_000), + }); + } + + #[reducer] + pub fn tick(_ctx: &ReducerContext, _row: TickTimer) { + } + ``` + +2. **The golden example**: + ```rust + use spacetimedb::{reducer, table, ReducerContext, ScheduleAt, Table}; + use std::time::Duration; + + #[table(name = tick_timer, scheduled(tick))] + pub struct TickTimer { + #[primary_key] + #[auto_inc] + pub scheduled_id: u64, + pub scheduled_at: ScheduleAt, + } + + #[reducer] + pub fn tick(_ctx: &ReducerContext, _schedule: TickTimer) { + } + + #[reducer(init)] + pub fn init(ctx: &ReducerContext) { + let every_50ms: ScheduleAt = Duration::from_millis(50).into(); + ctx.db.tick_timer().insert(TickTimer { + scheduled_id: 0, + scheduled_at: every_50ms, + }); + } + ``` + +3. **The error**: + - `publish_error: spacetime publish failed (exit=1)` + +4. **Explain the difference**: + - The LLM generated code uses `ScheduleAt::repeat_micros(50_000)` while the expected code uses `ScheduleAt::Interval(Duration::from_millis(50).into())`. + - The `scheduled` attribute is incorrectly set. + +5. **Root cause**: + - The documentation lacks clear guidance on using the `ScheduleAt` type effectively and the format for specifying scheduled actions. + +6. **Recommendation**: + - Update documentation to clarify how to define timing for scheduled entries, using `ScheduleAt::Interval` instead of `ScheduleAt::repeat_*` methods. -- **Root Cause**: The documentation may not clearly explain the syntax for the `scheduled` attribute. +### Compile/Publish Errors (3 Failures) -- **Recommendation**: Update documentation to emphasize that the `scheduled` attribute must be structured as `scheduled(reducer_name)`. +#### t_003_struct_in_table + +1. **The generated code**: + ```rust + use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType}; + + #[derive(SpacetimeType)] + pub struct Position { + x: i32, + y: i32, + } + + #[table(name = entity)] + pub struct Entity { + #[primary_key] + id: i32, + pos: Position, + } + + #[reducer] + pub fn add_entity(ctx: &ReducerContext, id: i32, x: i32, y: i32) { + ctx.db.entity().insert(Entity { id, pos: Position { x, y } }); + } + ``` + +2. **The golden example**: + ```rust + use spacetimedb::{table, SpacetimeType}; + + #[derive(SpacetimeType, Clone, Debug)] + pub struct Position { + pub x: i32, + pub y: i32, + } + + #[table(name = entity)] + pub struct Entity { + #[primary_key] + pub id: i32, + pub pos: Position, + } + ``` + +3. **The error**: + - `schema_parity: reducers differ - expected [], got ["add_entity()"]` + +4. **Explain the difference**: + - The expected code does not include any reducers, while the generated code has an unnecessary `add_entity` reducer. + +5. **Root cause**: + - Misrepresentation of structural requirements regarding reducers in the schema. + +6. **Recommendation**: + - Update the documentation to clarify when reducers should or should not be defined for schema parity. --- -#### 2. **t_003_struct_in_table** -- **Generated Code**: - ```rust - #[spacetimedb::table(name = entity)] - pub struct Entity { - #[primary_key] - id: i32, - pos: Position, - } - ``` - -- **Golden Example**: - ```rust - #[table(name = entity)] - pub struct Entity { - #[primary_key] - pub id: i32, - pub pos: Position, - } - ``` - -- **Error**: `publish_error: spacetime publish failed (exit=1)` - -- **Explanation**: - The LLM did not use `pub` for struct fields which is required for visibility in SpacetimeDB. - -- **Root Cause**: The visibility rules for struct fields in Rust may need clearer explanation in the documentation. - -- **Recommendation**: Include specific examples indicating that all fields in SpacetimeDB tables should be public. +#### t_018_constraints + +1. **The generated code**: + ```rust + use spacetimedb::{table, reducer, ReducerContext, Table}; + + #[table(name = account, index(name = by_name, btree(columns = [name])))] + pub struct Account { + #[primary_key] + id: i32, + #[unique] + email: String, + name: String, + } + + #[reducer] + pub fn seed(ctx: &ReducerContext) { + let t = ctx.db.account(); + t.insert(Account { id: 1, email: "a@example.com".to_string(), name: "Alice".to_string() }); + t.insert(Account { id: 2, email: "b@example.com".to_string(), name: "Bob".to_string() }); + } + ``` + +2. **The golden example**: + ```rust + use spacetimedb::{reducer, table, ReducerContext, Table}; + + #[table( + name = account, + index(name = by_name, btree(columns = [name])) + )] + pub struct Account { + #[primary_key] + pub id: i32, + #[unique] + pub email: String, + pub name: String, + } + + #[reducer] + pub fn seed(ctx: &ReducerContext) { + ctx.db.account().insert(Account { id: 1, email: "a@example.com".into(), name: "Alice".into() }); + ctx.db.account().insert(Account { id: 2, email: "b@example.com".into(), name: "Bob".into() }); + } + ``` + +3. **The error**: + - `constraints_row_parity_after_seed: spacetime sql failed: no such table: 'account'` + +4. **Explain the difference**: + - The generated code did not include the `pub` keyword in front of fields, which results in private access. + +5. **Root cause**: + - Lack of explicit guidelines on visibility modifiers for database fields and schema definition. + +6. **Recommendation**: + - Update the documentation to emphasize that struct fields in database models must be public. --- -#### 3. **t_017_scheduled_columns** -- **Generated Code**: - ```rust - #[reducer(init)] - pub fn init(ctx: &ReducerContext) { - if ctx.db.tick_timer().count() == 0 { - ctx.db.tick_timer().insert(TickTimer { - scheduled_id: 0, - scheduled_at: ScheduleAt::repeat_micros(50_000), - }); - } - } - ``` - -- **Golden Example**: - ```rust - #[reducer(init)] - pub fn init(ctx: &ReducerContext) { - let every_50ms: ScheduleAt = Duration::from_millis(50).into(); - ctx.db.tick_timer().insert(TickTimer { - scheduled_id: 0, - scheduled_at: every_50ms, - }); - } - ``` - -- **Error**: `publish_error: spacetime publish failed (exit=1)` - -- **Explanation**: The method for initializing `scheduled_at` is incorrect. Instead of using `repeat_micros()`, the code should convert a `Duration` to `ScheduleAt`. - -- **Root Cause**: Misunderstanding of the proper way to initialize scheduled columns could be reflected in lacking documentation details. - -- **Recommendation**: Clarify the documentation regarding initializing `ScheduleAt`, emphasizing conversion from `Duration`. - ---- - -### Other Failures (2 Failures) - -#### 4. **t_016_sum_type_columns** -- **Generated Code**: - ```rust - #[spacetimedb::table(name = drawing)] - pub struct Drawing { - #[primary_key] - id: i32, - a: Shape, - b: Shape, - } - ``` - -- **Golden Example**: - ```rust - #[table(name = drawing)] - pub struct Drawing { - #[primary_key] - pub id: i32, - pub a: Shape, - pub b: Shape, - } - ``` - -- **Error**: Errors regarding tables not found. - -- **Explanation**: Missing the `pub` attribute on struct fields results in failure to compile. - -- **Root Cause**: Lack of clarity on the use of visibility attributes (`pub`) in struct definitions. - -- **Recommendation**: Revise documentation to instruct that fields must be public to work within SpacetimeDB. - ---- - -#### 5. **t_020_ecs** -- **Generated Code**: - ```rust - #[spacetimedb::table(name = entity)] - pub struct Entity { - #[primary_key] - id: i32, - } - - #[spacetimedb::table(name = position)] - pub struct Position { - #[primary_key] - entity_id: i32, - x: i32, - y: i32, - } - ``` - -- **Golden Example**: - ```rust - #[table(name = entity)] - pub struct Entity { - #[primary_key] - pub id: i32, - } - - #[table(name = position)] - pub struct Position { - #[primary_key] - pub entity_id: i32, - pub x: i32, - pub y: i32, - } - ``` - -- **Error**: Errors regarding tables not found. - -- **Explanation**: Missing the `pub` attribute leads to the struct not being properly registered with SpacetimeDB. - -- **Root Cause**: Similar to previous errors, the need for public access to struct fields is unclear. - -- **Recommendation**: Ensure documentation explicitly states that public access is necessary for all fields in SpacetimeDB structs. - ---- - -## Rust / docs Failures (22 total) - -### Timeout Issues (8 Failures) - -- **Failures**: Various tasks timed out, indicating potential performance or configuration issues. - -- **Root Cause**: Specifics of timeout settings and performance optimization strategies should be more explicit in the documentation. - -- **Recommendation**: Include guidelines on optimizing performance for long-running tasks or emphasize best practices for structuring queries and data handling. - ---- - -### Other Failures (14 Failures) - -#### 6. **t_000_empty_reducers** -- **Generated Code**: - ```rust - #[spacetimedb::reducer] - pub fn empty_reducer_no_args(_ctx: &spacetimedb::ReducerContext) { - } - ``` - -- **Golden Example**: - ```rust - #[reducer] - pub fn empty_reducer_no_args(ctx: &ReducerContext) -> Result<(), String> { - Ok(()) - } - ``` - -- **Error**: Schema-related errors due to missing return type and proper handling. +### Additional Recommendations -- **Explanation**: Missing return type (`Result<(), String>`) was not implemented. +1. **Documentation Clarity**: + - Ensure clear examples defining the expected syntax for all relevant SpacetimeDB features (e.g., table structure, reducer signatures). + +2. **Example Consistency**: + - Modify the examples to guarantee consistency in field access levels (public/private) across all instances. -- **Root Cause**: The documentation may not explicitly mention that reducers should return results. - -- **Recommendation**: Adjust the documentation to specify that reducer functions must include appropriate return types. +3. **Error Handling**: + - Include a section on expected error messages and discrepancies that developers should look out for, which could help in debugging similar errors effectively. --- -#### 7. **t_001_basic_tables** -- **Generated Code**: - ```rust - #[spacetimedb::table(name = user)] - pub struct User { - #[primary_key] - id: i32, - name: String, - age: i32, - active: bool, - } - ``` +## Rust / docs Failures -- **Golden Example**: - ```rust - #[table(name = user)] - pub struct User { - #[primary_key] - pub id: i32, - pub name: String, - pub age: i32, - pub active: bool, - } - ``` - -- **Error**: Schema-related errors due to missing `pub` modifiers. - -- **Explanation**: Missing public access modifiers on struct fields prevented expected behavior. +### Timeout Issues -- **Root Cause**: Visibility rules may not have been adequately covered in the documentation. - -- **Recommendation**: Ensure the documentation includes examples with visibility modifiers. +- **Failures**: t_013_spacetime_sum_type, t_015_product_type_columns, t_016_sum_type_columns, t_018_constraints, t_019_many_to_many, t_020_ecs +- **Recommendation**: + - Review the execution time of these benchmarks and possibly optimize the code for performance or provide a timeout setting for testing. --- -### C# / docs Failures (4 total) - -#### Other Failures (4 Failures) - -#### 8. **t_014_elementary_columns** -- **Generated Code**: - ```csharp - [SpacetimeDB.Table(Name = "Primitive", Public = true)] - public partial struct Primitive - { - [SpacetimeDB.PrimaryKey] - public int Id; - public int Count; - ... - } - ``` - -- **Golden Example**: - ```csharp - [Table(Name = "Primitive")] - public partial struct Primitive - { - [PrimaryKey] public int Id; - public int Count; - ... - } - ``` - -- **Error**: Table not found during sql operations. - -- **Explanation**: The `Public` attribute's use was incorrect; it's not necessary in the struct definition. - -- **Root Cause**: Confusion over the purpose and necessity of attributes. - -- **Recommendation**: Update documentation to clarify attributes' roles in table definitions, removing unnecessary ones for struct exposure. - ---- - -#### 9. **t_016_sum_type_columns** -- **Generated Code**: - ```csharp - [SpacetimeDB.Table(Name = "Drawing", Public = true)] - public partial struct Drawing - { - [SpacetimeDB.PrimaryKey] - public int Id; - } - ``` - -- **Golden Example**: - ```csharp - [Table(Name = "Drawing")] - public partial struct Drawing - { - [PrimaryKey] public int Id; - } - ``` - -- **Error**: Table not found during sql operations. - -- **Explanation**: Similar to the previous failure, the `Public` attribute was misapplied. - -- **Root Cause**: Misalignment between understood attribute requirements and actual usage. - -- **Recommendation**: Further clarification of when and where to apply attributes in C# constructs related to SpacetimeDB. +## C# / docs Failures + +### t_014_elementary_columns + +1. **The generated code**: + ```csharp + using SpacetimeDB; + + public static partial class Module + { + [SpacetimeDB.Table(Name = "Primitive", Public = true)] + public partial struct Primitive + { + [SpacetimeDB.PrimaryKey] + public int Id; + public int Count; + public long Total; + public float Price; + public double Ratio; + public bool Active; + public string Name; + } + + [SpacetimeDB.Reducer] + public static void Seed(ReducerContext ctx) + { + ctx.Db.Primitive.Insert(new Primitive + { + Id = 1, + Count = 2, + Total = 3000000000L, + Price = 1.5f, + Ratio = 2.25, + Active = true, + Name = "Alice" + }); + } + } + ``` + +2. **The golden example**: + ```csharp + using SpacetimeDB; + + public static partial class Module + { + [Table(Name = "Primitive")] + public partial struct Primitive + { + [PrimaryKey] public int Id; + public int Count; + public long Total; + public float Price; + public double Ratio; + public bool Active; + public string Name; + } + + [Reducer] + public static void Seed(ReducerContext ctx) + { + ctx.Db.Primitive.Insert(new Primitive { + Id = 1, + Count = 2, + Total = 3000000000, + Price = 1.5f, + Ratio = 2.25, + Active = true, + Name = "Alice" + }); + } + } + ``` + +3. **The error**: + - `no such table: 'primitive'` + +4. **Explain the difference**: + - The generated code has an extra public field visibility which is redundant in this context, leading to distraction. + +5. **Root cause**: + - Inconsistent handling of public annotations for struct attributes. + +6. **Recommendation**: + - Align the documentation to show proper usage of attributes and visibility appropriately. --- @@ -351,47 +325,4 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do } ``` -- **Golden Example**: - ```csharp - [Table(Name = "TickTimer", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))] - public partial struct TickTimer - { - [PrimaryKey, AutoInc] public ulong ScheduledId; - public ScheduleAt ScheduledAt; - } - ``` - -- **Error**: Table not found during sql operations. - -- **Explanation**: The field definitions and relationships were incorrectly configured. - -- **Root Cause**: Possible gaps in documentation regarding definitions of scheduled columns and expected real structures. - -- **Recommendation**: Revise documentation to ensure clear expectations about table configuration and proper struct setup. - ---- - -#### 11. **t_020_ecs** -- **Generated Code**: - ```csharp - [SpacetimeDB.Table(Name = "Entity", Public = true)] - public partial struct Entity { [SpacetimeDB.PrimaryKey] public int Id; } - ``` - -- **Golden Example**: - ```csharp - [Table(Name = "Entity")] - public partial struct Entity { [PrimaryKey] public int Id; } - ``` - -- **Error**: Errors related to missing tables. - -- **Explanation**: Public attributes were misused in creating struct definitions for the tables. - -- **Root Cause**: Attribute usage may be causing confusion in use cases. - -- **Recommendation**: Ensure documentation includes proper usage guidelines for attributes in defining entities. - ---- - -By addressing the aforementioned discrepancies and gaps in documentation, developers can improve their implementation of SpacetimeDB, leading to smoother integrations and reduced error rates during execution. +This analysis serves to highlight the discrepancies noted in the benchmark test failures across Rust and C#, with actionable steps to amend recurring issues. Essential areas of improvement focus on explicit documentation, consistent field access levels, and clearer definitions of API requirements. By implementing these recommendations, we can streamline the development process and avoid common pitfalls. diff --git a/docs/llms/docs-benchmark-comment.md b/docs/llms/docs-benchmark-comment.md index 37272389e0d..907eb0e9b50 100644 --- a/docs/llms/docs-benchmark-comment.md +++ b/docs/llms/docs-benchmark-comment.md @@ -2,16 +2,16 @@ | Language | Mode | Category | Tests Passed | Task Pass % | |----------|------|----------|--------------|-------------| -| Rust | rustdoc_json | basics | 25/27 | 83.3% ⬆️ +9.0% | -| Rust | rustdoc_json | schema | 26/34 | 75.3% ⬆️ +10.0% | -| Rust | rustdoc_json | **total** | 51/61 | **79.7%** ⬆️ +9.5% | +| Rust | rustdoc_json | basics | 25/27 | 83.3% ⬆️ +6.9% | +| Rust | rustdoc_json | schema | 24/34 | 68.7% ⬇️ -6.7% | +| Rust | rustdoc_json | **total** | 49/61 | **76.7%** ⬆️ +0.8% | | Rust | docs | basics | 5/27 | 11.1% | -| Rust | docs | schema | 0/14 | 0.0% ⬇️ -20.5% | -| Rust | docs | **total** | 5/41 | **6.1%** ⬇️ -9.3% | +| Rust | docs | schema | 4/18 | 12.5% ⬇️ -8.0% | +| Rust | docs | **total** | 9/45 | **11.7%** ⬇️ -3.6% | | C# | docs | basics | 27/27 | 100.0% | -| C# | docs | schema | 25/34 | 73.7% | -| C# | docs | **total** | 52/61 | **88.0%** | +| C# | docs | schema | 24/32 | 70.3% ⬆️ +6.7% | +| C# | docs | **total** | 51/59 | **86.5%** ⬆️ +3.0% | _Compared against master branch baseline_ -Generated at: 2026-01-23T20:21:59.670Z +Generated at: 2026-01-26T19:41:35.586Z diff --git a/docs/llms/docs-benchmark-details.json b/docs/llms/docs-benchmark-details.json index 1a8a6449ec1..fc7a2432196 100644 --- a/docs/llms/docs-benchmark-details.json +++ b/docs/llms/docs-benchmark-details.json @@ -19,7 +19,7 @@ "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\nfn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_int(_ctx: &ReducerContext, _count: i32) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_string(_ctx: &ReducerContext, _name: String) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_two_args(_ctx: &ReducerContext, _count: i32, _name: String) {\n}\n\n#[spacetimedb::reducer]\nfn empty_reducer_with_three_args(_ctx: &ReducerContext, _active: bool, _ratio: f32, _label: String) {\n}", + "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &ReducerContext, _count: i32) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &ReducerContext, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &ReducerContext, _count: i32, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &ReducerContext, _active: bool, _ratio: f32, _label: String) {\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-000-empty-reducers-golden", @@ -35,15 +35,15 @@ "llm_db": "basics-t-000-empty-reducers-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:12.144740177Z", - "finished_at": "2026-01-23T20:09:46.065291337Z" + "started_at": "2026-01-26T19:27:52.325853523Z", + "finished_at": "2026-01-26T19:28:19.691117111Z" }, "t_001_basic_tables": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -69,15 +69,15 @@ "llm_db": "basics-t-001-basic-tables-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:14.464369753Z", - "finished_at": "2026-01-23T20:09:44.014749235Z" + "started_at": "2026-01-26T19:27:55.244006331Z", + "finished_at": "2026-01-26T19:28:22.209162875Z" }, "t_002_scheduled_table": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -87,7 +87,7 @@ "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, ScheduleAt, Table};\n\n#[table(name = tick_timer, schedule(column = scheduled_at, reducer = tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext) {}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _scheduled_id: u64) {\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -99,24 +99,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling serde v1.0.228\n Compiling zerocopy v0.8.33\n Compiling either v1.15.0\n Compiling shlex v1.3.0\n Compiling find-msvc-tools v0.1.8\n Compiling bitflags v2.10.0\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling thiserror v1.0.69\n Compiling zmij v1.0.16\n Compiling keccak v0.1.5\n Compiling heck v0.4.1\n Compiling arrayvec v0.7.6\n Compiling bytes v1.11.0\n Compiling humantime v2.3.0\n Compiling convert_case v0.4.0\n Compiling itoa v1.0.17\n Compiling second-stack v0.3.5\n Compiling serde_json v1.0.149\n Compiling constant_time_eq v0.4.2\n Compiling getrandom v0.2.17\n Compiling smallvec v1.15.1\n Compiling hex v0.4.3\n Compiling cc v1.2.54\n Compiling bytemuck v1.24.0\n Compiling arrayref v0.3.9\n Compiling spacetimedb-lib v1.11.1\n Compiling itertools v0.12.1\n Compiling memchr v2.7.6\n Compiling log v0.4.29\n Compiling rand_core v0.6.4\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling blake3 v1.8.3\n Compiling decorum v0.3.1\n Compiling block-buffer v0.10.4\n Compiling crypto-common v0.1.7\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling ethnum v1.5.2\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_002_scheduled_table/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(column = scheduled_at, reducer = tick))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:18:36\n |\n18 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:17:15\n |\n17 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:18:16\n |\n18 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:20:39\n |\n20 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nSome errors have detailed explanations: E0422, E0599.\nFor more information about an error, try `rustc --explain E0422`.\nerror: could not compile `spacetime-module` (lib) due to 5 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling heck v0.5.0\n Compiling serde_core v1.0.228\n Compiling cfg-if v1.0.4\n Compiling find-msvc-tools v0.1.8\n Compiling either v1.15.0\n Compiling shlex v1.3.0\n Compiling serde v1.0.228\n Compiling zerocopy v0.8.34\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling bytes v1.11.0\n Compiling arrayvec v0.7.6\n Compiling humantime v2.3.0\n Compiling keccak v0.1.5\n Compiling zmij v1.0.17\n Compiling heck v0.4.1\n Compiling convert_case v0.4.0\n Compiling smallvec v1.15.1\n Compiling hex v0.4.3\n Compiling second-stack v0.3.5\n Compiling constant_time_eq v0.4.2\n Compiling arrayref v0.3.9\n Compiling getrandom v0.2.17\n Compiling itertools v0.12.1\n Compiling cc v1.2.54\n Compiling itoa v1.0.17\n Compiling spacetimedb-lib v1.11.1\n Compiling serde_json v1.0.149\n Compiling rand_core v0.6.4\n Compiling bytemuck v1.24.0\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling block-buffer v0.10.4\n Compiling crypto-common v0.1.7\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ethnum v1.5.2\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_002_scheduled_table/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:15:36\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:15:16\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:39\n |\n17 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nSome errors have detailed explanations: E0422, E0599.\nFor more information about an error, try `rustc --explain E0422`.\nerror: could not compile `spacetime-module` (lib) due to 5 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:35.992436277Z", - "finished_at": "2026-01-23T20:10:39.770857477Z" + "started_at": "2026-01-26T19:28:10.719260484Z", + "finished_at": "2026-01-26T19:29:24.230351153Z" }, "t_003_struct_in_table": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", "task": "t_003_struct_in_table", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::ReducerContext;\n\n#[derive(spacetimedb::SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n pos: Position,\n}\n\n#[spacetimedb::reducer]\npub fn add_entity(ctx: &ReducerContext, id: i32, x: i32, y: i32) {\n let pos = Position { x, y };\n ctx.db.entity().insert(Entity { id, pos });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n pos: Position,\n}\n\n#[reducer]\npub fn add_entity(ctx: &ReducerContext, id: i32, x: i32, y: i32) {\n ctx.db.entity().insert(Entity { id, pos: Position { x, y } });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-003-struct-in-table-golden", @@ -124,18 +124,28 @@ "work_dir_golden": "target/llm-runs/basics/t_003_struct_in_table/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_003_struct_in_table/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling unicode-ident v1.0.22\n Compiling quote v1.0.44\n Compiling version_check v0.9.5\n Compiling typenum v1.19.0\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling zerocopy v0.8.33\n Compiling serde v1.0.228\n Compiling shlex v1.3.0\n Compiling either v1.15.0\n Compiling find-msvc-tools v0.1.8\n Compiling anyhow v1.0.100\n Compiling nohash-hasher v0.2.0\n Compiling bitflags v2.10.0\n Compiling thiserror v1.0.69\n Compiling bytes v1.11.0\n Compiling heck v0.4.1\n Compiling humantime v2.3.0\n Compiling zmij v1.0.16\n Compiling keccak v0.1.5\n Compiling arrayvec v0.7.6\n Compiling convert_case v0.4.0\n Compiling hex v0.4.3\n Compiling bytemuck v1.24.0\n Compiling second-stack v0.3.5\n Compiling arrayref v0.3.9\n Compiling getrandom v0.2.17\n Compiling spacetimedb-lib v1.11.1\n Compiling itoa v1.0.17\n Compiling itertools v0.12.1\n Compiling constant_time_eq v0.4.2\n Compiling smallvec v1.15.1\n Compiling serde_json v1.0.149\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling rand_core v0.6.4\n Compiling scoped-tls v1.0.1\n Compiling cc v1.2.54\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling blake3 v1.8.3\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling block-buffer v0.10.4\n Compiling crypto-common v0.1.7\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling ethnum v1.5.2\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_003_struct_in_table/rust/server/gpt-5/llm)\nerror[E0599]: no method named `insert` found for reference `&entity__TableHandle` in the current scope\n --> src/lib.rs:20:21\n |\n20 | ctx.db.entity().insert(Entity { id, pos });\n | ^^^^^^\n |\n = help: items from traits can only be used if the trait is in scope\nhelp: trait `Table` which provides `insert` is implemented but not in scope; perhaps you want to import it\n |\n 2 + use spacetimedb::Table;\n |\nhelp: there is a method `try_insert` with a similar name\n |\n20 | ctx.db.entity().try_insert(Entity { id, pos });\n | ++++\n\nFor more information about this error, try `rustc --explain E0599`.\nerror: could not compile `spacetime-module` (lib) due to 1 previous error\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", - "phase": "build_or_publish" + "golden_db": "basics-t-003-struct-in-table-golden", + "llm_db": "basics-t-003-struct-in-table-gpt-5-llm", + "reducers_diff": { + "only_golden": [], + "only_llm": [ + "add_entity()" + ] + }, + "reducers_equal": false, + "server": "http://127.0.0.1:44233", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:14.464130029Z", - "finished_at": "2026-01-23T20:09:54.314351498Z" + "started_at": "2026-01-26T19:27:53.381607365Z", + "finished_at": "2026-01-26T19:28:20.526037052Z" }, "t_004_insert": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -169,7 +179,7 @@ "llm_out": "id | name | age | active ----+---------+-----+-------- 1 | \"Alice\" | 30 | true", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "insert_user", - "server": "http://127.0.0.1:41115" + "server": "http://127.0.0.1:44233" } }, "schema_parity": { @@ -180,15 +190,15 @@ "llm_db": "basics-t-004-insert-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:14.983974693Z", - "finished_at": "2026-01-23T20:09:35.992396086Z" + "started_at": "2026-01-26T19:28:03.162962728Z", + "finished_at": "2026-01-26T19:28:30.365311126Z" }, "t_005_update": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -198,7 +208,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn update_user(ctx: &ReducerContext, id: i32, name: String, age: i32, active: bool) {\n let row = User { id, name, age, active };\n ctx.db.user().id().update(row);\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, UniqueColumn};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn update_user(ctx: &ReducerContext, id: i32, name: String, age: i32, active: bool) {\n ctx.db.user().id().update(User { id, name, age, active });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-005-update-golden", @@ -206,6 +216,19 @@ "work_dir_golden": "target/llm-runs/basics/t_005_update/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_005_update/rust/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-005-update-golden", + "llm_db": "basics-t-005-update-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44233", + "tables_diff": null, + "tables_equal": true + } + }, "seed_users_row": { "pass": true, "partial": 1.0, @@ -229,26 +252,13 @@ "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "update_user", - "server": "http://127.0.0.1:41115" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-005-update-golden", - "llm_db": "basics-t-005-update-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41115", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:44233" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:57.792213429Z", - "finished_at": "2026-01-23T20:09:53.091667873Z" + "started_at": "2026-01-26T19:27:50.273973455Z", + "finished_at": "2026-01-26T19:28:39.660285285Z" }, "t_006_delete": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -266,15 +276,6 @@ "work_dir_golden": "target/llm-runs/basics/t_006_delete/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_006_delete/rust/server/gpt-5/llm", "scorer_details": { - "delete_user_count_zero": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -283,11 +284,20 @@ "llm_db": "basics-t-006-delete-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } }, + "delete_user_count_zero": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" + } + }, "seed_users_row": { "pass": true, "partial": 1.0, @@ -297,8 +307,8 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:35.084889228Z", - "finished_at": "2026-01-23T20:09:14.643664761Z" + "started_at": "2026-01-26T19:27:19.862018853Z", + "finished_at": "2026-01-26T19:27:52.325711770Z" }, "t_007_crud": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -308,7 +318,7 @@ "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, UniqueColumn};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn crud(ctx: &ReducerContext) {\n let users = ctx.db.user();\n\n let mut u1 = users.insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n\n let _u2 = users.insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n\n u1.name = \"Alice2\".to_string();\n u1.age = 31;\n u1.active = false;\n let _u1_updated = users.id().update(u1);\n\n users.id().delete(&2);\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn crud(ctx: &ReducerContext) {\n let users = ctx.db.user();\n\n users.insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n users.insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n\n let updated = User { id: 1, name: \"Alice2\".to_string(), age: 31, active: false };\n users.id().update(updated);\n\n users.id().delete(&2);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -325,6 +335,15 @@ "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" } }, + "crud_total_count_one": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM user" + } + }, "crud_row_id1_parity": { "pass": true, "partial": 1.0, @@ -336,16 +355,7 @@ "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "crud", - "server": "http://127.0.0.1:41115" - } - }, - "crud_total_count_one": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user" + "server": "http://127.0.0.1:44233" } }, "schema_parity": { @@ -356,15 +366,15 @@ "llm_db": "basics-t-007-crud-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:56.057273916Z", - "finished_at": "2026-01-23T20:09:48.569368820Z" + "started_at": "2026-01-26T19:27:23.893528453Z", + "finished_at": "2026-01-26T19:28:07.775124578Z" }, "t_008_index_lookup": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -374,7 +384,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(u) = ctx.db.user().id().find(id) {\n let User { id, name, .. } = u;\n ctx.db.result().id().delete(&id);\n ctx.db.result().insert(ResultRow { id, name });\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, UniqueColumn};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(user) = ctx.db.user().id().find(id) {\n let _ = ctx.db.result().id().delete(&id);\n ctx.db.result().insert(ResultRow { id: user.id, name: user.name });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -382,11 +392,17 @@ "work_dir_golden": "target/llm-runs/basics/t_008_index_lookup/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_008_index_lookup/rust/server/gpt-5/llm", "scorer_details": { - "seed_user_row": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + "golden_db": "basics-t-008-index-lookup-golden", + "llm_db": "basics-t-008-index-lookup-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44233", + "tables_diff": null, + "tables_equal": true } }, "index_lookup_projection_parity": { @@ -402,26 +418,20 @@ "llm_out": "id | name ----+--------- 1 | \"Alice\"", "query": "SELECT id, name FROM result WHERE id=1", "reducer": "lookup_user_name", - "server": "http://127.0.0.1:41115" + "server": "http://127.0.0.1:44233" } }, - "schema_parity": { + "seed_user_row": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "basics-t-008-index-lookup-golden", - "llm_db": "basics-t-008-index-lookup-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41115", - "tables_diff": null, - "tables_equal": true + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:14.643699808Z", - "finished_at": "2026-01-23T20:09:52.566672855Z" + "started_at": "2026-01-26T19:28:01.265667865Z", + "finished_at": "2026-01-26T19:28:38.153772708Z" }, "t_009_init": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -431,7 +441,7 @@ "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n let user = ctx.db.user();\n user.insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n user.insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) {\n let user = ctx.db.user();\n user.insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n user.insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -448,15 +458,6 @@ "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2 AND name='Bob' AND age=22 AND active=false" } }, - "init_seed_alice": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -465,7 +466,7 @@ "llm_db": "basics-t-009-init-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } @@ -478,11 +479,20 @@ "expected": 2, "sql": "SELECT COUNT(*) AS n FROM user" } + }, + "init_seed_alice": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" + } } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:57.046090650Z", - "finished_at": "2026-01-23T20:09:23.724177316Z" + "started_at": "2026-01-26T19:27:35.047568301Z", + "finished_at": "2026-01-26T19:28:10.719222494Z" }, "t_010_connect": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -492,7 +502,7 @@ "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = event)]\npub struct Event {\n #[primary_key]\n #[auto_inc]\n id: i32,\n kind: String,\n}\n\n#[spacetimedb::reducer(client_connected)]\npub fn client_connected(ctx: &ReducerContext) {\n let _ = ctx.db.event().insert(Event { id: 0, kind: \"connected\".to_string() });\n}\n\n#[spacetimedb::reducer(client_disconnected)]\npub fn client_disconnected(ctx: &ReducerContext) {\n let _ = ctx.db.event().insert(Event { id: 0, kind: \"disconnected\".to_string() });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = event)]\npub struct Event {\n #[primary_key]\n #[auto_inc]\n id: i32,\n kind: String,\n}\n\n#[reducer(client_connected)]\npub fn client_connected(ctx: &ReducerContext) {\n ctx.db.event().insert(Event { id: 0, kind: \"connected\".to_string() });\n}\n\n#[reducer(client_disconnected)]\npub fn client_disconnected(ctx: &ReducerContext) {\n ctx.db.event().insert(Event { id: 0, kind: \"disconnected\".to_string() });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-010-connect-golden", @@ -508,15 +518,15 @@ "llm_db": "basics-t-010-connect-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:35.620982701Z", - "finished_at": "2026-01-23T20:09:12.144710803Z" + "started_at": "2026-01-26T19:27:22.864510006Z", + "finished_at": "2026-01-26T19:28:01.265636007Z" }, "t_011_helper_function": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -526,7 +536,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n ctx.db.result().insert(ResultRow { id, sum: add(a, b) });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[reducer]\nfn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let sum = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -534,6 +544,37 @@ "work_dir_golden": "target/llm-runs/basics/t_011_helper_function/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_011_helper_function/rust/server/gpt-5/llm", "scorer_details": { + "helper_func_sum_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "args": [ + 1, + 2, + 3 + ], + "golden_db": "basics-t-011-helper-function-golden", + "golden_out": "id | sum ----+----- 1 | 5", + "llm_db": "basics-t-011-helper-function-gpt-5-llm", + "llm_out": "id | sum ----+----- 1 | 5", + "query": "SELECT id, sum FROM result WHERE id=1", + "reducer": "compute_sum", + "server": "http://127.0.0.1:44233" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-011-helper-function-golden", + "llm_db": "basics-t-011-helper-function-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44233", + "tables_diff": null, + "tables_equal": true + } + }, "helper_func_sum_abs": { "pass": true, "partial": 1.0, @@ -576,8 +617,8 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:09:23.724208808Z", - "finished_at": "2026-01-23T20:09:51.292524674Z" + "started_at": "2026-01-26T19:28:07.775155436Z", + "finished_at": "2026-01-26T19:28:36.996978868Z" }, "t_012_spacetime_product_type": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -587,7 +628,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow { id, value: Score { left, right } });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -612,7 +653,7 @@ "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } @@ -632,13 +673,13 @@ "llm_out": "id | value ----+----------------------- 1 | (left = 2, right = 3)", "query": "SELECT id, value FROM result WHERE id=1", "reducer": "set_score", - "server": "http://127.0.0.1:41115" + "server": "http://127.0.0.1:44233" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:32.450266496Z", - "finished_at": "2026-01-23T20:09:14.310539584Z" + "started_at": "2026-01-26T19:27:19.861773654Z", + "finished_at": "2026-01-26T19:27:55.243933613Z" }, "t_013_spacetime_sum_type": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -647,8 +688,8 @@ "golden_published": true, "model_name": "GPT-5", "total_tests": 3, - "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\nstruct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\nenum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = result)]\nstruct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[reducer]\nfn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {\n ctx.db.result().insert(ResultRow { id, value: Shape::Circle(radius) });\n}", + "passed_tests": 2, + "llm_output": "use spacetimedb::{reducer, table, ReducerContext, SpacetimeType, Table};\n\n#[derive(SpacetimeType, Clone)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType, Clone)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[reducer]\npub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {\n ctx.db\n .result()\n .insert(ResultRow { id, value: Shape::Circle(radius) });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-013-spacetime-sum-type-golden", @@ -656,6 +697,14 @@ "work_dir_golden": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/gpt-5/llm", "scorer_details": { + "sum_type_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `result`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200d2d3b6f126b42f6535fa1c89a272d1278f24e7645295553d055f0964bb68/sql)\n", + "phase": "sql_golden" + } + }, "sum_type_row_count": { "pass": true, "partial": 1.0, @@ -673,32 +722,15 @@ "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } - }, - "sum_type_row_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "args": [ - 1, - 10 - ], - "golden_db": "schema-t-013-spacetime-sum-type-golden", - "golden_out": "id | value ----+--------------- 1 | (Circle = 10)", - "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", - "llm_out": "id | value ----+--------------- 1 | (Circle = 10)", - "query": "SELECT id, value FROM result WHERE id=1", - "reducer": "set_circle", - "server": "http://127.0.0.1:41115" - } } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.743148689Z", - "finished_at": "2026-01-23T20:08:32.450224286Z" + "started_at": "2026-01-26T19:26:39.088386414Z", + "finished_at": "2026-01-26T19:27:19.723979899Z" }, "t_014_elementary_columns": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -708,7 +740,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000,\n price: 1.5,\n ratio: 2.25,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3000000000,\n price: 1.5f32,\n ratio: 2.25,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-014-elementary-columns-golden", @@ -716,17 +748,13 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { + "elementary_columns_row_count": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "schema-t-014-elementary-columns-golden", - "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41115", - "tables_diff": null, - "tables_equal": true + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" } }, "elementary_columns_row_parity": { @@ -740,22 +768,26 @@ "llm_out": "id | count | total | price | ratio | active | name ----+-------+------------+-------+-------+--------+--------- 1 | 2 | 3000000000 | 1.5 | 2.25 | true | \"Alice\"", "query": "SELECT id, count, total, price, ratio, active, name FROM primitive WHERE id=1", "reducer": "seed", - "server": "http://127.0.0.1:41115" + "server": "http://127.0.0.1:44233" } }, - "elementary_columns_row_count": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" + "golden_db": "schema-t-014-elementary-columns-golden", + "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44233", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:08:30.379293605Z", - "finished_at": "2026-01-23T20:09:14.464089675Z" + "started_at": "2026-01-26T19:27:08.469170041Z", + "finished_at": "2026-01-26T19:28:03.162920625Z" }, "t_015_product_type_columns": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -765,7 +797,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\nstruct Address {\n street: String,\n zip: i32,\n}\n\n#[derive(SpacetimeType)]\nstruct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = profile)]\nstruct Profile {\n #[primary_key]\n id: i32,\n home: Address,\n work: Address,\n pos: Position,\n}\n\n#[reducer]\nfn seed(ctx: &ReducerContext) {\n let home = Address { street: \"1 Main\".to_string(), zip: 11111 };\n let work = Address { street: \"2 Broad\".to_string(), zip: 22222 };\n let pos = Position { x: 7, y: 9 };\n match ctx.db.profile().id().find(1) {\n Some(mut row) => {\n row.home = home;\n row.work = work;\n row.pos = pos;\n ctx.db.profile().id().update(row);\n }\n None => {\n ctx.db.profile().insert(Profile { id: 1, home, work, pos });\n }\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Address {\n street: String,\n zip: i32,\n}\n\n#[derive(SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = profile)]\npub struct Profile {\n #[primary_key]\n id: i32,\n home: Address,\n work: Address,\n pos: Position,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.profile().insert(Profile {\n id: 1,\n home: Address { street: \"1 Main\".to_string(), zip: 11111 },\n work: Address { street: \"2 Broad\".to_string(), zip: 22222 },\n pos: Position { x: 7, y: 9 },\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-015-product-type-columns-golden", @@ -773,18 +805,13 @@ "work_dir_golden": "target/llm-runs/schema/t_015_product_type_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_015_product_type_columns/rust/server/gpt-5/llm", "scorer_details": { - "product_type_columns_row_parity": { + "product_type_columns_row_count": { "pass": true, "partial": 1.0, "notes": { - "args": [], - "golden_db": "schema-t-015-product-type-columns-golden", - "golden_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", - "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", - "llm_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", - "query": "SELECT id, home, work, pos FROM profile WHERE id=1", - "reducer": "seed", - "server": "http://127.0.0.1:41115" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM profile WHERE id=1" } }, "schema_parity": { @@ -795,24 +822,29 @@ "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } }, - "product_type_columns_row_count": { + "product_type_columns_row_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM profile WHERE id=1" + "args": [], + "golden_db": "schema-t-015-product-type-columns-golden", + "golden_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", + "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", + "llm_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", + "query": "SELECT id, home, work, pos FROM profile WHERE id=1", + "reducer": "seed", + "server": "http://127.0.0.1:44233" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.743649083Z", - "finished_at": "2026-01-23T20:08:57.046048716Z" + "started_at": "2026-01-26T19:26:39.089258499Z", + "finished_at": "2026-01-26T19:27:08.469138831Z" }, "t_016_sum_type_columns": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -822,7 +854,7 @@ "model_name": "GPT-5", "total_tests": 3, "passed_tests": 1, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[derive(spacetimedb::SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(spacetimedb::SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[spacetimedb::table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n if ctx.db.drawing().id().find(1).is_none() {\n ctx.db.drawing().insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let drawings = ctx.db.drawing();\n for row in drawings.iter() {\n drawings.id().delete(&row.id);\n }\n drawings.insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-016-sum-type-columns-golden", @@ -830,11 +862,19 @@ "work_dir_golden": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/gpt-5/llm", "scorer_details": { + "sum_type_columns_row_count": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c20072beef7cc108a057376dd8b6be7e2a74798bdfaea38dde4e2e708af5e427/sql)\n", + "phase": "sql" + } + }, "sum_type_columns_row_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c200be63a5c073cb57163fbe420fbf96d0ca1c24fb78e5d67bbed19841d5eeee/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c20076700591ec6cb5396663df5e1f56128de954277e753577b8dd7756ee998c/sql)\n", "phase": "sql_golden" } }, @@ -846,7 +886,7 @@ "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } @@ -861,8 +901,8 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.742955241Z", - "finished_at": "2026-01-23T20:08:35.620943048Z" + "started_at": "2026-01-26T19:26:39.088020973Z", + "finished_at": "2026-01-26T19:27:22.864464632Z" }, "t_017_scheduled_columns": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -872,7 +912,7 @@ "model_name": "GPT-5", "total_tests": 2, "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -884,14 +924,14 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling serde v1.0.228\n Compiling either v1.15.0\n Compiling shlex v1.3.0\n Compiling zerocopy v0.8.33\n Compiling find-msvc-tools v0.1.8\n Compiling nohash-hasher v0.2.0\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling anyhow v1.0.100\n Compiling arrayvec v0.7.6\n Compiling zmij v1.0.16\n Compiling heck v0.4.1\n Compiling convert_case v0.4.0\n Compiling humantime v2.3.0\n Compiling bytes v1.11.0\n Compiling keccak v0.1.5\n Compiling constant_time_eq v0.4.2\n Compiling bytemuck v1.24.0\n Compiling second-stack v0.3.5\n Compiling smallvec v1.15.1\n Compiling getrandom v0.2.17\n Compiling hex v0.4.3\n Compiling spacetimedb-lib v1.11.1\n Compiling itertools v0.12.1\n Compiling cc v1.2.54\n Compiling serde_json v1.0.149\n Compiling itoa v1.0.17\n Compiling arrayref v0.3.9\n Compiling rand_core v0.6.4\n Compiling memchr v2.7.6\n Compiling log v0.4.29\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling syn v2.0.114\n Compiling http v1.4.0\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling ethnum v1.5.2\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:15:36\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0412]: cannot find type `TickTimer` in this scope\n --> src/lib.rs:23:42\n |\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:15:16\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:39\n |\n17 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n 22 | #[reducer]\n | ---------- required by a bound introduced by this call\n 23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `register_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:746:81\n |\n746 | pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) {\n | ^^^^^^^^^^^^^^ required by this bound in `register_reducer`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n22 | #[reducer]\n | ---------- required by a bound introduced by this call\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `invoke_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:45:19\n |\n44 | pub fn invoke_reducer<'a, A: Args<'a>>(\n | -------------- required by a bound in this function\n45 | reducer: impl Reducer<'a, A>,\n | ^^^^^^^^^^^^^^ required by this bound in `invoke_reducer`\n\nSome errors have detailed explanations: E0277, E0412, E0422, E0599.\nFor more information about an error, try `rustc --explain E0277`.\nerror: could not compile `spacetime-module` (lib) due to 8 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Blocking waiting for file lock on package cache\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Blocking waiting for file lock on package cache\n Blocking waiting for file lock on package cache\n Compiling proc-macro2 v1.0.106\n Compiling unicode-ident v1.0.22\n Compiling quote v1.0.44\n Compiling version_check v0.9.5\n Compiling typenum v1.19.0\n Compiling autocfg v1.5.0\n Compiling heck v0.5.0\n Compiling serde_core v1.0.228\n Compiling cfg-if v1.0.4\n Compiling find-msvc-tools v0.1.8\n Compiling serde v1.0.228\n Compiling either v1.15.0\n Compiling zerocopy v0.8.34\n Compiling shlex v1.3.0\n Compiling anyhow v1.0.100\n Compiling bitflags v2.10.0\n Compiling thiserror v1.0.69\n Compiling nohash-hasher v0.2.0\n Compiling heck v0.4.1\n Compiling arrayvec v0.7.6\n Compiling zmij v1.0.17\n Compiling convert_case v0.4.0\n Compiling keccak v0.1.5\n Compiling humantime v2.3.0\n Compiling bytes v1.11.0\n Compiling itoa v1.0.17\n Compiling arrayref v0.3.9\n Compiling second-stack v0.3.5\n Compiling smallvec v1.15.1\n Compiling getrandom v0.2.17\n Compiling constant_time_eq v0.4.2\n Compiling cc v1.2.54\n Compiling itertools v0.12.1\n Compiling serde_json v1.0.149\n Compiling hex v0.4.3\n Compiling spacetimedb-lib v1.11.1\n Compiling bytemuck v1.24.0\n Compiling memchr v2.7.6\n Compiling generic-array v0.14.7\n Compiling log v0.4.29\n Compiling scoped-tls v1.0.1\n Compiling rand_core v0.6.4\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling blake3 v1.8.3\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling decorum v0.3.1\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling ethnum v1.5.2\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm)\nerror: expected `at`\n --> src/lib.rs:4:38\n |\n4 | #[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]\n | ^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:14:32\n |\n14 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0412]: cannot find type `TickTimer` in this scope\n --> src/lib.rs:21:42\n |\n21 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:12\n |\n14 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:16:35\n |\n16 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:21:8\n |\n 20 | #[reducer]\n | ---------- required by a bound introduced by this call\n 21 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `register_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:746:81\n |\n746 | pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) {\n | ^^^^^^^^^^^^^^ required by this bound in `register_reducer`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:21:8\n |\n20 | #[reducer]\n | ---------- required by a bound introduced by this call\n21 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `invoke_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:45:19\n |\n44 | pub fn invoke_reducer<'a, A: Args<'a>>(\n | -------------- required by a bound in this function\n45 | reducer: impl Reducer<'a, A>,\n | ^^^^^^^^^^^^^^ required by this bound in `invoke_reducer`\n\nSome errors have detailed explanations: E0277, E0412, E0422, E0599.\nFor more information about an error, try `rustc --explain E0277`.\nerror: could not compile `spacetime-module` (lib) due to 7 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.742610502Z", - "finished_at": "2026-01-23T20:08:56.057254318Z" + "started_at": "2026-01-26T19:26:39.087192758Z", + "finished_at": "2026-01-26T19:27:53.381568310Z" }, "t_018_constraints": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -900,8 +940,8 @@ "golden_published": true, "model_name": "GPT-5", "total_tests": 3, - "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db\n .account()\n .insert(Account {\n id: 1,\n email: \"a@example.com\".to_string(),\n name: \"Alice\".to_string(),\n });\n ctx.db\n .account()\n .insert(Account {\n id: 2,\n email: \"b@example.com\".to_string(),\n name: \"Bob\".to_string(),\n });\n}", + "passed_tests": 2, + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let t = ctx.db.account();\n t.insert(Account { id: 1, email: \"a@example.com\".to_string(), name: \"Alice\".to_string() });\n t.insert(Account { id: 2, email: \"b@example.com\".to_string(), name: \"Bob\".to_string() });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-018-constraints-golden", @@ -909,17 +949,12 @@ "work_dir_golden": "target/llm-runs/schema/t_018_constraints/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_018_constraints/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, + "constraints_row_parity_after_seed": { + "pass": false, + "partial": 0.0, "notes": { - "golden_db": "schema-t-018-constraints-golden", - "llm_db": "schema-t-018-constraints-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:33615", - "tables_diff": null, - "tables_equal": true + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `account`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200ce532d202b333f35de1400d0f2b40c51bd06fe40198129dd9b2a5b0d196e/sql)\n", + "phase": "sql_golden" } }, "constraints_seed_two_rows": { @@ -953,15 +988,15 @@ "llm_db": "schema-t-018-constraints-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.742384971Z", - "finished_at": "2026-01-23T20:08:30.379256146Z" + "started_at": "2026-01-26T19:26:39.086684099Z", + "finished_at": "2026-01-26T19:27:19.861734913Z" }, "t_019_many_to_many": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -971,7 +1006,7 @@ "model_name": "GPT-5", "total_tests": 5, "passed_tests": 5, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[table(name = group)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[table(\n name = membership,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n // Clear existing rows to ensure exactly the requested rows exist after seeding\n let membership_ids: Vec = ctx.db.membership().iter().map(|m| m.id).collect();\n for id in membership_ids {\n ctx.db.membership().id().delete(&id);\n }\n\n let user_ids: Vec = ctx.db.user().iter().map(|u| u.user_id).collect();\n for id in user_ids {\n ctx.db.user().user_id().delete(&id);\n }\n\n let group_ids: Vec = ctx.db.group().iter().map(|g| g.group_id).collect();\n for id in group_ids {\n ctx.db.group().group_id().delete(&id);\n }\n\n // Insert users\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".to_string() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".to_string() });\n\n // Insert groups\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".to_string() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".to_string() });\n\n // Insert memberships\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[table(name = group)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[table(\n name = membership,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n {\n let tbl = ctx.db.membership();\n let ids: Vec = tbl.iter().map(|r| r.id).collect();\n for id in ids {\n tbl.id().delete(&id);\n }\n }\n {\n let tbl = ctx.db.user();\n let ids: Vec = tbl.iter().map(|r| r.user_id).collect();\n for id in ids {\n tbl.user_id().delete(&id);\n }\n }\n {\n let tbl = ctx.db.group();\n let ids: Vec = tbl.iter().map(|r| r.group_id).collect();\n for id in ids {\n tbl.group_id().delete(&id);\n }\n }\n\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".to_string() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".to_string() });\n\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".to_string() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".to_string() });\n\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-019-many-to-many-golden", @@ -979,20 +1014,7 @@ "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-019-many-to-many-golden", - "llm_db": "schema-t-019-many-to-many-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41115", - "tables_diff": null, - "tables_equal": true - } - }, - "m2m_has_1_20": { + "m2m_has_1_10": { "pass": true, "partial": 1.0, "notes": { @@ -1001,13 +1023,13 @@ "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" } }, - "m2m_has_2_20": { + "m2m_has_1_20": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" } }, "memberships_three_rows": { @@ -1019,19 +1041,32 @@ "sql": "SELECT COUNT(*) AS n FROM membership" } }, - "m2m_has_1_10": { + "m2m_has_2_20": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=10" + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-019-many-to-many-golden", + "llm_db": "schema-t-019-many-to-many-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44233", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.743323315Z", - "finished_at": "2026-01-23T20:08:57.792175612Z" + "started_at": "2026-01-26T19:26:39.088752482Z", + "finished_at": "2026-01-26T19:27:50.273815091Z" }, "t_020_ecs": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -1041,7 +1076,7 @@ "model_name": "GPT-5", "total_tests": 5, "passed_tests": 1, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[spacetimedb::table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[spacetimedb::table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n // Clear and insert entities\n for &id in &[1, 2] {\n if ctx.db.entity().id().find(id).is_some() {\n ctx.db.entity().id().delete(&id);\n }\n ctx.db.entity().insert(Entity { id });\n }\n\n // Clear existing positions/velocities for these entities and insert new values\n // Entity 1: pos=(0,0), vel=(1,0)\n if ctx.db.position().entity_id().find(1).is_some() {\n ctx.db.position().entity_id().delete(&1);\n }\n ctx.db.position().insert(Position { entity_id: 1, x: 0, y: 0 });\n if ctx.db.velocity().entity_id().find(1).is_some() {\n ctx.db.velocity().entity_id().delete(&1);\n }\n ctx.db.velocity().insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n // Entity 2: pos=(10,0), vel=(-2,3)\n if ctx.db.position().entity_id().find(2).is_some() {\n ctx.db.position().entity_id().delete(&2);\n }\n ctx.db.position().insert(Position { entity_id: 2, x: 10, y: 0 });\n if ctx.db.velocity().entity_id().find(2).is_some() {\n ctx.db.velocity().entity_id().delete(&2);\n }\n ctx.db.velocity().insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n\n // Clean any existing next_position rows for these entities\n for &id in &[1, 2] {\n if ctx.db.next_position().entity_id().find(id).is_some() {\n ctx.db.next_position().entity_id().delete(&id);\n }\n }\n}\n\n#[spacetimedb::reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let nx = pos.x + vel.vx;\n let ny = pos.y + vel.vy;\n let next = NextPosition {\n entity_id: pos.entity_id,\n x: nx,\n y: ny,\n };\n\n if ctx.db.next_position().entity_id().find(pos.entity_id).is_some() {\n let _ = ctx.db.next_position().entity_id().update(next);\n } else {\n let _ = ctx.db.next_position().insert(next);\n }\n }\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.entity().insert(Entity { id: 1 });\n ctx.db.position().insert(Position { entity_id: 1, x: 0, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n ctx.db.entity().insert(Entity { id: 2 });\n ctx.db.position().insert(Position { entity_id: 2, x: 10, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n}\n\n#[reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let next = NextPosition {\n entity_id: pos.entity_id,\n x: pos.x + vel.vx,\n y: pos.y + vel.vy,\n };\n\n if ctx.db.next_position().entity_id().find(pos.entity_id).is_some() {\n ctx.db.next_position().entity_id().update(next);\n } else {\n ctx.db.next_position().insert(next);\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-020-ecs-golden", @@ -1053,7 +1088,15 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", + "phase": "sql" + } + }, + "ecs_next_pos_entity2": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", "phase": "sql" } }, @@ -1061,7 +1104,7 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", "phase": "sql" } }, @@ -1073,7 +1116,7 @@ "llm_db": "schema-t-020-ecs-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } @@ -1082,22 +1125,14 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", - "phase": "sql" - } - }, - "ecs_next_pos_entity2": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c20022d8f2e2d547824e6b1c08b40372fd94143f227cebc3dd95d8debbce411d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.743495455Z", - "finished_at": "2026-01-23T20:09:14.983916389Z" + "started_at": "2026-01-26T19:26:39.089004480Z", + "finished_at": "2026-01-26T19:27:35.047523671Z" }, "t_021_multi_column_index": { "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", @@ -1107,7 +1142,7 @@ "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = log, index(name = by_user_day, btree(columns = [user_id, day])))]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let table = ctx.db.log();\n table.insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".to_string() });\n table.insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".to_string() });\n table.insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".to_string() });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = log, index(name = by_user_day, btree(columns = [user_id, day])))]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let ids: Vec = ctx.db.log().iter().map(|r| r.id).collect();\n for id in ids {\n ctx.db.log().id().delete(&id);\n }\n\n ctx.db.log().insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".to_string() });\n ctx.db.log().insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".to_string() });\n ctx.db.log().insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".to_string() });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-021-multi-column-index-golden", @@ -1115,15 +1150,6 @@ "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/rust/server/gpt-5/llm", "scorer_details": { - "mcindex_lookup_u7_d1": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -1132,7 +1158,7 @@ "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:44233", "tables_diff": null, "tables_equal": true } @@ -1146,7 +1172,16 @@ "sql": "SELECT COUNT(*) AS n FROM log" } }, - "mcindex_seed_count": { + "mcindex_lookup_u7_d2": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2" + } + }, + "mcindex_lookup_u7_d1": { "pass": true, "partial": 1.0, "notes": { @@ -1157,8 +1192,8 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:07:57.742772776Z", - "finished_at": "2026-01-23T20:08:35.084850930Z" + "started_at": "2026-01-26T19:26:39.087595992Z", + "finished_at": "2026-01-26T19:27:23.893472645Z" } } } @@ -1166,21 +1201,21 @@ }, { "mode": "docs", - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_000_empty_reducers", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &spacetimedb::ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &spacetimedb::ReducerContext, _count: i32) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &spacetimedb::ReducerContext, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &spacetimedb::ReducerContext, _count: i32, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &spacetimedb::ReducerContext, _active: bool, _ratio: f32, _label: String) {\n}", + "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &ReducerContext, count: i32) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &ReducerContext, name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &ReducerContext, count: i32, name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &ReducerContext, active: bool, ratio: f32, label: String) {\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-000-empty-reducers-golden", @@ -1198,11 +1233,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:10.018237719Z", - "finished_at": "2026-01-23T20:12:41.638729168Z" + "started_at": "2026-01-26T19:30:54.611008723Z", + "finished_at": "2026-01-26T19:31:59.326178772Z" }, "t_001_basic_tables": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_001_basic_tables", "lang": "rust", "golden_published": true, @@ -1227,18 +1262,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:46.725514922Z", - "finished_at": "2026-01-23T20:13:51.799945305Z" + "started_at": "2026-01-26T19:31:23.564110648Z", + "finished_at": "2026-01-26T19:32:09.696102989Z" }, "t_002_scheduled_table": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_002_scheduled_table", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {\n // No-op scheduled tick.\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n });\n Ok(())\n}", + "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().try_insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n })?;\n }\n Ok(())\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -1256,11 +1291,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:13:28.197750258Z", - "finished_at": "2026-01-23T20:14:26.307958881Z" + "started_at": "2026-01-26T19:32:03.232154280Z", + "finished_at": "2026-01-26T19:32:55.980604615Z" }, "t_003_struct_in_table": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_003_struct_in_table", "lang": "rust", "golden_published": true, @@ -1285,11 +1320,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:41.638758353Z", - "finished_at": "2026-01-23T20:13:47.479970679Z" + "started_at": "2026-01-26T19:31:11.581070012Z", + "finished_at": "2026-01-26T19:32:09.839951728Z" }, "t_004_insert": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_004_insert", "lang": "rust", "golden_published": true, @@ -1322,11 +1357,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:46.734575843Z", - "finished_at": "2026-01-23T20:13:46.613223334Z" + "started_at": "2026-01-26T19:31:53.617759187Z", + "finished_at": "2026-01-26T19:32:28.129265268Z" }, "t_005_update": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_005_update", "lang": "rust", "golden_published": true, @@ -1341,12 +1376,13 @@ "work_dir_golden": "target/llm-runs/basics/t_005_update/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_005_update/rust/server/gpt-5/llm", "scorer_details": { - "data_parity_update_user": { + "seed_users_row": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", - "phase": "call_reducer_golden" + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", + "phase": "sql_golden", + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } }, "schema_parity": { @@ -1364,23 +1400,14 @@ "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", "phase": "call_reducer_golden" } - }, - "seed_users_row": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", - "phase": "sql_golden", - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" - } } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:10.015338220Z", - "finished_at": "2026-01-23T20:13:14.713691221Z" + "started_at": "2026-01-26T19:30:54.604964500Z", + "finished_at": "2026-01-26T19:31:53.617639721Z" }, "t_006_delete": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_006_delete", "lang": "rust", "golden_published": true, @@ -1412,29 +1439,28 @@ "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" } }, - "seed_users_row": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-006-delete-golden`.\n", - "phase": "sql_golden", - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-006-delete-golden`.\n", + "phase": "describe_golden" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:09.994528341Z", - "finished_at": "2026-01-23T20:12:46.205776277Z" + "started_at": "2026-01-26T19:30:54.580009457Z", + "finished_at": "2026-01-26T19:32:03.232098066Z" }, "t_007_crud": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_007_crud", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 1, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer]\npub fn crud(ctx: &ReducerContext) {\n // insert (id=1, name=\"Alice\", age=30, active=true)\n ctx.db.user().insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n\n // insert (id=2, name=\"Bob\", age=22, active=false)\n ctx.db.user().insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n\n // update (id=1, name=\"Alice2\", age=31, active=false)\n if let Some(mut u1) = ctx.db.user().id().find(1) {\n u1.name = \"Alice2\".to_string();\n u1.age = 31;\n u1.active = false;\n ctx.db.user().id().update(u1);\n }\n\n // delete id=2\n ctx.db.user().id().delete(2);\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer]\npub fn crud(ctx: &ReducerContext) {\n ctx.db.user().insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n ctx.db.user().insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n\n if ctx.db.user().id().find(1).is_some() {\n ctx.db.user().id().update(User { id: 1, name: \"Alice2\".to_string(), age: 31, active: false });\n }\n\n ctx.db.user().id().delete(2);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -1442,21 +1468,12 @@ "work_dir_golden": "target/llm-runs/basics/t_007_crud/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_007_crud/rust/server/gpt-5/llm", "scorer_details": { - "crud_row_id1_parity": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", - "phase": "call_reducer_golden" - } - }, - "crud_row_id2_deleted": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", + "phase": "describe_golden" } }, "crud_total_count_one": { @@ -1468,28 +1485,37 @@ "sql": "SELECT COUNT(*) AS n FROM user" } }, - "schema_parity": { + "crud_row_id1_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", - "phase": "describe_golden" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", + "phase": "call_reducer_golden" + } + }, + "crud_row_id2_deleted": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:10.004797508Z", - "finished_at": "2026-01-23T20:13:37.162002816Z" + "started_at": "2026-01-26T19:30:54.591258099Z", + "finished_at": "2026-01-26T19:32:19.735936055Z" }, "t_008_index_lookup": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_008_index_lookup", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) -> Result<(), String> {\n if let Some(user) = ctx.db.user().id().find(id) {\n ctx.db\n .result()\n .try_insert(ResultRow { id: user.id, name: user.name.clone() })?;\n Ok(())\n } else {\n Err(\"User not found\".to_string())\n }\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user, public)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::table(name = result, public)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(u) = ctx.db.user().id().find(id) {\n ctx.db.result().id().delete(&id);\n ctx.db.result().insert(ResultRow { id: u.id, name: u.name });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -1497,6 +1523,15 @@ "work_dir_golden": "target/llm-runs/basics/t_008_index_lookup/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_008_index_lookup/rust/server/gpt-5/llm", "scorer_details": { + "seed_user_row": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-008-index-lookup-golden`.\n", + "phase": "sql_golden", + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + } + }, "schema_parity": { "pass": false, "partial": 0.0, @@ -1512,30 +1547,21 @@ "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-008-index-lookup-golden`.\n", "phase": "call_reducer_golden" } - }, - "seed_user_row": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-008-index-lookup-golden`.\n", - "phase": "sql_golden", - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" - } } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:46.729438058Z", - "finished_at": "2026-01-23T20:13:54.235945228Z" + "started_at": "2026-01-26T19:31:52.996077836Z", + "finished_at": "2026-01-26T19:32:44.567947473Z" }, "t_009_init": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_009_init", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 3, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.user().insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n ctx.db.user().insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n Ok(())\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.user().insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n ctx.db.user().insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n Ok(())\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -1543,13 +1569,13 @@ "work_dir_golden": "target/llm-runs/basics/t_009_init/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_009_init/rust/server/gpt-5/llm", "scorer_details": { - "init_seed_bob": { + "init_seed_alice": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2 AND name='Bob' AND age=22 AND active=false" + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" } }, "schema_parity": { @@ -1569,22 +1595,22 @@ "sql": "SELECT COUNT(*) AS n FROM user" } }, - "init_seed_alice": { + "init_seed_bob": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2 AND name='Bob' AND age=22 AND active=false" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:10.009828612Z", - "finished_at": "2026-01-23T20:12:45.617807272Z" + "started_at": "2026-01-26T19:30:54.597845517Z", + "finished_at": "2026-01-26T19:32:17.483969682Z" }, "t_010_connect": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_010_connect", "lang": "rust", "golden_published": true, @@ -1609,18 +1635,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:09.998960857Z", - "finished_at": "2026-01-23T20:13:28.197638116Z" + "started_at": "2026-01-26T19:30:54.585220084Z", + "finished_at": "2026-01-26T19:31:52.995965049Z" }, "t_011_helper_function": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_011_helper_function", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[spacetimedb::reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let s = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum: s });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[spacetimedb::reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let sum = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -1663,18 +1689,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:13:14.723917629Z", - "finished_at": "2026-01-23T20:14:00.225654958Z" + "started_at": "2026-01-26T19:31:59.326285562Z", + "finished_at": "2026-01-26T19:32:34.857458085Z" }, "t_012_spacetime_product_type": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_012_spacetime_product_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[derive(spacetimedb::SpacetimeType, Clone, Debug)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[spacetimedb::reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[derive(spacetimedb::SpacetimeType, Clone)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[spacetimedb::reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db\n .result()\n .insert(ResultRow { id, value: Score { left, right } });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -1709,11 +1735,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:09.991277650Z", - "finished_at": "2026-01-23T20:12:46.725468970Z" + "started_at": "2026-01-26T19:30:31.399995435Z", + "finished_at": "2026-01-26T19:31:11.581019739Z" }, "t_013_spacetime_sum_type": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_013_spacetime_sum_type", "lang": "rust", "golden_published": false, @@ -1738,18 +1764,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308049242Z", - "finished_at": "2026-01-23T20:14:26.308049242Z" + "started_at": "2026-01-26T19:32:55.980673255Z", + "finished_at": "2026-01-26T19:32:55.980673255Z" }, "t_014_elementary_columns": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_014_elementary_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000,\n price: 1.5_f32,\n ratio: 2.25,\n active: true,\n name: \"Alice\".into(),\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive, public)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000,\n price: 1.5f32,\n ratio: 2.25,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-014-elementary-columns-golden", @@ -1757,13 +1783,12 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/rust/server/gpt-5/llm", "scorer_details": { - "elementary_columns_row_count": { + "elementary_columns_row_parity": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", + "phase": "call_reducer_golden" } }, "schema_parity": { @@ -1774,21 +1799,22 @@ "phase": "describe_golden" } }, - "elementary_columns_row_parity": { + "elementary_columns_row_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", - "phase": "call_reducer_golden" + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:12:09.987997099Z", - "finished_at": "2026-01-23T20:13:50.463947582Z" + "started_at": "2026-01-26T19:30:30.882003264Z", + "finished_at": "2026-01-26T19:31:23.563975616Z" }, "t_015_product_type_columns": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_015_product_type_columns", "lang": "rust", "golden_published": false, @@ -1813,11 +1839,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308063959Z", - "finished_at": "2026-01-23T20:14:26.308063959Z" + "started_at": "2026-01-26T19:32:55.980689378Z", + "finished_at": "2026-01-26T19:32:55.980689378Z" }, "t_016_sum_type_columns": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_016_sum_type_columns", "lang": "rust", "golden_published": false, @@ -1842,40 +1868,49 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308044663Z", - "finished_at": "2026-01-23T20:14:26.308044663Z" + "started_at": "2026-01-26T19:32:55.980668485Z", + "finished_at": "2026-01-26T19:32:55.980668485Z" }, "t_017_scheduled_columns": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_017_scheduled_columns", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, - "passed_tests": 0, - "llm_output": null, + "total_tests": 2, + "passed_tests": 1, + "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.tick_timer().try_insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n })?;\n Ok(())\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-017-scheduled-columns-golden", + "llm_db": "schema-t-017-scheduled-columns-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_017_scheduled_columns/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-017-scheduled-columns-golden`.\n", + "phase": "describe_golden" + } + }, + "scheduled_seeded_one_row": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM tick_timer WHERE scheduled_id>=0" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308033084Z", - "finished_at": "2026-01-23T20:14:26.308033084Z" + "started_at": "2026-01-26T19:29:24.576470966Z", + "finished_at": "2026-01-26T19:30:31.399943290Z" }, "t_018_constraints": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_018_constraints", "lang": "rust", "golden_published": false, @@ -1900,11 +1935,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308021447Z", - "finished_at": "2026-01-23T20:14:26.308021447Z" + "started_at": "2026-01-26T19:32:55.980661308Z", + "finished_at": "2026-01-26T19:32:55.980661308Z" }, "t_019_many_to_many": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_019_many_to_many", "lang": "rust", "golden_published": false, @@ -1929,11 +1964,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308054994Z", - "finished_at": "2026-01-23T20:14:26.308054994Z" + "started_at": "2026-01-26T19:32:55.980679692Z", + "finished_at": "2026-01-26T19:32:55.980679692Z" }, "t_020_ecs": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_020_ecs", "lang": "rust", "golden_published": false, @@ -1958,37 +1993,64 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308059854Z", - "finished_at": "2026-01-23T20:14:26.308059854Z" + "started_at": "2026-01-26T19:32:55.980684633Z", + "finished_at": "2026-01-26T19:32:55.980684633Z" }, "t_021_multi_column_index": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "task": "t_021_multi_column_index", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, - "passed_tests": 0, - "llm_output": null, + "total_tests": 4, + "passed_tests": 3, + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(\n name = log,\n index(name = by_user_day, btree(columns = [user_id, day]))\n)]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let _ = ctx.db.log().try_insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".to_string() });\n let _ = ctx.db.log().try_insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".to_string() });\n let _ = ctx.db.log().try_insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".to_string() });\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-021-multi-column-index-golden", + "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "mcindex_lookup_u7_d2": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2" + } + }, + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-021-multi-column-index-golden`.\n", + "phase": "describe_golden" + } + }, + "mcindex_lookup_u7_d1": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" + } + }, + "mcindex_seed_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM log" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:14:26.308040547Z", - "finished_at": "2026-01-23T20:14:26.308040547Z" + "started_at": "2026-01-26T19:29:24.579594233Z", + "finished_at": "2026-01-26T19:30:30.881922637Z" } } } @@ -2179,14 +2241,14 @@ "modes": [ { "mode": "docs", - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_000_empty_reducers", "lang": "csharp", "golden_published": true, @@ -2209,25 +2271,25 @@ "llm_db": "basics-t-000-empty-reducers-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:20:05.908071Z", - "finished_at": "2026-01-23T20:21:02.544054377Z" + "started_at": "2026-01-26T19:38:54.385915075Z", + "finished_at": "2026-01-26T19:40:03.912043999Z" }, "t_001_basic_tables": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_001_basic_tables", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Product\")]\n public partial struct Product\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Title;\n public float Price;\n public bool InStock;\n }\n\n [SpacetimeDB.Table(Name = \"Note\")]\n public partial struct Note\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Body;\n public long Rating;\n public bool Pinned;\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Product\", Public = true)]\n public partial struct Product\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Title;\n public float Price;\n public bool InStock;\n }\n\n [SpacetimeDB.Table(Name = \"Note\", Public = true)]\n public partial struct Note\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Body;\n public long Rating;\n public bool Pinned;\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-001-basic-tables-golden", @@ -2243,25 +2305,25 @@ "llm_db": "basics-t-001-basic-tables-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:20:17.520008030Z", - "finished_at": "2026-01-23T20:21:03.652127542Z" + "started_at": "2026-01-26T19:39:06.588178775Z", + "finished_at": "2026-01-26T19:40:26.686164444Z" }, "t_002_scheduled_table": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_002_scheduled_table", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey, SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer timer)\n {\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n}", + "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [PrimaryKey, AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n }\n\n [Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledId = 0,\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -2277,25 +2339,25 @@ "llm_db": "basics-t-002-scheduled-table-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:21:05.396968262Z", - "finished_at": "2026-01-23T20:21:59.590160864Z" + "started_at": "2026-01-26T19:40:26.686215935Z", + "finished_at": "2026-01-26T19:41:35.359471807Z" }, "t_003_struct_in_table": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_003_struct_in_table", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Entity\")]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Position Pos;\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Entity\", Public = true)]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Position Pos;\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-003-struct-in-table-golden", @@ -2311,18 +2373,18 @@ "llm_db": "basics-t-003-struct-in-table-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:20:12.029574819Z", - "finished_at": "2026-01-23T20:20:58.944028610Z" + "started_at": "2026-01-26T19:39:03.248071954Z", + "finished_at": "2026-01-26T19:40:22.292027026Z" }, "t_004_insert": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_004_insert", "lang": "csharp", "golden_published": true, @@ -2337,6 +2399,19 @@ "work_dir_golden": "target/llm-runs/basics/t_004_insert/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_004_insert/csharp/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-004-insert-golden", + "llm_db": "basics-t-004-insert-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44935", + "tables_diff": null, + "tables_equal": true + } + }, "data_parity_insert_user": { "pass": true, "partial": 1.0, @@ -2353,36 +2428,23 @@ "llm_out": "Id | Name | Age | Active ----+---------+-----+-------- 1 | \"Alice\" | 30 | true", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "InsertUser", - "server": "http://127.0.0.1:41045" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-004-insert-golden", - "llm_db": "basics-t-004-insert-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:44935" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:21:02.544101204Z", - "finished_at": "2026-01-23T20:21:46.575966420Z" + "started_at": "2026-01-26T19:40:05.942682308Z", + "finished_at": "2026-01-26T19:41:00.825583459Z" }, "t_005_update": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_005_update", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void UpdateUser(ReducerContext ctx, int id, string name, int age, bool active)\n {\n ctx.Db.User.Id.Update(new User\n {\n Id = id,\n Name = name,\n Age = age,\n Active = active\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void UpdateUser(ReducerContext ctx, int id, string name, int age, bool active)\n {\n var user = ctx.Db.User.Id.Find(id) ?? throw new System.Exception(\"User not found\");\n user.Name = name;\n user.Age = age;\n user.Active = active;\n ctx.Db.User.Id.Update(user);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-005-update-golden", @@ -2397,20 +2459,7 @@ "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" } }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-005-update-golden", - "llm_db": "basics-t-005-update-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true - } - }, - "data_parity_update_user": { + "data_parity_update_user": { "pass": true, "partial": 1.0, "notes": { @@ -2426,23 +2475,36 @@ "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "UpdateUser", - "server": "http://127.0.0.1:41045" + "server": "http://127.0.0.1:44935" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-005-update-golden", + "llm_db": "basics-t-005-update-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44935", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:19:53.867992725Z", - "finished_at": "2026-01-23T20:21:05.391950708Z" + "started_at": "2026-01-26T19:38:38.720018388Z", + "finished_at": "2026-01-26T19:40:05.937381701Z" }, "t_006_delete": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_006_delete", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void DeleteUser(ReducerContext ctx, int id)\n {\n ctx.Db.User.Id.Delete(id);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void DeleteUser(ReducerContext ctx, int id)\n {\n ctx.Db.User.Id.Delete(id);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-006-delete-golden", @@ -2450,15 +2512,6 @@ "work_dir_golden": "target/llm-runs/basics/t_006_delete/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_006_delete/csharp/server/gpt-5/llm", "scorer_details": { - "delete_user_count_zero": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2467,7 +2520,7 @@ "llm_db": "basics-t-006-delete-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -2478,21 +2531,30 @@ "notes": { "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" } + }, + "delete_user_count_zero": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1" + } } }, "vendor": "openai", - "started_at": "2026-01-23T20:19:10.793697386Z", - "finished_at": "2026-01-23T20:19:53.867926470Z" + "started_at": "2026-01-26T19:37:37.167869929Z", + "finished_at": "2026-01-26T19:38:38.719937430Z" }, "t_007_crud": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_007_crud", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void Crud(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n\n var found = ctx.Db.User.Id.Find(1);\n if (found is User user1)\n {\n user1.Name = \"Alice2\";\n user1.Age = 31;\n user1.Active = false;\n ctx.Db.User.Id.Update(user1);\n }\n\n ctx.Db.User.Id.Delete(2);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void Crud(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n\n if (ctx.Db.User.Id.Find(1) is User user1)\n {\n user1.Name = \"Alice2\";\n user1.Age = 31;\n user1.Active = false;\n ctx.Db.User.Id.Update(user1);\n }\n\n ctx.Db.User.Id.Delete(2);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -2509,15 +2571,6 @@ "sql": "SELECT COUNT(*) AS n FROM User" } }, - "crud_row_id2_deleted": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2526,18 +2579,18 @@ "llm_db": "basics-t-007-crud-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } }, - "crud_total_count_one": { + "crud_row_id2_deleted": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM User" + "actual": 0, + "expected": 0, + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2" } }, "crud_row_id2_deleted": { @@ -2560,23 +2613,23 @@ "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "Crud", - "server": "http://127.0.0.1:41045" + "server": "http://127.0.0.1:44935" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:19:29.508011285Z", - "finished_at": "2026-01-23T20:20:17.519940667Z" + "started_at": "2026-01-26T19:37:59.027103288Z", + "finished_at": "2026-01-26T19:38:54.385590993Z" }, "t_008_index_lookup": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_008_index_lookup", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial class User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name = \"\";\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial class Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name = \"\";\n }\n\n [SpacetimeDB.Reducer]\n public static void LookupUserName(ReducerContext ctx, int id)\n {\n if (ctx.Db.User.Id.Find(id) is User u)\n {\n ctx.Db.Result.Insert(new Result { Id = u.Id, Name = u.Name });\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void LookupUserName(ReducerContext ctx, int id)\n {\n if (ctx.Db.User.Id.Find(id) is User user)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = user.Id,\n Name = user.Name\n });\n }\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -2592,7 +2645,7 @@ "llm_db": "basics-t-008-index-lookup-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -2617,23 +2670,23 @@ "llm_out": "Id | Name ----+--------- 1 | \"Alice\"", "query": "SELECT Id, Name FROM Result WHERE Id=1", "reducer": "LookupUserName", - "server": "http://127.0.0.1:41045" + "server": "http://127.0.0.1:44935" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:20:58.944081428Z", - "finished_at": "2026-01-23T20:21:57.704447793Z" + "started_at": "2026-01-26T19:40:05.937447735Z", + "finished_at": "2026-01-26T19:41:10.697769188Z" }, "t_009_init": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_009_init", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer(SpacetimeDB.ReducerKind.Init)]\n public static void Init(SpacetimeDB.ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -2641,60 +2694,60 @@ "work_dir_golden": "target/llm-runs/basics/t_009_init/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_009_init/csharp/server/gpt-5/llm", "scorer_details": { - "init_total_two": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 2, - "expected": 2, - "sql": "SELECT COUNT(*) AS n FROM User" + "golden_db": "basics-t-009-init-golden", + "llm_db": "basics-t-009-init-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44935", + "tables_diff": null, + "tables_equal": true } }, - "init_seed_bob": { + "init_seed_alice": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2 AND Name='Bob' AND Age=22 AND Active=false" + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1 AND Name='Alice' AND Age=30 AND Active=true" } }, - "init_seed_alice": { + "init_seed_bob": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1 AND Name='Alice' AND Age=30 AND Active=true" + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2 AND Name='Bob' AND Age=22 AND Active=false" } }, - "schema_parity": { + "init_total_two": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "basics-t-009-init-golden", - "llm_db": "basics-t-009-init-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true + "actual": 2, + "expected": 2, + "sql": "SELECT COUNT(*) AS n FROM User" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:19:36.893890047Z", - "finished_at": "2026-01-23T20:20:12.029514649Z" + "started_at": "2026-01-26T19:38:16.753424300Z", + "finished_at": "2026-01-26T19:39:06.588120002Z" }, "t_010_connect": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_010_connect", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Event\")]\n public partial struct Event\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public int Id;\n public string Kind;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientConnected)]\n public static void ClientConnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"connected\" });\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)]\n public static void ClientDisconnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"disconnected\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Event\", Public = true)]\n public partial struct Event\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public int Id;\n public string Kind;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientConnected)]\n public static void ClientConnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"connected\" });\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)]\n public static void ClientDisconnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"disconnected\" });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-010-connect-golden", @@ -2710,25 +2763,25 @@ "llm_db": "basics-t-010-connect-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-23T20:19:23.574032624Z", - "finished_at": "2026-01-23T20:20:05.908027898Z" + "started_at": "2026-01-26T19:37:47.380111761Z", + "finished_at": "2026-01-26T19:39:03.248030401Z" }, "t_011_helper_function": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_011_helper_function", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int Sum;\n }\n\n public static int Add(int a, int b)\n {\n return a + b;\n }\n\n [SpacetimeDB.Reducer]\n public static void ComputeSum(ReducerContext ctx, int id, int a, int b)\n {\n ctx.Db.Result.Insert(new Result { Id = id, Sum = Add(a, b) });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int Sum;\n }\n\n private static int Add(int a, int b)\n {\n return a + b;\n }\n\n [SpacetimeDB.Reducer]\n public static void ComputeSum(ReducerContext ctx, int id, int a, int b)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Sum = Add(a, b)\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -2753,7 +2806,7 @@ "llm_db": "basics-t-011-helper-function-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -2773,23 +2826,23 @@ "llm_out": "Id | Sum ----+----- 1 | 5", "query": "SELECT Id, Sum FROM Result WHERE Id=1", "reducer": "ComputeSum", - "server": "http://127.0.0.1:41045" + "server": "http://127.0.0.1:44935" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:21:05.392014348Z", - "finished_at": "2026-01-23T20:21:51.189712882Z" + "started_at": "2026-01-26T19:40:22.292081947Z", + "finished_at": "2026-01-26T19:41:08.915943296Z" }, "t_012_spacetime_product_type": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_012_spacetime_product_type", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Score\n {\n public int Left;\n public int Right;\n }\n\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Score Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetScore(ReducerContext ctx, int id, int left, int right)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = new Score { Left = left, Right = right }\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Score\n {\n public int Left;\n public int Right;\n }\n\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Score Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetScore(ReducerContext ctx, int id, int left, int right)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = new Score\n {\n Left = left,\n Right = right\n }\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -2797,19 +2850,6 @@ "work_dir_golden": "target/llm-runs/schema/t_012_spacetime_product_type/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_012_spacetime_product_type/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-012-spacetime-product-type-golden", - "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true - } - }, "product_type_row_parity": { "pass": true, "partial": 1.0, @@ -2825,7 +2865,7 @@ "llm_out": "Id | Value ----+----------------------- 1 | (Left = 2, Right = 3)", "query": "SELECT Id, Value FROM Result WHERE Id=1", "reducer": "SetScore", - "server": "http://127.0.0.1:41045" + "server": "http://127.0.0.1:44935" } }, "product_type_row_count": { @@ -2836,21 +2876,34 @@ "expected": 1, "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-012-spacetime-product-type-golden", + "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44935", + "tables_diff": null, + "tables_equal": true + } } }, "vendor": "openai", - "started_at": "2026-01-23T20:18:54.161733902Z", - "finished_at": "2026-01-23T20:19:36.893826573Z" + "started_at": "2026-01-26T19:37:30.236090594Z", + "finished_at": "2026-01-26T19:38:16.753346626Z" }, "t_013_spacetime_sum_type": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_013_spacetime_sum_type", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetCircle(ReducerContext ctx, int id, int radius)\n {\n var value = new Shape.Circle(new Circle { Radius = radius });\n ctx.Db.Result.Insert(new Result { Id = id, Value = value });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetCircle(ReducerContext ctx, int id, int radius)\n {\n var shape = new Shape.Circle(new Circle { Radius = radius });\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = shape\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-013-spacetime-sum-type-golden", @@ -2858,28 +2911,6 @@ "work_dir_golden": "target/llm-runs/schema/t_013_spacetime_sum_type/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_013_spacetime_sum_type/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-013-spacetime-sum-type-golden", - "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true - } - }, - "sum_type_row_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" - } - }, "sum_type_row_parity": { "pass": true, "partial": 1.0, @@ -2894,7 +2925,16 @@ "llm_out": "Id | Value ----+-------------------------- 1 | (Circle = (Radius = 10))", "query": "SELECT Id, Value FROM Result WHERE Id=1", "reducer": "SetCircle", - "server": "http://127.0.0.1:41045" + "server": "http://127.0.0.1:44935" + } + }, + "sum_type_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" } }, "schema_parity": { @@ -2905,27 +2945,18 @@ "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } - }, - "sum_type_row_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" - } } }, "vendor": "openai", - "started_at": "2026-01-23T20:17:49.057528012Z", - "finished_at": "2026-01-23T20:18:46.199910007Z" + "started_at": "2026-01-26T19:35:59.196578278Z", + "finished_at": "2026-01-26T19:37:03.535790946Z" }, "t_014_elementary_columns": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_014_elementary_columns", "lang": "csharp", "golden_published": true, @@ -2940,6 +2971,14 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/csharp/server/gpt-5/llm", "scorer_details": { + "elementary_columns_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2000e37e733499f47b57d9f488477b94fccf2e4c5c6c32182171721cbaba64a/sql)\n", + "phase": "sql_golden" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2948,7 +2987,7 @@ "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -2957,32 +2996,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c200c583183a5879f79de7a06c7395893137fa8a834f830859f2ee7a4c9e10d4/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c200e70d6c47b9f5b97a9584014efb7008b4c312687bfdbfe1b0ee1891420453/sql)\n", "phase": "sql" } - }, - "elementary_columns_row_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2008dfd963859de34e7ba657c3416cbcee034a702128f54b0cb0b0b03aa914f/sql)\n", - "phase": "sql_golden" - } } }, "vendor": "openai", - "started_at": "2026-01-23T20:18:46.199983893Z", - "finished_at": "2026-01-23T20:19:29.507804243Z" + "started_at": "2026-01-26T19:37:03.535862900Z", + "finished_at": "2026-01-26T19:37:59.026960569Z" }, "t_015_product_type_columns": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_015_product_type_columns", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Address\n {\n public string Street;\n public int Zip;\n }\n\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Profile\", Public = true)]\n public partial struct Profile\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Address Home;\n public Address Work;\n public Position Pos;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n if (ctx.Db.Profile.Id.Find(1) == null)\n {\n ctx.Db.Profile.Insert(new Profile\n {\n Id = 1,\n Home = new Address { Street = \"1 Main\", Zip = 11111 },\n Work = new Address { Street = \"2 Broad\", Zip = 22222 },\n Pos = new Position { X = 7, Y = 9 },\n });\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Address\n {\n public string Street;\n public int Zip;\n }\n\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Profile\", Public = true)]\n public partial struct Profile\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Address Home;\n public Address Work;\n public Position Pos;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Profile.Insert(new Profile\n {\n Id = 1,\n Home = new Address { Street = \"1 Main\", Zip = 11111 },\n Work = new Address { Street = \"2 Broad\", Zip = 22222 },\n Pos = new Position { X = 7, Y = 9 }\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-015-product-type-columns-golden", @@ -2990,6 +3021,19 @@ "work_dir_golden": "target/llm-runs/schema/t_015_product_type_columns/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_015_product_type_columns/csharp/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-015-product-type-columns-golden", + "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44935", + "tables_diff": null, + "tables_equal": true + } + }, "product_type_columns_row_count": { "pass": true, "partial": 1.0, @@ -3010,86 +3054,52 @@ "llm_out": "Id | Home | Work | Pos ----+----------------------------------+-----------------------------------+---------------- 1 | (Street = \"1 Main\", Zip = 11111) | (Street = \"2 Broad\", Zip = 22222) | (X = 7, Y = 9)", "query": "SELECT Id, Home, Work, Pos FROM Profile WHERE Id=1", "reducer": "Seed", - "server": "http://127.0.0.1:41045" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-015-product-type-columns-golden", - "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:44935" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:18:11.292039093Z", - "finished_at": "2026-01-23T20:18:54.161647622Z" + "started_at": "2026-01-26T19:36:38.953458698Z", + "finished_at": "2026-01-26T19:37:30.236009816Z" }, "t_016_sum_type_columns": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_016_sum_type_columns", "lang": "csharp", - "golden_published": true, + "golden_published": false, "model_name": "GPT-5", - "total_tests": 3, - "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Drawing\")]\n public partial struct Drawing\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape A;\n public Shape B;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Drawing.Insert(new Drawing\n {\n Id = 1,\n A = new Shape.Circle(new Circle { Radius = 10 }),\n B = new Shape.Rectangle(new Rectangle { Width = 4, Height = 6 })\n });\n }\n}", + "total_tests": 1, + "passed_tests": 0, + "llm_output": null, "category": "schema", "route_api_model": "gpt-5", - "golden_db": "schema-t-016-sum-type-columns-golden", - "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", - "work_dir_golden": "target/llm-runs/schema/t_016_sum_type_columns/csharp/server/golden", - "work_dir_llm": "target/llm-runs/schema/t_016_sum_type_columns/csharp/server/gpt-5/llm", + "golden_db": null, + "llm_db": null, + "work_dir_golden": null, + "work_dir_llm": null, "scorer_details": { - "sum_type_columns_row_count": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c200b1fbaa5b44721798298318bab63a7fcd80d50f6e47060d881bfa066b8642/sql)\n", - "phase": "sql" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-016-sum-type-columns-golden", - "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true - } - }, - "sum_type_columns_row_parity": { + "publish_error": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2003b0da13c17c6220fd590cdb5d23015a0e698b01b6c6ecbfd10b5aabbbf4c/sql)\n", - "phase": "sql_golden" + "error": "LLM call timed out", + "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:16:40.802337426Z", - "finished_at": "2026-01-23T20:18:08.899029179Z" + "started_at": "2026-01-26T19:41:35.359543125Z", + "finished_at": "2026-01-26T19:41:35.359543125Z" }, "t_017_scheduled_columns": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_017_scheduled_columns", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 2, "passed_tests": 1, - "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [PrimaryKey, AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [Reducer]\n public static void Tick(ReducerContext ctx, TickTimer timer)\n {\n // Scheduled tick handler (no-op)\n }\n\n [Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n if (ctx.Db.TickTimer.Count == 0)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMicroseconds(50_000))\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -3105,7 +3115,7 @@ "llm_db": "schema-t-017-scheduled-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -3114,24 +3124,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `tick_timer`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2000932373ef07be1f77db87f24b98a9819f6033c40da69c914e654c807ead2/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `tick_timer`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2004563b2a3af718eb5a6d78c0e16523a6ad57949ac9dd820dbc2c2e11c8842/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:16:40.797164170Z", - "finished_at": "2026-01-23T20:18:08.735264338Z" + "started_at": "2026-01-26T19:35:08.495907944Z", + "finished_at": "2026-01-26T19:36:38.949408263Z" }, "t_018_constraints": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_018_constraints", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Account\", Public = true)]\n public partial struct Account\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n\n [SpacetimeDB.Unique]\n public string Email;\n\n [SpacetimeDB.Index.BTree(Name = \"by_name\")]\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Account.Insert(new Account { Id = 1, Email = \"a@example.com\", Name = \"Alice\" });\n ctx.Db.Account.Insert(new Account { Id = 2, Email = \"b@example.com\", Name = \"Bob\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Account\", Public = true)]\n [SpacetimeDB.Index.BTree(Name = \"by_name\", Columns = new[] { \"Name\" })]\n public partial struct Account\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n [SpacetimeDB.Unique]\n public string Email;\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Account.Insert(new Account { Id = 1, Email = \"a@example.com\", Name = \"Alice\" });\n ctx.Db.Account.Insert(new Account { Id = 2, Email = \"b@example.com\", Name = \"Bob\" });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-018-constraints-golden", @@ -3139,6 +3149,15 @@ "work_dir_golden": "target/llm-runs/schema/t_018_constraints/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_018_constraints/csharp/server/gpt-5/llm", "scorer_details": { + "constraints_seed_two_rows": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Account WHERE Id=2" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -3147,7 +3166,7 @@ "llm_db": "schema-t-018-constraints-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -3163,45 +3182,23 @@ "llm_out": "Id | Email | Name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", "query": "SELECT Id, Email, Name FROM Account WHERE Id=1", "reducer": "Seed", - "server": "http://127.0.0.1:41045" - } - }, - "constraints_seed_two_rows": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Account WHERE Id=2" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-018-constraints-golden", - "llm_db": "schema-t-018-constraints-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:34379", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:44935" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:16:40.794071431Z", - "finished_at": "2026-01-23T20:18:11.291994106Z" + "started_at": "2026-01-26T19:35:08.491947971Z", + "finished_at": "2026-01-26T19:35:59.196533076Z" }, "t_019_many_to_many": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_019_many_to_many", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 5, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int UserId;\n public string Name;\n }\n\n [SpacetimeDB.Table(Name = \"Group\")]\n public partial struct Group\n {\n [SpacetimeDB.PrimaryKey]\n public int GroupId;\n public string Title;\n }\n\n [SpacetimeDB.Table(Name = \"Membership\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user\", Columns = new[] { \"UserId\" })]\n [SpacetimeDB.Index.BTree(Name = \"by_group\", Columns = new[] { \"GroupId\" })]\n public partial struct Membership\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int GroupId;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n foreach (var m in ctx.Db.Membership.Iter())\n {\n ctx.Db.Membership.Id.Delete(m.Id);\n }\n foreach (var u in ctx.Db.User.Iter())\n {\n ctx.Db.User.UserId.Delete(u.UserId);\n }\n foreach (var g in ctx.Db.Group.Iter())\n {\n ctx.Db.Group.GroupId.Delete(g.GroupId);\n }\n\n ctx.Db.User.Insert(new User { UserId = 1, Name = \"Alice\" });\n ctx.Db.User.Insert(new User { UserId = 2, Name = \"Bob\" });\n\n ctx.Db.Group.Insert(new Group { GroupId = 10, Title = \"Admin\" });\n ctx.Db.Group.Insert(new Group { GroupId = 20, Title = \"Dev\" });\n\n ctx.Db.Membership.Insert(new Membership { Id = 1, UserId = 1, GroupId = 10 });\n ctx.Db.Membership.Insert(new Membership { Id = 2, UserId = 1, GroupId = 20 });\n ctx.Db.Membership.Insert(new Membership { Id = 3, UserId = 2, GroupId = 20 });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int UserId;\n public string Name;\n }\n\n [SpacetimeDB.Table(Name = \"Group\", Public = true)]\n public partial struct Group\n {\n [SpacetimeDB.PrimaryKey]\n public int GroupId;\n public string Title;\n }\n\n [SpacetimeDB.Table(Name = \"Membership\", Public = true)]\n [SpacetimeDB.Index.BTree(Name = \"by_user\", Columns = new[] { \"UserId\" })]\n [SpacetimeDB.Index.BTree(Name = \"by_group\", Columns = new[] { \"GroupId\" })]\n public partial struct Membership\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int GroupId;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n // Ensure exactly these rows by clearing existing data first\n foreach (var m in ctx.Db.Membership.Iter())\n {\n ctx.Db.Membership.Id.Delete(m.Id);\n }\n foreach (var u in ctx.Db.User.Iter())\n {\n ctx.Db.User.UserId.Delete(u.UserId);\n }\n foreach (var g in ctx.Db.Group.Iter())\n {\n ctx.Db.Group.GroupId.Delete(g.GroupId);\n }\n\n // Users\n ctx.Db.User.Insert(new User { UserId = 1, Name = \"Alice\" });\n ctx.Db.User.Insert(new User { UserId = 2, Name = \"Bob\" });\n\n // Groups\n ctx.Db.Group.Insert(new Group { GroupId = 10, Title = \"Admin\" });\n ctx.Db.Group.Insert(new Group { GroupId = 20, Title = \"Dev\" });\n\n // Memberships\n ctx.Db.Membership.Insert(new Membership { Id = 1, UserId = 1, GroupId = 10 });\n ctx.Db.Membership.Insert(new Membership { Id = 2, UserId = 1, GroupId = 20 });\n ctx.Db.Membership.Insert(new Membership { Id = 3, UserId = 2, GroupId = 20 });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-019-many-to-many-golden", @@ -3209,6 +3206,15 @@ "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/csharp/server/gpt-5/llm", "scorer_details": { + "memberships_three_rows": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM Membership" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -3217,7 +3223,7 @@ "llm_db": "schema-t-019-many-to-many-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } @@ -3231,22 +3237,13 @@ "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=2 AND GroupId=20" } }, - "memberships_three_rows": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM Membership" - } - }, "m2m_has_1_20": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=1 AND GroupId=20" + "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=2 AND GroupId=20" } }, "m2m_has_1_10": { @@ -3260,18 +3257,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-23T20:18:08.899074821Z", - "finished_at": "2026-01-23T20:19:10.793593915Z" + "started_at": "2026-01-26T19:36:32.689581659Z", + "finished_at": "2026-01-26T19:37:37.167783708Z" }, "t_020_ecs": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_020_ecs", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Entity\", Public = true)]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n }\n\n [SpacetimeDB.Table(Name = \"Position\", Public = true)]\n public partial struct Position\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Velocity\", Public = true)]\n public partial struct Velocity\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int VX;\n public int VY;\n }\n\n [SpacetimeDB.Table(Name = \"NextPosition\", Public = true)]\n public partial struct NextPosition\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n // Entity 1\n if (ctx.Db.Entity.Id.Find(1) is not Entity)\n {\n ctx.Db.Entity.Insert(new Entity { Id = 1 });\n }\n if (ctx.Db.Position.EntityId.Find(1) is Position p1)\n {\n p1.X = 0;\n p1.Y = 0;\n ctx.Db.Position.EntityId.Update(p1);\n }\n else\n {\n ctx.Db.Position.Insert(new Position { EntityId = 1, X = 0, Y = 0 });\n }\n if (ctx.Db.Velocity.EntityId.Find(1) is Velocity v1)\n {\n v1.VX = 1;\n v1.VY = 0;\n ctx.Db.Velocity.EntityId.Update(v1);\n }\n else\n {\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 1, VX = 1, VY = 0 });\n }\n\n // Entity 2\n if (ctx.Db.Entity.Id.Find(2) is not Entity)\n {\n ctx.Db.Entity.Insert(new Entity { Id = 2 });\n }\n if (ctx.Db.Position.EntityId.Find(2) is Position p2)\n {\n p2.X = 10;\n p2.Y = 0;\n ctx.Db.Position.EntityId.Update(p2);\n }\n else\n {\n ctx.Db.Position.Insert(new Position { EntityId = 2, X = 10, Y = 0 });\n }\n if (ctx.Db.Velocity.EntityId.Find(2) is Velocity v2)\n {\n v2.VX = -2;\n v2.VY = 3;\n ctx.Db.Velocity.EntityId.Update(v2);\n }\n else\n {\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 2, VX = -2, VY = 3 });\n }\n }\n\n [SpacetimeDB.Reducer]\n public static void Step(ReducerContext ctx)\n {\n foreach (var pos in ctx.Db.Position.Iter())\n {\n var vOpt = ctx.Db.Velocity.EntityId.Find(pos.EntityId);\n if (vOpt is Velocity vel)\n {\n int nx = pos.X + vel.VX;\n int ny = pos.Y + vel.VY;\n\n var npOpt = ctx.Db.NextPosition.EntityId.Find(pos.EntityId);\n if (npOpt is NextPosition np)\n {\n np.X = nx;\n np.Y = ny;\n ctx.Db.NextPosition.EntityId.Update(np);\n }\n else\n {\n ctx.Db.NextPosition.Insert(new NextPosition\n {\n EntityId = pos.EntityId,\n X = nx,\n Y = ny\n });\n }\n }\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Entity\", Public = true)]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n }\n\n [SpacetimeDB.Table(Name = \"Position\", Public = true)]\n public partial struct Position\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Velocity\", Public = true)]\n public partial struct Velocity\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int VX;\n public int VY;\n }\n\n [SpacetimeDB.Table(Name = \"NextPosition\", Public = true)]\n public partial struct NextPosition\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Entity.Insert(new Entity { Id = 1 });\n ctx.Db.Position.Insert(new Position { EntityId = 1, X = 0, Y = 0 });\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 1, VX = 1, VY = 0 });\n\n ctx.Db.Entity.Insert(new Entity { Id = 2 });\n ctx.Db.Position.Insert(new Position { EntityId = 2, X = 10, Y = 0 });\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 2, VX = -2, VY = 3 });\n }\n\n [SpacetimeDB.Reducer]\n public static void Step(ReducerContext ctx)\n {\n foreach (var pos in ctx.Db.Position.Iter())\n {\n if (ctx.Db.Velocity.EntityId.Find(pos.EntityId) is Velocity vel)\n {\n int nx = pos.X + vel.VX;\n int ny = pos.Y + vel.VY;\n\n if (ctx.Db.NextPosition.EntityId.Find(pos.EntityId) is NextPosition np)\n {\n np.X = nx;\n np.Y = ny;\n ctx.Db.NextPosition.EntityId.Update(np);\n }\n else\n {\n ctx.Db.NextPosition.Insert(new NextPosition { EntityId = pos.EntityId, X = nx, Y = ny });\n }\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-020-ecs-golden", @@ -3279,65 +3276,65 @@ "work_dir_golden": "target/llm-runs/schema/t_020_ecs/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_020_ecs/csharp/server/gpt-5/llm", "scorer_details": { - "ecs_next_pos_entity1": { - "pass": false, - "partial": 0.0, + "schema_parity": { + "pass": true, + "partial": 1.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", - "phase": "sql" + "golden_db": "schema-t-020-ecs-golden", + "llm_db": "schema-t-020-ecs-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:44935", + "tables_diff": null, + "tables_equal": true } }, "ecs_seed_positions_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", "phase": "sql" } }, - "ecs_next_pos_entity2": { + "ecs_step_next_positions_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", "phase": "sql" } }, - "ecs_step_next_positions_count": { + "ecs_next_pos_entity2": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41045/v1/database/c2005b7d5d9b2b6b33a4a581ebd8661a3b0380c077f59eee8e552ef3c67ff1b9/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", "phase": "sql" } }, - "schema_parity": { - "pass": true, - "partial": 1.0, + "ecs_next_pos_entity1": { + "pass": false, + "partial": 0.0, "notes": { - "golden_db": "schema-t-020-ecs-golden", - "llm_db": "schema-t-020-ecs-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:41045", - "tables_diff": null, - "tables_equal": true + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", + "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:18:08.902649901Z", - "finished_at": "2026-01-23T20:19:23.573927579Z" + "started_at": "2026-01-26T19:36:38.949546269Z", + "finished_at": "2026-01-26T19:37:47.379943704Z" }, "t_021_multi_column_index": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "task": "t_021_multi_column_index", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Log\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user_day\", Columns = [\"UserId\", \"Day\"])]\n public partial struct Log\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int Day;\n public string Message;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Log.Insert(new Log { Id = 1, UserId = 7, Day = 1, Message = \"a\" });\n ctx.Db.Log.Insert(new Log { Id = 2, UserId = 7, Day = 2, Message = \"b\" });\n ctx.Db.Log.Insert(new Log { Id = 3, UserId = 9, Day = 1, Message = \"c\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Log\", Public = true)]\n [SpacetimeDB.Index.BTree(Name = \"by_user_day\", Columns = new[] { \"UserId\", \"Day\" })]\n public partial struct Log\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int Day;\n public string Message;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Log.Insert(new Log { Id = 1, UserId = 7, Day = 1, Message = \"a\" });\n ctx.Db.Log.Insert(new Log { Id = 2, UserId = 7, Day = 2, Message = \"b\" });\n ctx.Db.Log.Insert(new Log { Id = 3, UserId = 9, Day = 1, Message = \"c\" });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-021-multi-column-index-golden", @@ -3345,6 +3342,15 @@ "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/csharp/server/gpt-5/llm", "scorer_details": { + "mcindex_seed_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM Log" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -3353,20 +3359,11 @@ "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41045", + "server": "http://127.0.0.1:44935", "tables_diff": null, "tables_equal": true } }, - "mcindex_lookup_u7_d2": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2" - } - }, "mcindex_lookup_u7_d1": { "pass": true, "partial": 1.0, @@ -3376,19 +3373,19 @@ "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=1" } }, - "mcindex_seed_count": { + "mcindex_lookup_u7_d2": { "pass": true, "partial": 1.0, "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM Log" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2" } } }, "vendor": "openai", - "started_at": "2026-01-23T20:16:40.799865241Z", - "finished_at": "2026-01-23T20:17:49.057471707Z" + "started_at": "2026-01-26T19:35:08.500770472Z", + "finished_at": "2026-01-26T19:36:32.689520614Z" } } } diff --git a/docs/llms/docs-benchmark-summary.json b/docs/llms/docs-benchmark-summary.json index 8e7f8400b57..fa057f8e85f 100644 --- a/docs/llms/docs-benchmark-summary.json +++ b/docs/llms/docs-benchmark-summary.json @@ -1,11 +1,11 @@ { "version": 1, - "generated_at": "2026-01-23T20:21:59.670Z", + "generated_at": "2026-01-26T19:41:35.586Z", "by_language": { "csharp": { "modes": { "docs": { - "hash": "0bdd5572150f1bebf8032e2007d3a7644df903777de6c1ad070cab80e77b3ed2", + "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", "models": { "GPT-5": { "categories": { @@ -19,20 +19,20 @@ }, "schema": { "tasks": 10, - "total_tests": 34, - "passed_tests": 25, - "pass_pct": 73.52941, - "task_pass_equiv": 7.3666663, - "task_pass_pct": 73.666664 + "total_tests": 32, + "passed_tests": 24, + "pass_pct": 75.0, + "task_pass_equiv": 7.033333, + "task_pass_pct": 70.33333 } }, "totals": { "tasks": 22, - "total_tests": 61, - "passed_tests": 52, - "pass_pct": 85.2459, - "task_pass_equiv": 19.366667, - "task_pass_pct": 88.030304 + "total_tests": 59, + "passed_tests": 51, + "pass_pct": 86.44068, + "task_pass_equiv": 19.033333, + "task_pass_pct": 86.515144 } } } @@ -42,7 +42,7 @@ "rust": { "modes": { "docs": { - "hash": "315390340d7551db2791f061b9bff7602dc13350b7a4caee6aca61ef97867ec9", + "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", "models": { "GPT-5": { "categories": { @@ -56,20 +56,20 @@ }, "schema": { "tasks": 10, - "total_tests": 14, - "passed_tests": 0, - "pass_pct": 0.0, - "task_pass_equiv": 0.0, - "task_pass_pct": 0.0 + "total_tests": 18, + "passed_tests": 4, + "pass_pct": 22.222221, + "task_pass_equiv": 1.25, + "task_pass_pct": 12.5 } }, "totals": { "tasks": 22, - "total_tests": 41, - "passed_tests": 5, - "pass_pct": 12.195122, - "task_pass_equiv": 1.3333334, - "task_pass_pct": 6.060606 + "total_tests": 45, + "passed_tests": 9, + "pass_pct": 20.0, + "task_pass_equiv": 2.5833335, + "task_pass_pct": 11.742425 } } } @@ -90,19 +90,19 @@ "schema": { "tasks": 10, "total_tests": 34, - "passed_tests": 26, - "pass_pct": 76.47059, - "task_pass_equiv": 7.5333333, - "task_pass_pct": 75.333336 + "passed_tests": 24, + "pass_pct": 70.588234, + "task_pass_equiv": 6.8666663, + "task_pass_pct": 68.666664 } }, "totals": { "tasks": 22, "total_tests": 61, - "passed_tests": 51, - "pass_pct": 83.60656, - "task_pass_equiv": 17.533333, - "task_pass_pct": 79.69697 + "passed_tests": 49, + "pass_pct": 80.327866, + "task_pass_equiv": 16.866667, + "task_pass_pct": 76.666664 } } } From 85dc1dc4fb5494269211e30092198460826b1f7d Mon Sep 17 00:00:00 2001 From: joshua-spacetime Date: Wed, 28 Jan 2026 09:53:35 -0800 Subject: [PATCH 3/8] [2.0 Breaking] `Sender` changes for C# modules (#4143) # Description of Changes Make `Sender` a method on [Reducer|View|Procedure|Tx]Context in C#. Equivalent changes to https://github.com/clockworklabs/SpacetimeDB/pull/4101. # API and ABI breaking changes API breaking # Expected complexity level and risk 1 # Testing Pure refactor, no additional testing. --- .../diag/snapshots/Module#FFI.verified.cs | 21 +++++++++--- .../server/snapshots/Module#FFI.verified.cs | 21 +++++++++--- crates/bindings-csharp/Codegen/Module.cs | 20 +++++++++--- .../Runtime/Internal/TxContext.cs | 7 ++-- .../Runtime/ProcedureContext.cs | 10 ++++-- demo/Blackholio/server-csharp/Lib.cs | 16 +++++----- .../00400-key-architecture.md | 2 +- .../00300-tutorials/00100-chat-app.md | 12 +++---- .../00300-unity-tutorial/00300-part-2.md | 4 +-- .../00300-unity-tutorial/00400-part-3.md | 10 +++--- .../00300-unity-tutorial/00500-part-4.md | 4 +-- .../00400-unreal-tutorial/00300-part-2.md | 4 +-- .../00400-unreal-tutorial/00400-part-3.md | 10 +++--- .../00400-unreal-tutorial/00500-part-4.md | 4 +-- .../00100-databases/00500-cheat-sheet.md | 4 +-- .../00300-reducers/00400-reducer-context.md | 4 +-- .../00300-reducers/00500-lifecycle.md | 6 ++-- .../00300-reducers/00600-error-handling.md | 2 +- .../00200-functions/00500-views.md | 6 ++-- docs/docs/00200-core-concepts/00300-tables.md | 2 +- .../00300-tables/00210-file-storage.md | 2 +- .../00300-tables/00400-access-permissions.md | 8 ++--- .../00100-how-to/00300-logging.md | 4 +-- docs/static/llms.md | 32 +++++++++---------- modules/module-test-cs/Lib.cs | 6 ++-- modules/sdk-test-connect-disconnect-cs/Lib.cs | 4 +-- modules/sdk-test-cs/Lib.cs | 8 ++--- .../examples~/regression-tests/server/Lib.cs | 24 +++++++------- templates/chat-console-cs/spacetimedb/Lib.cs | 12 +++---- 29 files changed, 155 insertions(+), 114 deletions(-) diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs index 90eb00d3eaf..0731b890923 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs @@ -1,4 +1,4 @@ -//HintName: FFI.cs +//HintName: FFI.cs // #nullable enable // The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type. @@ -17,7 +17,6 @@ namespace SpacetimeDB { public sealed record ReducerContext : DbContext, Internal.IReducerContext { - public readonly Identity Sender; public readonly ConnectionId? ConnectionId; public readonly Random Rng; public readonly Timestamp Timestamp; @@ -29,6 +28,8 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // We need this property to be non-static for parity with client SDK. public Identity Identity => Internal.IReducerContext.GetIdentity(); + private readonly Identity _sender; + internal ReducerContext( Identity identity, ConnectionId? connectionId, @@ -37,7 +38,7 @@ internal ReducerContext( AuthCtx? senderAuth = null ) { - Sender = identity; + _sender = identity; ConnectionId = connectionId; Rng = random; Timestamp = time; @@ -45,6 +46,11 @@ internal ReducerContext( CounterUuid = 0; } + /// + /// The identity of the client that invoked the reducer. + /// + public Identity Sender() => _sender; + /// /// Create a new random `v4` using the built-in RNG. /// @@ -209,13 +215,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase public sealed record ViewContext : DbContext, Internal.IViewContext { - public Identity Sender { get; } + private readonly Identity _sender; internal ViewContext(Identity sender, Internal.LocalReadOnly db) : base(db) { - Sender = sender; + _sender = sender; } + + /// + /// The identity of the client that invoked the view. + /// + public Identity Sender() => _sender; } public sealed record AnonymousViewContext diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs index f4d86c2ddbc..86a559890c1 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs @@ -1,4 +1,4 @@ -//HintName: FFI.cs +//HintName: FFI.cs // #nullable enable // The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type. @@ -17,7 +17,6 @@ namespace SpacetimeDB { public sealed record ReducerContext : DbContext, Internal.IReducerContext { - public readonly Identity Sender; public readonly ConnectionId? ConnectionId; public readonly Random Rng; public readonly Timestamp Timestamp; @@ -29,6 +28,8 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // We need this property to be non-static for parity with client SDK. public Identity Identity => Internal.IReducerContext.GetIdentity(); + private readonly Identity _sender; + internal ReducerContext( Identity identity, ConnectionId? connectionId, @@ -37,7 +38,7 @@ internal ReducerContext( AuthCtx? senderAuth = null ) { - Sender = identity; + _sender = identity; ConnectionId = connectionId; Rng = random; Timestamp = time; @@ -45,6 +46,11 @@ internal ReducerContext( CounterUuid = 0; } + /// + /// The identity of the client that invoked the reducer. + /// + public Identity Sender() => _sender; + /// /// Create a new random `v4` using the built-in RNG. /// @@ -199,13 +205,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase public sealed record ViewContext : DbContext, Internal.IViewContext { - public Identity Sender { get; } + private readonly Identity _sender; internal ViewContext(Identity sender, Internal.LocalReadOnly db) : base(db) { - Sender = sender; + _sender = sender; } + + /// + /// The identity of the client that invoked the view. + /// + public Identity Sender() => _sender; } public sealed record AnonymousViewContext diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index 63331bba5b6..e927f8832a4 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -1737,7 +1737,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context) namespace SpacetimeDB { public sealed record ReducerContext : DbContext, Internal.IReducerContext { - public readonly Identity Sender; public readonly ConnectionId? ConnectionId; public readonly Random Rng; public readonly Timestamp Timestamp; @@ -1747,16 +1746,24 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // We need this property to be non-static for parity with client SDK. public Identity Identity => Internal.IReducerContext.GetIdentity(); + private readonly Identity _sender; + internal ReducerContext(Identity identity, ConnectionId? connectionId, Random random, Timestamp time, AuthCtx? senderAuth = null) { - Sender = identity; + _sender = identity; ConnectionId = connectionId; Rng = random; Timestamp = time; SenderAuth = senderAuth ?? AuthCtx.BuildFromSystemTables(connectionId, identity); CounterUuid = 0; } + + /// + /// The identity of the client that invoked the reducer. + /// + public Identity Sender() => _sender; + /// /// Create a new random `v4` using the built-in RNG. /// @@ -1891,13 +1898,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase { public sealed record ViewContext : DbContext, Internal.IViewContext { - public Identity Sender { get; } + private readonly Identity _sender; internal ViewContext(Identity sender, Internal.LocalReadOnly db) : base(db) { - Sender = sender; + _sender = sender; } + + /// + /// The identity of the client that invoked the view. + /// + public Identity Sender() => _sender; } public sealed record AnonymousViewContext : DbContext, Internal.IAnonymousViewContext diff --git a/crates/bindings-csharp/Runtime/Internal/TxContext.cs b/crates/bindings-csharp/Runtime/Internal/TxContext.cs index d5bea2febd9..f8465e78d56 100644 --- a/crates/bindings-csharp/Runtime/Internal/TxContext.cs +++ b/crates/bindings-csharp/Runtime/Internal/TxContext.cs @@ -9,13 +9,16 @@ public sealed class TxContext( Random rng ) { + private readonly Identity _sender = sender; + public Local Db { get; } = db; - public Identity Sender { get; } = sender; public ConnectionId? ConnectionId { get; } = connectionId; public Timestamp Timestamp { get; } = timestamp; public AuthCtx SenderAuth { get; } = senderAuth; public Random Rng { get; } = rng; + public Identity Sender() => _sender; + public TxContext WithTimestamp(Timestamp ts) => - new(Db, Sender, ConnectionId, ts, SenderAuth, Rng); + new(Db, _sender, ConnectionId, ts, SenderAuth, Rng); } diff --git a/crates/bindings-csharp/Runtime/ProcedureContext.cs b/crates/bindings-csharp/Runtime/ProcedureContext.cs index 4eb8583b7d5..1b878b8e549 100644 --- a/crates/bindings-csharp/Runtime/ProcedureContext.cs +++ b/crates/bindings-csharp/Runtime/ProcedureContext.cs @@ -10,8 +10,11 @@ public abstract class ProcedureContextBase( Timestamp time ) : Internal.IInternalProcedureContext { + private readonly Identity _sender = sender; + + public Identity Sender() => _sender; + public static Identity Identity => Internal.IProcedureContext.GetIdentity(); - public Identity Sender { get; } = sender; public ConnectionId? ConnectionId { get; } = connectionId; public Random Rng { get; } = random; public Timestamp Timestamp { get; private set; } = time; @@ -47,7 +50,7 @@ public Internal.TxContext EnterTxContext(long timestampMicros) txContext?.WithTimestamp(timestamp) ?? new Internal.TxContext( CreateLocal(), - Sender, + _sender, ConnectionId, timestamp, SenderAuth, @@ -229,8 +232,9 @@ public abstract class ProcedureTxContextBase(Internal.TxContext inner) internal void Refresh(Internal.TxContext inner) => Inner = inner; + public Identity Sender() => Inner.Sender(); + public LocalBase Db => (LocalBase)Inner.Db; - public Identity Sender => Inner.Sender; public ConnectionId? ConnectionId => Inner.ConnectionId; public Timestamp Timestamp => Inner.Timestamp; public AuthCtx SenderAuth => Inner.SenderAuth; diff --git a/demo/Blackholio/server-csharp/Lib.cs b/demo/Blackholio/server-csharp/Lib.cs index 20e26cf99e6..542a7040037 100644 --- a/demo/Blackholio/server-csharp/Lib.cs +++ b/demo/Blackholio/server-csharp/Lib.cs @@ -138,7 +138,7 @@ public static void Init(ReducerContext ctx) [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender); + var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender()); if (player != null) { ctx.Db.player.Insert(player.Value); @@ -157,7 +157,7 @@ public static void Connect(ReducerContext ctx) { ctx.Db.player.Insert(new Player { - identity = ctx.Sender, + identity = ctx.Sender(), name = "", }); } @@ -166,7 +166,7 @@ public static void Connect(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { var entity = ctx.Db.entity.entity_id.Find(circle.entity_id) ?? throw new Exception("Could not find circle"); @@ -183,7 +183,7 @@ public static void Disconnect(ReducerContext ctx) public static void EnterGame(ReducerContext ctx, string name) { Log.Info($"Creating player with name {name}"); - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); player.name = name; ctx.Db.player.identity.Update(player); SpawnPlayerInitialCircle(ctx, player.player_id); @@ -192,7 +192,7 @@ public static void EnterGame(ReducerContext ctx, string name) [Reducer] public static void Respawn(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("No such player found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("No such player found"); SpawnPlayerInitialCircle(ctx, player.player_id); } @@ -200,7 +200,7 @@ public static void Respawn(ReducerContext ctx) [Reducer] public static void Suicide(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("No such player found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("No such player found"); foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { @@ -246,7 +246,7 @@ public static Entity SpawnCircleAt(ReducerContext ctx, int player_id, int mass, [Reducer] public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id)) { var circle = c; @@ -449,7 +449,7 @@ public static void DestroyEntity(ReducerContext ctx, int entityId) [Reducer] public static void PlayerSplit(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Sender has no player"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Sender has no player"); List circles = ctx.Db.circle.player_id.Filter(player.player_id).ToList(); var circle_count = circles.Count; if (circle_count >= MAX_CIRCLES_PER_PLAYER) diff --git a/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md b/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md index 63eff91f7b0..59ba40c581f 100644 --- a/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md +++ b/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md @@ -439,7 +439,7 @@ A view can be written in C# like so: [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender) as Player; + return ctx.Db.Player.Identity.Find(ctx.Sender()) as Player; } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md b/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md index 06ef0c039ce..f8dc277f38c 100644 --- a/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md +++ b/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md @@ -322,7 +322,7 @@ public static void SetName(ReducerContext ctx, string name) { name = ValidateName(name); - if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) { user.Name = name; ctx.Db.User.Identity.Update(user); @@ -411,7 +411,7 @@ public static void SendMessage(ReducerContext ctx, string text) ctx.Db.Message.Insert( new Message { - Sender = ctx.Sender, + Sender = ctx.Sender(), Text = text, Sent = ctx.Timestamp, } @@ -504,9 +504,9 @@ In `spacetimedb/Lib.cs`, add to the `Module` class: [Reducer(ReducerKind.ClientConnected)] public static void ClientConnected(ReducerContext ctx) { - Log.Info($"Connect {ctx.Sender}"); + Log.Info($"Connect {ctx.Sender()}"); - if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) { user.Online = true; ctx.Db.User.Identity.Update(user); @@ -517,7 +517,7 @@ public static void ClientConnected(ReducerContext ctx) new User { Name = null, - Identity = ctx.Sender, + Identity = ctx.Sender(), Online = true, } ); @@ -527,7 +527,7 @@ public static void ClientConnected(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void ClientDisconnected(ReducerContext ctx) { - if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) { user.Online = false; ctx.Db.User.Identity.Update(user); diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md index b6766e12672..26f278f5051 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md @@ -335,7 +335,7 @@ Add this function to the `Module` class in `Lib.cs`: [Reducer] public static void Debug(ReducerContext ctx) { - Log.Info($"This reducer was called by {ctx.Sender}"); + Log.Info($"This reducer was called by {ctx.Sender()}"); } ``` @@ -444,7 +444,7 @@ Next let's connect our client to our database. Let's start by modifying our `Deb [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - Log.Info($"{ctx.Sender} just connected."); + Log.Info($"{ctx.Sender()} just connected."); } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md index ab95e71294d..f1a0c99aa0d 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md @@ -359,7 +359,7 @@ Next, modify your `Connect` reducer and add a new `Disconnect` reducer below it: [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender); + var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender()); if (player != null) { ctx.Db.player.Insert(player.Value); @@ -369,7 +369,7 @@ public static void Connect(ReducerContext ctx) { ctx.Db.player.Insert(new Player { - identity = ctx.Sender, + identity = ctx.Sender(), name = "", }); } @@ -378,7 +378,7 @@ public static void Connect(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); ctx.Db.logged_out_player.Insert(player); ctx.Db.player.identity.Delete(player.identity); } @@ -457,7 +457,7 @@ const int START_PLAYER_MASS = 15; public static void EnterGame(ReducerContext ctx, string name) { Log.Info($"Creating player with name {name}"); - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); player.name = name; ctx.Db.player.identity.Update(player); SpawnPlayerInitialCircle(ctx, player.player_id); @@ -579,7 +579,7 @@ Let's also modify our `disconnect` reducer to remove the circles from the arena [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); // Remove any circles from the arena foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md index 647efe78bcb..cdf062fd8d0 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md @@ -49,7 +49,7 @@ Next, add the following reducer to the `Module` class of your `Lib.cs` file. [Reducer] public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id)) { var circle = c; @@ -60,7 +60,7 @@ public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) } ``` -This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender` value is not set by the client. Instead `ctx.Sender` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. +This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender()` value is not set by the client. Instead `ctx.Sender()` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md index bde4659ba26..a97a65abec8 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md @@ -333,7 +333,7 @@ Add this function to the `Module` class in `Lib.cs`: [Reducer] public static void Debug(ReducerContext ctx) { - Log.Info($"This reducer was called by {ctx.Sender}"); + Log.Info($"This reducer was called by {ctx.Sender()}"); } ``` @@ -440,7 +440,7 @@ Next let's connect our client to our database. Let's start by modifying our `Deb [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - Log.Info($"{ctx.Sender} just connected."); + Log.Info($"{ctx.Sender()} just connected."); } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md index 192c7d3ebc8..d3543050874 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md @@ -352,7 +352,7 @@ Next, modify your `Connect` reducer and add a new `Disconnect` reducer below it: [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender); + var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender()); if (player != null) { ctx.Db.player.Insert(player.Value); @@ -362,7 +362,7 @@ public static void Connect(ReducerContext ctx) { ctx.Db.player.Insert(new Player { - identity = ctx.Sender, + identity = ctx.Sender(), name = "", }); } @@ -371,7 +371,7 @@ public static void Connect(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); ctx.Db.logged_out_player.Insert(player); ctx.Db.player.identity.Delete(player.identity); } @@ -446,7 +446,7 @@ const int START_PLAYER_MASS = 15; public static void EnterGame(ReducerContext ctx, string name) { Log.Info($"Creating player with name {name}"); - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); player.name = name; ctx.Db.player.identity.Update(player); SpawnPlayerInitialCircle(ctx, player.player_id); @@ -566,7 +566,7 @@ Let's also modify our `disconnect` reducer to remove the circles from the arena [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); // Remove any circles from the arena foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md index ae8eb620633..2acda18aac8 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md @@ -50,7 +50,7 @@ Next, add the following reducer to the `Module` class of your `Lib.cs` file. [Reducer] public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) { - var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id)) { var circle = c; @@ -61,7 +61,7 @@ public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) } ``` -This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender` value is not set by the client. Instead `ctx.Sender` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. +This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender()` value is not set by the client. Instead `ctx.Sender()` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. Let's start by building out a simple math library to help us do collision calculations. Create a new `math.rs` file in the `blackholio/spacetimedb/src` directory and add the following contents. Let's also move the `DbVector2` type from `lib.rs` into this file. diff --git a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md index e4754aca0e8..c7c8eafee96 100644 --- a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md +++ b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md @@ -457,7 +457,7 @@ using SpacetimeDB; [SpacetimeDB.View(Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender); + return ctx.Db.Player.Identity.Find(ctx.Sender()); } // Return multiple rows @@ -510,7 +510,7 @@ ctx.identity // Module's identity ```csharp ctx.Db // Database access -ctx.Sender // Identity of caller +ctx.Sender() // Identity of caller ctx.ConnectionId // ConnectionId? ctx.Timestamp // Timestamp ctx.Identity // Module's identity diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md index 38f447125d4..d789845ab29 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md @@ -145,7 +145,7 @@ public static partial class Module public static void UpdateScore(ReducerContext ctx, uint newScore) { // Get the caller's identity - Identity caller = ctx.Sender; + Identity caller = ctx.Sender(); // Find and update their player record if (ctx.Db.Player.Identity.Find(caller) is Player player) @@ -262,7 +262,7 @@ public static partial class Module public static void SendReminder(ReducerContext ctx, ScheduledTask task) { // Only allow the scheduler (module identity) to call this - if (ctx.Sender != ctx.Identity) + if (ctx.Sender() != ctx.Identity) { throw new Exception("This reducer can only be called by the scheduler"); } diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md index 20f43bc8394..605ad09dd09 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md @@ -110,7 +110,7 @@ spacetimedb.clientConnected((ctx) => { [SpacetimeDB.Reducer(ReducerKind.ClientConnected)] public static void OnConnect(ReducerContext ctx) { - Log.Info($"Client connected: {ctx.Sender}"); + Log.Info($"Client connected: {ctx.Sender()}"); // ctx.ConnectionId is guaranteed to be non-null var connId = ctx.ConnectionId!.Value; @@ -119,7 +119,7 @@ public static void OnConnect(ReducerContext ctx) ctx.Db.Session.Insert(new Session { ConnectionId = connId, - Identity = ctx.Sender, + Identity = ctx.Sender(), ConnectedAt = ctx.Timestamp }); } @@ -182,7 +182,7 @@ spacetimedb.clientDisconnected((ctx) => { [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)] public static void OnDisconnect(ReducerContext ctx) { - Log.Info($"Client disconnected: {ctx.Sender}"); + Log.Info($"Client disconnected: {ctx.Sender()}"); // ctx.ConnectionId is guaranteed to be non-null var connId = ctx.ConnectionId!.Value; diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md index 714f68d1110..661e5870853 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md @@ -61,7 +61,7 @@ Throw an exception: [SpacetimeDB.Reducer] public static void TransferCredits(ReducerContext ctx, ulong toUser, uint amount) { - var fromUser = ctx.Db.User.Id.Find(ctx.Sender); + var fromUser = ctx.Db.User.Id.Find(ctx.Sender()); if (fromUser == null) { throw new InvalidOperationException("User not found"); diff --git a/docs/docs/00200-core-concepts/00200-functions/00500-views.md b/docs/docs/00200-core-concepts/00200-functions/00500-views.md index 0603fa97dad..7b8c43ea1b7 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00500-views.md +++ b/docs/docs/00200-core-concepts/00200-functions/00500-views.md @@ -130,7 +130,7 @@ public static partial class Module [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender) as Player; + return ctx.Db.Player.Identity.Find(ctx.Sender()) as Player; } // Multiple rows: return a list @@ -283,7 +283,7 @@ spacetimedb.view( [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender); + return ctx.Db.Player.Identity.Find(ctx.Sender()); } ``` @@ -485,7 +485,7 @@ public partial class Module [SpacetimeDB.View(Name = "EntitiesInMyChunk", Public = true)] public static List EntitiesInMyChunk(ViewContext ctx) { - if (ctx.Db.Player.Identity.Find(ctx.Sender) is not Player player) + if (ctx.Db.Player.Identity.Find(ctx.Sender()) is not Player player) { return new List(); } diff --git a/docs/docs/00200-core-concepts/00300-tables.md b/docs/docs/00200-core-concepts/00300-tables.md index cf3727b18d8..c09cf9b832c 100644 --- a/docs/docs/00200-core-concepts/00300-tables.md +++ b/docs/docs/00200-core-concepts/00300-tables.md @@ -348,7 +348,7 @@ ctx.Db.Player.Insert(new Player { /* ... */ }); ctx.Db.LoggedOutPlayer.Insert(new Player { /* ... */ }); // Move a row between tables -var player = ctx.Db.LoggedOutPlayer.Identity.Find(ctx.Sender); +var player = ctx.Db.LoggedOutPlayer.Identity.Find(ctx.Sender()); if (player != null) { ctx.Db.Player.Insert(player.Value); diff --git a/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md b/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md index 33e617c542a..239737330c8 100644 --- a/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md +++ b/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md @@ -221,7 +221,7 @@ public static partial class Module ctx.Db.Document.Insert(new Document { Id = 0, // auto-increment - OwnerId = ctx.Sender, + OwnerId = ctx.Sender(), Filename = filename, MimeType = mimeType, SizeBytes = sizeBytes, diff --git a/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md b/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md index 0f3c83978ed..6fe4e6d9833 100644 --- a/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md +++ b/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md @@ -393,8 +393,8 @@ public partial class Module public static List MyMessages(ViewContext ctx) { // Look up messages by index where caller is sender or recipient - var sent = ctx.Db.Message.Sender.Filter(ctx.Sender).ToList(); - var received = ctx.Db.Message.Recipient.Filter(ctx.Sender).ToList(); + var sent = ctx.Db.Message.Sender.Filter(ctx.Sender()).ToList(); + var received = ctx.Db.Message.Recipient.Filter(ctx.Sender()).ToList(); sent.AddRange(received); return sent; } @@ -526,7 +526,7 @@ public partial class Module public static PublicUserProfile? MyProfile(ViewContext ctx) { // Look up the caller's account by their identity (unique index) - if (ctx.Db.UserAccount.Identity.Find(ctx.Sender) is not UserAccount user) + if (ctx.Db.UserAccount.Identity.Find(ctx.Sender()) is not UserAccount user) { return null; } @@ -676,7 +676,7 @@ public partial class Module public static List MyColleagues(ViewContext ctx) { // Find the caller's employee record by identity (unique index) - if (ctx.Db.Employee.Identity.Find(ctx.Sender) is not Employee me) + if (ctx.Db.Employee.Identity.Find(ctx.Sender()) is not Employee me) { return new List(); } diff --git a/docs/docs/00300-resources/00100-how-to/00300-logging.md b/docs/docs/00300-resources/00100-how-to/00300-logging.md index 1958b01634e..1b77fd7bcc7 100644 --- a/docs/docs/00300-resources/00100-how-to/00300-logging.md +++ b/docs/docs/00300-resources/00100-how-to/00300-logging.md @@ -69,7 +69,7 @@ public static partial class Module throw new ArgumentException("Value cannot be zero"); } - Log.Debug($"Debug information: ctx.Sender = {ctx.Sender}"); + Log.Debug($"Debug information: ctx.Sender() = {ctx.Sender()}"); } } ``` @@ -202,7 +202,7 @@ Include relevant context in your log messages: [SpacetimeDB.Reducer] public static void TransferCredits(ReducerContext ctx, ulong toUser, uint amount) { - Log.Info($"Credit transfer: from={ctx.Sender}, to={toUser}, amount={amount}"); + Log.Info($"Credit transfer: from={ctx.Sender()}, to={toUser}, amount={amount}"); // ... transfer logic } diff --git a/docs/static/llms.md b/docs/static/llms.md index 876a91b31ad..f35907bf85d 100644 --- a/docs/static/llms.md +++ b/docs/static/llms.md @@ -1449,7 +1449,7 @@ Reducers are the functions within your server module responsible for atomically - **Return Type:** Reducers should typically return `void`. Errors are signaled by throwing exceptions. - **Reducer Context:** The `ReducerContext` (`ctx`) provides access to: - `ctx.Db`: Handles for interacting with database tables. - - `ctx.Sender`: The `Identity` of the caller. + - `ctx.Sender()`: The `Identity` of the caller. - `ctx.Identity`: The `Identity` of the module itself. - `ctx.Timestamp`: The `Timestamp` of the invocation. - `ctx.ConnectionId`: The nullable `ConnectionId` of the caller. @@ -1478,7 +1478,7 @@ public static partial class Module [Reducer] public static void UpdatePlayerData(ReducerContext ctx, string? newName) { - var playerId = ctx.Sender; + var playerId = ctx.Sender(); // Find player by primary key var player = ctx.Db.player_state.PlayerId.Find(playerId); @@ -1521,10 +1521,10 @@ public static partial class Module if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name cannot be empty."); } - Log.Info($"Attempting to register player: {name} ({ctx.Sender})"); + Log.Info($"Attempting to register player: {name} ({ctx.Sender()})"); // Check if player identity or name already exists - if (ctx.Db.player_state.PlayerId.Find(ctx.Sender) != null || ctx.Db.player_state.Name.Find(name) != null) + if (ctx.Db.player_state.PlayerId.Find(ctx.Sender()) != null || ctx.Db.player_state.Name.Find(name) != null) { throw new Exception("Player already registered or name taken."); } @@ -1532,7 +1532,7 @@ public static partial class Module // Create new player instance var newPlayer = new PlayerState { - PlayerId = ctx.Sender, + PlayerId = ctx.Sender(), Name = name, Health = 100, Level = 1, @@ -1541,14 +1541,14 @@ public static partial class Module // Insert the new player. This will throw on constraint violation. ctx.Db.player_state.Insert(newPlayer); - Log.Info($"Player registered successfully: {ctx.Sender}"); + Log.Info($"Player registered successfully: {ctx.Sender()}"); } // Example: Basic reducer showing deletion [Reducer] public static void DeleteMyItems(ReducerContext ctx) { - var ownerId = ctx.Sender; + var ownerId = ctx.Sender(); int deletedCount = 0; // Find items by owner (Requires an index on OwnerId for efficiency) @@ -1632,13 +1632,13 @@ These reducers cannot take arguments beyond `&ReducerContext`. // Example init reducer is shown in Scheduled Reducers section [Reducer(ReducerKind.ClientConnected)] public static void HandleConnect(ReducerContext ctx) { - Log.Info($"Client connected: {ctx.Sender}"); + Log.Info($"Client connected: {ctx.Sender()}"); // ... setup initial state for ctx.sender ... } [Reducer(ReducerKind.ClientDisconnected)] public static void HandleDisconnect(ReducerContext ctx) { - Log.Info($"Client disconnected: {ctx.Sender}"); + Log.Info($"Client disconnected: {ctx.Sender()}"); // ... cleanup state for ctx.sender ... } ``` @@ -1692,7 +1692,7 @@ public static partial class Module public static void SendMessage(ReducerContext ctx, SendMessageSchedule scheduleArgs) { // Security check is important! - if (!ctx.Sender.Equals(ctx.Identity)) + if (!ctx.Sender().Equals(ctx.Identity)) { throw new Exception("Reducer SendMessage may not be invoked by clients, only via scheduling."); } @@ -1740,12 +1740,12 @@ public static partial class Module - **Best-Effort Scheduling:** Scheduled reducers are called on a best-effort basis and may be slightly delayed in their execution when a database is under heavy load. -- **Restricting Access (Security):** Scheduled reducers are normal reducers and _can_ still be called directly by clients. If a scheduled reducer should _only_ be called by the scheduler, it is crucial to begin the reducer with a check comparing the caller's identity (`ctx.Sender`) to the module's own identity (`ctx.Identity`). +- **Restricting Access (Security):** Scheduled reducers are normal reducers and _can_ still be called directly by clients. If a scheduled reducer should _only_ be called by the scheduler, it is crucial to begin the reducer with a check comparing the caller's identity (`ctx.Sender()`) to the module's own identity (`ctx.Identity`). ```csharp [Reducer] // Assuming linked via [Table(Scheduled=...)] public static void MyScheduledTask(ReducerContext ctx, MyScheduleArgs args) { - if (!ctx.Sender.Equals(ctx.Identity)) + if (!ctx.Sender().Equals(ctx.Identity)) { throw new Exception("Reducer MyScheduledTask may not be invoked by clients, only via scheduling."); } @@ -1757,7 +1757,7 @@ public static partial class Module ``` :::info Scheduled Reducers and Connections -Scheduled reducer calls originate from the SpacetimeDB scheduler itself, not from an external client connection. Therefore, within a scheduled reducer, `ctx.Sender` will be the module's own identity, and `ctx.ConnectionId` will be `null`. +Scheduled reducer calls originate from the SpacetimeDB scheduler itself, not from an external client connection. Therefore, within a scheduled reducer, `ctx.Sender()` will be the module's own identity, and `ctx.ConnectionId` will be `null`. ::: ##### Error Handling: Exceptions @@ -1827,7 +1827,7 @@ public static partial class Module [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender); + return ctx.Db.Player.Identity.Find(ctx.Sender()); } // View that returns all players at a specific level (same for all callers) @@ -1858,7 +1858,7 @@ public static partial class Module Views use one of two context types: -- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.Sender`. Use this when the view depends on who is querying it (e.g., "get my player"). +- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.Sender()`. Use this when the view depends on who is querying it (e.g., "get my player"). - **`AnonymousViewContext`**: Does not provide caller information. Use this when the view produces the same results regardless of who queries it (e.g., "get top 10 players"). Both contexts provide read-only access to tables and indexes through `ctx.Db`. @@ -1887,7 +1887,7 @@ The query builder provides a fluent API for constructing type-safe SQL queries: public static Query MyMessages(ViewContext ctx) { return ctx.Db.Message - .Filter(msg => msg.Sender == ctx.Sender) + .Filter(msg => msg.Sender == ctx.Sender()) .Build(); } diff --git a/modules/module-test-cs/Lib.cs b/modules/module-test-cs/Lib.cs index a8d7d7a05ba..72b69649960 100644 --- a/modules/module-test-cs/Lib.cs +++ b/modules/module-test-cs/Lib.cs @@ -219,7 +219,7 @@ static partial class Module [View(Name = "my_player", Public = true)] public static Player? my_player(ViewContext ctx) { - return (Player?)ctx.Db.player.identity.Find(ctx.Sender); + return (Player?)ctx.Db.player.identity.Find(ctx.Sender()); } // This reducer is run at module initialization. @@ -278,7 +278,7 @@ public static void log_module_identity(ReducerContext ctx) public static void test(ReducerContext ctx, TestAlias arg, TestB arg2, TestC arg3, TestF arg4) { Log.Info("BEGIN"); - Log.Info($"sender: {ctx.Sender}"); + Log.Info($"sender: {ctx.Sender()}"); Log.Info($"timestamp: {ctx.Timestamp}"); Log.Info($"bar: {arg2.foo}"); @@ -462,7 +462,7 @@ public static void test_btree_index_args(ReducerContext ctx) [Reducer] public static void assert_caller_identity_is_module_identity(ReducerContext ctx) { - var caller = ctx.Sender; + var caller = ctx.Sender(); var owner = ctx.Identity; if (!caller.Equals(owner)) { diff --git a/modules/sdk-test-connect-disconnect-cs/Lib.cs b/modules/sdk-test-connect-disconnect-cs/Lib.cs index 79af81d8cc4..200457fa616 100644 --- a/modules/sdk-test-connect-disconnect-cs/Lib.cs +++ b/modules/sdk-test-connect-disconnect-cs/Lib.cs @@ -19,12 +19,12 @@ static partial class Module [SpacetimeDB.Reducer(ReducerKind.ClientConnected)] public static void identity_connected(ReducerContext ctx) { - ctx.Db.connected.Insert(new Connected { identity = ctx.Sender}); + ctx.Db.connected.Insert(new Connected { identity = ctx.Sender()}); } [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)] public static void identity_disconnected(ReducerContext ctx) { - ctx.Db.disconnected.Insert(new Disconnected { identity = ctx.Sender}); + ctx.Db.disconnected.Insert(new Disconnected { identity = ctx.Sender()}); } } diff --git a/modules/sdk-test-cs/Lib.cs b/modules/sdk-test-cs/Lib.cs index 06ddacbb631..0387d77abae 100644 --- a/modules/sdk-test-cs/Lib.cs +++ b/modules/sdk-test-cs/Lib.cs @@ -1887,25 +1887,25 @@ public static void update_pk_simple_enum(ReducerContext ctx, SimpleEnum a, int d [SpacetimeDB.Reducer] public static void insert_caller_one_identity(ReducerContext ctx) { - ctx.Db.one_identity.Insert(new OneIdentity { i = ctx.Sender }); + ctx.Db.one_identity.Insert(new OneIdentity { i = ctx.Sender() }); } [SpacetimeDB.Reducer] public static void insert_caller_vec_identity(ReducerContext ctx) { - ctx.Db.vec_identity.Insert(new VecIdentity { i = new List { ctx.Sender } }); + ctx.Db.vec_identity.Insert(new VecIdentity { i = new List { ctx.Sender() } }); } [SpacetimeDB.Reducer] public static void insert_caller_unique_identity(ReducerContext ctx, int data) { - ctx.Db.unique_identity.Insert(new UniqueIdentity { i = ctx.Sender, data = data }); + ctx.Db.unique_identity.Insert(new UniqueIdentity { i = ctx.Sender(), data = data }); } [SpacetimeDB.Reducer] public static void insert_caller_pk_identity(ReducerContext ctx, int data) { - ctx.Db.pk_identity.Insert(new PkIdentity { i = ctx.Sender, data = data }); + ctx.Db.pk_identity.Insert(new PkIdentity { i = ctx.Sender(), data = data }); } [SpacetimeDB.Reducer] diff --git a/sdks/csharp/examples~/regression-tests/server/Lib.cs b/sdks/csharp/examples~/regression-tests/server/Lib.cs index bb63e977af4..7137e8cb468 100644 --- a/sdks/csharp/examples~/regression-tests/server/Lib.cs +++ b/sdks/csharp/examples~/regression-tests/server/Lib.cs @@ -163,13 +163,13 @@ public partial struct NullStringNullable [SpacetimeDB.View(Name = "my_player", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.player.Identity.Find(ctx.Sender); + return ctx.Db.player.Identity.Find(ctx.Sender()); } [SpacetimeDB.View(Name = "my_account", Public = true)] public static Account? MyAccount(ViewContext ctx) { - return ctx.Db.account.Identity.Find(ctx.Sender) as Account; + return ctx.Db.account.Identity.Find(ctx.Sender()) as Account; } [SpacetimeDB.View(Name = "my_account_missing", Public = true)] @@ -299,23 +299,23 @@ public static void InsertWhereTest(ReducerContext ctx, uint id, uint value, stri [Reducer(ReducerKind.ClientConnected)] public static void ClientConnected(ReducerContext ctx) { - Log.Info($"Connect {ctx.Sender}"); + Log.Info($"Connect {ctx.Sender()}"); - if (ctx.Db.player.Identity.Find(ctx.Sender) is Player player) + if (ctx.Db.player.Identity.Find(ctx.Sender()) is Player player) { // We are not logging player login status, so do nothing } else { // Lets setup a new player with a level of 1 - ctx.Db.player.Insert(new Player { Identity = ctx.Sender, Name = "NewPlayer" }); - var playerId = (ctx.Db.player.Identity.Find(ctx.Sender)!).Value.Id; + ctx.Db.player.Insert(new Player { Identity = ctx.Sender(), Name = "NewPlayer" }); + var playerId = (ctx.Db.player.Identity.Find(ctx.Sender())!).Value.Id; ctx.Db.player_level.Insert(new PlayerLevel { PlayerId = playerId, Level = 1 }); } - if (ctx.Db.account.Identity.Find(ctx.Sender) is null) + if (ctx.Db.account.Identity.Find(ctx.Sender()) is null) { - ctx.Db.account.Insert(new Account { Identity = ctx.Sender, Name = "Account" }); + ctx.Db.account.Insert(new Account { Identity = ctx.Sender(), Name = "Account" }); } if (ctx.Db.nullable_vec.Id.Find(1) is null) @@ -646,10 +646,10 @@ public static ReturnStruct TxContextCapabilities(ProcedureContext ctx) } // Test 3: Verify transaction context properties are accessible - var txSender = tx.Sender; + var txSender = tx.Sender(); var txTimestamp = tx.Timestamp; - if (txSender.Equals(ctx.Sender) == false) + if (txSender.Equals(ctx.Sender()) == false) { throw new InvalidOperationException("Transaction sender should match procedure sender"); } @@ -686,14 +686,14 @@ public static ReturnStruct AuthenticationCapabilities(ProcedureContext ctx) { // Test 1: Verify authentication context is accessible from procedure context var procAuth = ctx.SenderAuth; - var procSender = ctx.Sender; + var procSender = ctx.Sender(); var procConnectionId = ctx.ConnectionId; var result = ctx.WithTx(tx => { // Test 2: Verify authentication context is accessible from transaction context var txAuth = tx.SenderAuth; - var txSender = tx.Sender; + var txSender = tx.Sender(); var txConnectionId = tx.ConnectionId; // Test 3: Authentication contexts should be consistent diff --git a/templates/chat-console-cs/spacetimedb/Lib.cs b/templates/chat-console-cs/spacetimedb/Lib.cs index 3d82175859a..020bf6c072b 100644 --- a/templates/chat-console-cs/spacetimedb/Lib.cs +++ b/templates/chat-console-cs/spacetimedb/Lib.cs @@ -24,7 +24,7 @@ public static void SetName(ReducerContext ctx, string name) { name = ValidateName(name); - if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) { user.Name = name; ctx.Db.User.Identity.Update(user); @@ -49,7 +49,7 @@ public static void SendMessage(ReducerContext ctx, string text) ctx.Db.Message.Insert( new Message { - Sender = ctx.Sender, + Sender = ctx.Sender(), Text = text, Sent = ctx.Timestamp, } @@ -69,9 +69,9 @@ private static string ValidateMessage(string text) [Reducer(ReducerKind.ClientConnected)] public static void ClientConnected(ReducerContext ctx) { - Log.Info($"Connect {ctx.Sender}"); + Log.Info($"Connect {ctx.Sender()}"); - if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) { // If this is a returning user, i.e., we already have a `User` with this `Identity`, // set `Online: true`, but leave `Name` and `Identity` unchanged. @@ -86,7 +86,7 @@ public static void ClientConnected(ReducerContext ctx) new User { Name = null, - Identity = ctx.Sender, + Identity = ctx.Sender(), Online = true, } ); @@ -96,7 +96,7 @@ public static void ClientConnected(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void ClientDisconnected(ReducerContext ctx) { - if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) { // This user should exist, so set `Online: false`. user.Online = false; From 865b4952b7c2b836298b48d46467ca7308b342c9 Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Tue, 3 Feb 2026 11:03:04 +0530 Subject: [PATCH 4/8] [WASM] Expose `RawModuleDefV10` from modules (#4153) # Description of Changes Switch Wasm module to `__describe_module_v10__` from `__describe_module__` to expose `RawModuleDefV10` # API and ABI breaking changes 2.0 breaking change. # Expected complexity level and risk 1 # Testing Exising smoketests should be enough. --- crates/bindings-sys/src/lib.rs | 2 +- crates/bindings/src/rt.rs | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/bindings-sys/src/lib.rs b/crates/bindings-sys/src/lib.rs index dfbef0c6c55..50c0ccf13d0 100644 --- a/crates/bindings-sys/src/lib.rs +++ b/crates/bindings-sys/src/lib.rs @@ -924,7 +924,7 @@ pub mod raw { /// would be where you would initialize the interepreter and load the user module into it. fn __setup__() -> Result; /// Required. Runs after `__setup__`; returns all the exports for the module. - fn __describe_module__() -> Encoded; + fn __describe_module_v10__() -> Encoded; /// Required. id is an index into the `ModuleDef.reducers` returned from `__describe_module__`. /// args is a bsatn-encoded product value defined by the schema at `reducers[id]`. fn __call_reducer__( diff --git a/crates/bindings/src/rt.rs b/crates/bindings/src/rt.rs index 09f2e5e40eb..5bb4067df9f 100644 --- a/crates/bindings/src/rt.rs +++ b/crates/bindings/src/rt.rs @@ -4,8 +4,9 @@ use crate::query_builder::Query; use crate::table::IndexAlgo; use crate::{sys, AnonymousViewContext, IterBuf, ReducerContext, ReducerResult, SpacetimeType, Table, ViewContext}; use spacetimedb_lib::bsatn::EncodeError; +use spacetimedb_lib::db::raw_def::v10::RawModuleDefV10Builder; pub use spacetimedb_lib::db::raw_def::v9::Lifecycle as LifecycleReducer; -use spacetimedb_lib::db::raw_def::v9::{RawIndexAlgorithm, RawModuleDefV9Builder, TableType, ViewResultHeader}; +use spacetimedb_lib::db::raw_def::v9::{RawIndexAlgorithm, TableType, ViewResultHeader}; use spacetimedb_lib::de::{self, Deserialize, DeserializeOwned, Error as _, SeqProductAccess}; use spacetimedb_lib::sats::typespace::TypespaceBuilder; use spacetimedb_lib::sats::{impl_deserialize, impl_serialize, ProductTypeElement}; @@ -674,7 +675,7 @@ pub trait RowLevelSecurityInfo { } /// A function which will be registered by [`register_describer`] into [`DESCRIBERS`], -/// which will be called by [`__describe_module__`] to construct a module definition. +/// which will be called by [`__describe_module_v10__`] to construct a module definition. /// /// May be a closure over static data, so that e.g. /// [`register_row_level_security`] doesn't need to take a type parameter. @@ -700,6 +701,13 @@ pub fn register_reftype() { pub fn register_table() { register_describer(|module| { let product_type_ref = *T::Row::make_type(&mut module.inner).as_ref().unwrap(); + if let Some(schedule) = T::SCHEDULE { + module.inner.add_schedule( + T::TABLE_NAME, + schedule.scheduled_at_column, + schedule.reducer_or_procedure_name, + ); + } let mut table = module .inner @@ -719,10 +727,6 @@ pub fn register_table() { for &col in T::SEQUENCES { table = table.with_column_sequence(col); } - if let Some(schedule) = T::SCHEDULE { - table = table.with_schedule(schedule.reducer_or_procedure_name, schedule.scheduled_at_column); - } - for col in T::get_default_col_values().iter_mut() { table = table.with_default_column_value(col.col_id, col.value.clone()) } @@ -749,7 +753,11 @@ impl From> for RawIndexAlgorithm { pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) { register_describer(|module| { let params = A::schema::(&mut module.inner); - module.inner.add_reducer(I::NAME, params, I::LIFECYCLE); + if let Some(lifecycle) = I::LIFECYCLE { + module.inner.add_lifecycle_reducer(lifecycle, I::NAME, params); + } else { + module.inner.add_reducer(I::NAME, params); + } module.reducers.push(I::INVOKE); }) } @@ -814,7 +822,7 @@ pub fn register_row_level_security(sql: &'static str) { #[derive(Default)] pub struct ModuleBuilder { /// The module definition. - inner: RawModuleDefV9Builder, + inner: RawModuleDefV10Builder, /// The reducers of the module. reducers: Vec, /// The procedures of the module. @@ -863,7 +871,7 @@ static ANONYMOUS_VIEWS: OnceLock> = OnceLock::new(); /// including when modules are updated (re-publishing). /// After initialization, the module cannot alter the schema. #[no_mangle] -extern "C" fn __describe_module__(description: BytesSink) { +extern "C" fn __describe_module_v10__(description: BytesSink) { // Collect the `module`. let mut module = ModuleBuilder::default(); for describer in &mut *DESCRIBERS.lock().unwrap() { @@ -872,7 +880,7 @@ extern "C" fn __describe_module__(description: BytesSink) { // Serialize the module to bsatn. let module_def = module.inner.finish(); - let module_def = RawModuleDef::V9(module_def); + let module_def = RawModuleDef::V10(module_def); let bytes = bsatn::to_vec(&module_def).expect("unable to serialize typespace"); // Write the sets of reducers, procedures and views. From 750ae7d43e2a125f0a36b184dba0a3915ca32fba Mon Sep 17 00:00:00 2001 From: joshua-spacetime Date: Wed, 4 Feb 2026 17:42:52 -0800 Subject: [PATCH 5/8] [2.0 Breaking] Make `connection_id` a method on `ReducerContext` (#4200) # Description of Changes Same changes as https://github.com/clockworklabs/SpacetimeDB/pull/4101 but for `connection_id`. # API and ABI breaking changes API Breaking # Expected complexity level and risk 1 # Testing Pure refactor. Tests and docs have been updated, but no new tests added. --- crates/bindings/src/lib.rs | 19 +++++++++-- .../00100-databases/00500-cheat-sheet.md | 2 +- .../00300-reducers/00500-lifecycle.md | 14 ++++---- docs/static/llms.md | 34 +++++++++---------- modules/sdk-test/src/lib.rs | 8 ++--- smoketests/tests/zz_docker.py | 5 +-- 6 files changed, 49 insertions(+), 33 deletions(-) diff --git a/crates/bindings/src/lib.rs b/crates/bindings/src/lib.rs index ebe5f7075b3..ab8da2c663c 100644 --- a/crates/bindings/src/lib.rs +++ b/crates/bindings/src/lib.rs @@ -938,7 +938,7 @@ pub struct ReducerContext { /// /// Will be `None` for certain reducers invoked automatically by the host, /// including `init` and scheduled reducers. - pub connection_id: Option, + connection_id: Option, sender_auth: AuthCtx, @@ -1024,6 +1024,14 @@ impl ReducerContext { self.sender } + /// The `ConnectionId` of the client that invoked the reducer. + /// + /// Will be `None` for certain reducers invoked automatically by the host, + /// including `init` and scheduled reducers. + pub fn connection_id(&self) -> Option { + self.connection_id + } + /// Returns the authorization information for the caller of this reducer. pub fn sender_auth(&self) -> &AuthCtx { &self.sender_auth @@ -1142,7 +1150,7 @@ pub struct ProcedureContext { /// The `ConnectionId` of the client that invoked the procedure. /// /// Will be `None` for certain scheduled procedures. - pub connection_id: Option, + connection_id: Option, /// Methods for performing HTTP requests. pub http: crate::http::HttpClient, @@ -1178,6 +1186,13 @@ impl ProcedureContext { self.sender } + /// The `ConnectionId` of the client that invoked the procedure. + /// + /// Will be `None` for certain scheduled procedures. + pub fn connection_id(&self) -> Option { + self.connection_id + } + /// Read the current module's [`Identity`]. pub fn identity(&self) -> Identity { // Hypothetically, we *could* read the module identity out of the system tables. diff --git a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md index c7c8eafee96..d1e2624b343 100644 --- a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md +++ b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md @@ -523,7 +523,7 @@ ctx.Rng // Random number generator ```rust ctx.db // Database access ctx.sender() // Identity of caller -ctx.connection_id // Option +ctx.connection_id() // Option ctx.timestamp // Timestamp ctx.identity() // Module's identity ctx.rng() // Random number generator diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md index 605ad09dd09..e9c6b1cff61 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md @@ -133,8 +133,8 @@ public static void OnConnect(ReducerContext ctx) pub fn on_connect(ctx: &ReducerContext) -> Result<(), String> { log::info!("Client connected: {}", ctx.sender()); - // ctx.connection_id is guaranteed to be Some(...) - let conn_id = ctx.connection_id.unwrap(); + // ctx.connection_id() is guaranteed to be Some(...) + let conn_id = ctx.connection_id().unwrap(); // Initialize client session ctx.db.sessions().try_insert(Session { @@ -152,7 +152,7 @@ pub fn on_connect(ctx: &ReducerContext) -> Result<(), String> { The `client_connected` reducer: - Cannot take arguments beyond `ReducerContext` -- `ctx.connection_id` is guaranteed to be present +- `ctx.connection_id()` is guaranteed to be present - Failure disconnects the client - Runs for each distinct connection (WebSocket, HTTP call) @@ -200,8 +200,8 @@ public static void OnDisconnect(ReducerContext ctx) pub fn on_disconnect(ctx: &ReducerContext) -> Result<(), String> { log::info!("Client disconnected: {}", ctx.sender()); - // ctx.connection_id is guaranteed to be Some(...) - let conn_id = ctx.connection_id.unwrap(); + // ctx.connection_id() is guaranteed to be Some(...) + let conn_id = ctx.connection_id().unwrap(); // Clean up client session ctx.db.sessions().connection_id().delete(&conn_id); @@ -215,7 +215,7 @@ pub fn on_disconnect(ctx: &ReducerContext) -> Result<(), String> { The `client_disconnected` reducer: - Cannot take arguments beyond `ReducerContext` -- `ctx.connection_id` is guaranteed to be present +- `ctx.connection_id()` is guaranteed to be present - Failure is logged but doesn't prevent disconnection - Runs when connection ends (close, timeout, error) @@ -231,5 +231,5 @@ Reducers can be triggered at specific times using schedule tables. See [Schedule :::info Scheduled Reducer Context Scheduled reducer calls originate from SpacetimeDB itself, not from a client. Therefore: - `ctx.sender()` will be the module's own identity -- `ctx.connection_id` will be `None`/`null`/`undefined` +- `ctx.connection_id()` will be `None`/`null`/`undefined` ::: diff --git a/docs/static/llms.md b/docs/static/llms.md index f35907bf85d..c7144f9f20f 100644 --- a/docs/static/llms.md +++ b/docs/static/llms.md @@ -434,7 +434,7 @@ pub struct PlayerSessionData { fn example_reducer(ctx: &spacetimedb::ReducerContext) { // Reducers interact with the specific table handles: let session = PlayerSessionData { - player_id: ctx.sender, // Example: Use sender identity + player_id: ctx.sender(), // Example: Use sender identity session_id: 0, // Assuming auto_inc last_activity: ctx.timestamp, }; @@ -446,12 +446,12 @@ fn example_reducer(ctx: &spacetimedb::ReducerContext) { } // Find a player in the 'players_in_lobby' table by primary key - if let Some(lobby_player) = ctx.db.players_in_lobby().player_id().find(&ctx.sender) { + if let Some(lobby_player) = ctx.db.players_in_lobby().player_id().find(&ctx.sender()) { spacetimedb::log::info!("Player {} found in lobby.", lobby_player.player_id); } // Delete from the 'logged_in_players' table using the PK index - ctx.db.logged_in_players().player_id().delete(&ctx.sender); + ctx.db.logged_in_players().player_id().delete(&ctx.sender()); } ``` @@ -499,7 +499,7 @@ use spacetimedb::{reducer, ReducerContext, Table, Identity, Timestamp, log}; // Example: Basic reducer to set a user's name #[reducer] pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { - let sender_id = ctx.sender; + let sender_id = ctx.sender(); let name = validate_name(name)?; // Use helper for validation // Find the user row by primary key @@ -519,13 +519,13 @@ pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { #[reducer] pub fn send_message(ctx: &ReducerContext, text: String) -> Result<(), String> { let text = validate_message(text)?; // Use helper for validation - log::info!("User {} sent message: {}", ctx.sender, text); + log::info!("User {} sent message: {}", ctx.sender(), text); // Insert a new row into the Message table // Note: id is auto_inc, so we provide 0. insert() panics on constraint violation. let new_message = Message { id: 0, - sender: ctx.sender, + sender: ctx.sender(), text, sent: ctx.timestamp, }; @@ -567,8 +567,8 @@ Reducers can indicate failure either by returning `Err` from a function with a ` Special reducers handle specific events: - `#[reducer(init)]`: Runs once when the module is first published **and** any time the database is manually cleared (e.g., via `spacetime publish -c` or `spacetime server clear`). Failure prevents publishing or clearing. Often used for initial data setup. -- `#[reducer(client_connected)]`: Runs when any distinct client connection (e.g., WebSocket, HTTP call) is established. Failure disconnects the client. `ctx.connection_id` is guaranteed to be `Some(...)` within this reducer. -- `#[reducer(client_disconnected)]`: Runs when any distinct client connection terminates. Failure is logged but does not prevent disconnection. `ctx.connection_id` is guaranteed to be `Some(...)` within this reducer. +- `#[reducer(client_connected)]`: Runs when any distinct client connection (e.g., WebSocket, HTTP call) is established. Failure disconnects the client. `ctx.connection_id()` is guaranteed to be `Some(...)` within this reducer. +- `#[reducer(client_disconnected)]`: Runs when any distinct client connection terminates. Failure is logged but does not prevent disconnection. `ctx.connection_id()` is guaranteed to be `Some(...)` within this reducer. These reducers cannot take arguments beyond `&ReducerContext`. @@ -611,14 +611,14 @@ pub fn initialize_database(ctx: &ReducerContext) { // Example client_connected reducer #[reducer(client_connected)] pub fn handle_connect(ctx: &ReducerContext) { - log::info!("Client connected: {}, Connection ID: {:?}", ctx.sender, ctx.connection_id); + log::info!("Client connected: {}, Connection ID: {:?}", ctx.sender(), ctx.connection_id()); // ... setup initial state for ctx.sender ... } // Example client_disconnected reducer #[reducer(client_disconnected)] pub fn handle_disconnect(ctx: &ReducerContext) { - log::info!("Client disconnected: {}, Connection ID: {:?}", ctx.sender, ctx.connection_id); + log::info!("Client disconnected: {}, Connection ID: {:?}", ctx.sender(), ctx.connection_id()); // ... cleanup state for ctx.sender ... } ``` @@ -800,7 +800,7 @@ struct SendMessageSchedule { #[reducer] fn send_message(ctx: &ReducerContext, args: SendMessageSchedule) -> Result<(), String> { // Security check is important! - if ctx.sender != ctx.identity() { + if ctx.sender() != ctx.identity() { return Err("Reducer `send_message` may not be invoked by clients, only via scheduling.".into()); } @@ -851,7 +851,7 @@ Refer to the [official Rust Module SDK documentation on docs.rs](https://docs.rs - **Best-Effort Scheduling:** Scheduled reducers are called on a best-effort basis and may be slightly delayed in their execution when a database is under heavy load. -- **Restricting Access (Security):** Scheduled reducers are normal reducers and _can_ still be called directly by clients. If a scheduled reducer should _only_ be called by the scheduler, it is crucial to begin the reducer with a check comparing the caller's identity (`ctx.sender`) to the module's own identity (`ctx.identity()`). +- **Restricting Access (Security):** Scheduled reducers are normal reducers and _can_ still be called directly by clients. If a scheduled reducer should _only_ be called by the scheduler, it is crucial to begin the reducer with a check comparing the caller's identity (`ctx.sender()`) to the module's own identity (`ctx.identity()`). ```rust use spacetimedb::{reducer, ReducerContext}; @@ -860,7 +860,7 @@ Refer to the [official Rust Module SDK documentation on docs.rs](https://docs.rs #[reducer] fn my_scheduled_reducer(ctx: &ReducerContext, args: MyScheduleArgs) -> Result<(), String> { - if ctx.sender != ctx.identity() { + if ctx.sender() != ctx.identity() { return Err("Reducer `my_scheduled_reducer` may not be invoked by clients, only via scheduling.".into()); } // ... Reducer body proceeds only if called by scheduler ... @@ -869,7 +869,7 @@ Refer to the [official Rust Module SDK documentation on docs.rs](https://docs.rs ``` :::info Scheduled Reducers and Connections -Scheduled reducer calls originate from the SpacetimeDB scheduler itself, not from an external client connection. Therefore, within a scheduled reducer, `ctx.sender` will be the module's own identity, and `ctx.connection_id` will be `None`. +Scheduled reducer calls originate from the SpacetimeDB scheduler itself, not from an external client connection. Therefore, within a scheduled reducer, `ctx.sender()` will be the module's own identity, and `ctx.connection_id()` will be `None`. ::: #### View Functions @@ -922,7 +922,7 @@ pub struct PlayerAndLevel { // Returns Option for at-most-one row #[view(name = my_player, public)] fn my_player(ctx: &ViewContext) -> Option { - ctx.db.player().identity().find(ctx.sender) + ctx.db.player().identity().find(ctx.sender()) } // View that returns all players at a specific level (same for all callers) @@ -953,7 +953,7 @@ fn players_for_level(ctx: &AnonymousViewContext) -> Vec { Views use one of two context types: -- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.sender`. Use this when the view depends on who is querying it (e.g., "get my player"). +- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.sender()`. Use this when the view depends on who is querying it (e.g., "get my player"). - **`AnonymousViewContext`**: Does not provide caller information. Use this when the view produces the same results regardless of who queries it (e.g., "get top 10 players"). Both contexts provide read-only access to tables and indexes through `ctx.db`. @@ -984,7 +984,7 @@ use spacetimedb::{view, ViewContext, Query}; fn my_messages(ctx: &ViewContext) -> Query { // Build a typed query using the query builder ctx.db.message() - .filter(|cols| cols.sender.eq(ctx.sender)) + .filter(|cols| cols.sender.eq(ctx.sender())) .build() } diff --git a/modules/sdk-test/src/lib.rs b/modules/sdk-test/src/lib.rs index 0a6aed56358..26c19064d3f 100644 --- a/modules/sdk-test/src/lib.rs +++ b/modules/sdk-test/src/lib.rs @@ -664,7 +664,7 @@ fn insert_caller_pk_identity(ctx: &ReducerContext, data: i32) -> anyhow::Result< #[spacetimedb::reducer] fn insert_caller_one_connection_id(ctx: &ReducerContext) -> anyhow::Result<()> { ctx.db.one_connection_id().insert(OneConnectionId { - a: ctx.connection_id.context("No connection id in reducer context")?, + a: ctx.connection_id().context("No connection id in reducer context")?, }); Ok(()) } @@ -672,7 +672,7 @@ fn insert_caller_one_connection_id(ctx: &ReducerContext) -> anyhow::Result<()> { #[spacetimedb::reducer] fn insert_caller_vec_connection_id(ctx: &ReducerContext) -> anyhow::Result<()> { ctx.db.vec_connection_id().insert(VecConnectionId { - a: vec![ctx.connection_id.context("No connection id in reducer context")?], + a: vec![ctx.connection_id().context("No connection id in reducer context")?], }); Ok(()) } @@ -680,7 +680,7 @@ fn insert_caller_vec_connection_id(ctx: &ReducerContext) -> anyhow::Result<()> { #[spacetimedb::reducer] fn insert_caller_unique_connection_id(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { ctx.db.unique_connection_id().insert(UniqueConnectionId { - a: ctx.connection_id.context("No connection id in reducer context")?, + a: ctx.connection_id().context("No connection id in reducer context")?, data, }); Ok(()) @@ -689,7 +689,7 @@ fn insert_caller_unique_connection_id(ctx: &ReducerContext, data: i32) -> anyhow #[spacetimedb::reducer] fn insert_caller_pk_connection_id(ctx: &ReducerContext, data: i32) -> anyhow::Result<()> { ctx.db.pk_connection_id().insert(PkConnectionId { - a: ctx.connection_id.context("No connection id in reducer context")?, + a: ctx.connection_id().context("No connection id in reducer context")?, data, }); Ok(()) diff --git a/smoketests/tests/zz_docker.py b/smoketests/tests/zz_docker.py index bcfdef16a73..71ddf173093 100644 --- a/smoketests/tests/zz_docker.py +++ b/smoketests/tests/zz_docker.py @@ -113,14 +113,15 @@ class DockerRestartAutoDisconnect(Smoketest): fn on_connect(ctx: &ReducerContext) { ctx.db.connected_client().insert(ConnectedClient { identity: ctx.sender(), - connection_id: ctx.connection_id.expect("sender connection id unset"), + connection_id: ctx.connection_id().expect("sender connection id unset"), }); } #[spacetimedb::reducer(client_disconnected)] fn on_disconnect(ctx: &ReducerContext) { let sender_identity = &ctx.sender(); - let sender_connection_id = ctx.connection_id.as_ref().expect("sender connection id unset"); + let connection_id = ctx.connection_id(); + let sender_connection_id = connection_id.as_ref().expect("sender connection id unset"); let match_client = |row: &ConnectedClient| { &row.identity == sender_identity && &row.connection_id == sender_connection_id }; From 7b16052b1a2053f1b0f99a34dc745cd4063846f9 Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Thu, 5 Feb 2026 18:23:10 +0530 Subject: [PATCH 6/8] raw-mod-def-v8 --- .../lib/autogen/function_visibility_type.ts | 19 ++++++ .../raw_column_default_value_v_10_type.ts | 16 +++++ .../autogen/raw_constraint_def_v_10_type.ts | 19 ++++++ .../lib/autogen/raw_index_def_v_10_type.ts | 20 ++++++ .../raw_life_cycle_reducer_def_v_10_type.ts | 19 ++++++ .../src/lib/autogen/raw_module_def_type.ts | 4 ++ .../raw_module_def_v_10_section_type.ts | 53 +++++++++++++++ .../lib/autogen/raw_module_def_v_10_type.ts | 18 +++++ .../autogen/raw_procedure_def_v_10_type.ts | 27 ++++++++ .../lib/autogen/raw_reducer_def_v_10_type.ts | 30 +++++++++ .../lib/autogen/raw_schedule_def_v_10_type.ts | 18 +++++ .../autogen/raw_scoped_type_name_v_10_type.ts | 16 +++++ .../lib/autogen/raw_sequence_def_v_10_type.ts | 20 ++++++ .../lib/autogen/raw_table_def_v_10_type.ts | 41 ++++++++++++ .../src/lib/autogen/raw_type_def_v_10_type.ts | 20 ++++++ .../src/lib/autogen/raw_view_def_v_10_type.ts | 26 ++++++++ crates/bindings-typescript/src/lib/schema.ts | 43 +++++++++--- crates/bindings-typescript/src/lib/table.ts | 66 ++++++++++++------- .../src/lib/table_schema.ts | 12 +++- .../src/server/procedures.ts | 13 ++-- .../src/server/reducers.ts | 21 ++++-- .../bindings-typescript/src/server/runtime.ts | 17 +++-- .../bindings-typescript/src/server/schema.ts | 2 + .../bindings-typescript/src/server/views.ts | 17 ++--- crates/lib/src/db/raw_def/v10.rs | 38 +---------- crates/schema/src/def/validate/v10.rs | 50 +++++++++++++- 26 files changed, 539 insertions(+), 106 deletions(-) create mode 100644 crates/bindings-typescript/src/lib/autogen/function_visibility_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_column_default_value_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_constraint_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_index_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_life_cycle_reducer_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_section_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_procedure_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_reducer_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_schedule_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_scoped_type_name_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_sequence_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_table_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_type_def_v_10_type.ts create mode 100644 crates/bindings-typescript/src/lib/autogen/raw_view_def_v_10_type.ts diff --git a/crates/bindings-typescript/src/lib/autogen/function_visibility_type.ts b/crates/bindings-typescript/src/lib/autogen/function_visibility_type.ts new file mode 100644 index 00000000000..0b94830a87d --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/function_visibility_type.ts @@ -0,0 +1,19 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; + +// The tagged union or sum type for the algebraic type `FunctionVisibility`. +const FunctionVisibility = __t.enum('FunctionVisibility', { + Internal: __t.unit(), + ClientCallable: __t.unit(), +}); + +export default FunctionVisibility; diff --git a/crates/bindings-typescript/src/lib/autogen/raw_column_default_value_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_column_default_value_v_10_type.ts new file mode 100644 index 00000000000..5f37afa4604 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_column_default_value_v_10_type.ts @@ -0,0 +1,16 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; + +export default __t.object('RawColumnDefaultValueV10', { + colId: __t.u16(), + value: __t.byteArray(), +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_constraint_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_constraint_def_v_10_type.ts new file mode 100644 index 00000000000..76145329659 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_constraint_def_v_10_type.ts @@ -0,0 +1,19 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import RawConstraintDataV9 from './raw_constraint_data_v_9_type'; + +export default __t.object('RawConstraintDefV10', { + sourceName: __t.option(__t.string()), + get data() { + return RawConstraintDataV9; + }, +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_index_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_index_def_v_10_type.ts new file mode 100644 index 00000000000..2a1913b7ae4 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_index_def_v_10_type.ts @@ -0,0 +1,20 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import RawIndexAlgorithm from './raw_index_algorithm_type'; + +export default __t.object('RawIndexDefV10', { + sourceName: __t.option(__t.string()), + accessorName: __t.option(__t.string()), + get algorithm() { + return RawIndexAlgorithm; + }, +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_life_cycle_reducer_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_life_cycle_reducer_def_v_10_type.ts new file mode 100644 index 00000000000..7ccc26d79a3 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_life_cycle_reducer_def_v_10_type.ts @@ -0,0 +1,19 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import Lifecycle from './lifecycle_type'; + +export default __t.object('RawLifeCycleReducerDefV10', { + get lifecycleSpec() { + return Lifecycle; + }, + functionName: __t.string(), +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_module_def_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_module_def_type.ts index e0f91b646ff..40255921356 100644 --- a/crates/bindings-typescript/src/lib/autogen/raw_module_def_type.ts +++ b/crates/bindings-typescript/src/lib/autogen/raw_module_def_type.ts @@ -11,6 +11,7 @@ import { } from '../../lib/type_builders'; import RawModuleDefV8 from './raw_module_def_v_8_type'; import RawModuleDefV9 from './raw_module_def_v_9_type'; +import RawModuleDefV10 from './raw_module_def_v_10_type'; // The tagged union or sum type for the algebraic type `RawModuleDef`. const RawModuleDef = __t.enum('RawModuleDef', { @@ -20,6 +21,9 @@ const RawModuleDef = __t.enum('RawModuleDef', { get V9() { return RawModuleDefV9; }, + get V10() { + return RawModuleDefV10; + }, }); export default RawModuleDef; diff --git a/crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_section_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_section_type.ts new file mode 100644 index 00000000000..dcf579b9fd6 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_section_type.ts @@ -0,0 +1,53 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import Typespace from './typespace_type'; +import RawRowLevelSecurityDefV9 from './raw_row_level_security_def_v_9_type'; +import RawTypeDefV10 from './raw_type_def_v_10_type'; +import RawTableDefV10 from './raw_table_def_v_10_type'; +import RawReducerDefV10 from './raw_reducer_def_v_10_type'; +import RawProcedureDefV10 from './raw_procedure_def_v_10_type'; +import RawViewDefV10 from './raw_view_def_v_10_type'; +import RawScheduleDefV10 from './raw_schedule_def_v_10_type'; +import RawLifeCycleReducerDefV10 from './raw_life_cycle_reducer_def_v_10_type'; + +// The tagged union or sum type for the algebraic type `RawModuleDefV10Section`. +const RawModuleDefV10Section = __t.enum('RawModuleDefV10Section', { + get Typespace() { + return Typespace; + }, + get Types() { + return __t.array(RawTypeDefV10); + }, + get Tables() { + return __t.array(RawTableDefV10); + }, + get Reducers() { + return __t.array(RawReducerDefV10); + }, + get Procedures() { + return __t.array(RawProcedureDefV10); + }, + get Views() { + return __t.array(RawViewDefV10); + }, + get Schedules() { + return __t.array(RawScheduleDefV10); + }, + get LifeCycleReducers() { + return __t.array(RawLifeCycleReducerDefV10); + }, + get RowLevelSecurity() { + return __t.array(RawRowLevelSecurityDefV9); + }, +}); + +export default RawModuleDefV10Section; diff --git a/crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_type.ts new file mode 100644 index 00000000000..f12b1e66523 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_module_def_v_10_type.ts @@ -0,0 +1,18 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import RawModuleDefV10Section from './raw_module_def_v_10_section_type'; + +export default __t.object('RawModuleDefV10', { + get sections() { + return __t.array(RawModuleDefV10Section); + }, +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_procedure_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_procedure_def_v_10_type.ts new file mode 100644 index 00000000000..1c2b312c126 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_procedure_def_v_10_type.ts @@ -0,0 +1,27 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import AlgebraicType from './algebraic_type_type'; +import ProductType from './product_type_type'; +import FunctionVisibility from './function_visibility_type'; + +export default __t.object('RawProcedureDefV10', { + sourceName: __t.string(), + get params() { + return ProductType; + }, + get returnType() { + return AlgebraicType; + }, + get visibility() { + return FunctionVisibility; + }, +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_reducer_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_reducer_def_v_10_type.ts new file mode 100644 index 00000000000..2c40195ebb9 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_reducer_def_v_10_type.ts @@ -0,0 +1,30 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import AlgebraicType from './algebraic_type_type'; +import ProductType from './product_type_type'; +import FunctionVisibility from './function_visibility_type'; + +export default __t.object('RawReducerDefV10', { + sourceName: __t.string(), + get params() { + return ProductType; + }, + get visibility() { + return FunctionVisibility; + }, + get okReturnType() { + return AlgebraicType; + }, + get errReturnType() { + return AlgebraicType; + }, +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_schedule_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_schedule_def_v_10_type.ts new file mode 100644 index 00000000000..7ad8b18bad1 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_schedule_def_v_10_type.ts @@ -0,0 +1,18 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; + +export default __t.object('RawScheduleDefV10', { + sourceName: __t.option(__t.string()), + tableName: __t.string(), + scheduleAtCol: __t.u16(), + functionName: __t.string(), +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_scoped_type_name_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_scoped_type_name_v_10_type.ts new file mode 100644 index 00000000000..91bf0da5915 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_scoped_type_name_v_10_type.ts @@ -0,0 +1,16 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; + +export default __t.object('RawScopedTypeNameV10', { + scope: __t.array(__t.string()), + sourceName: __t.string(), +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_sequence_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_sequence_def_v_10_type.ts new file mode 100644 index 00000000000..e5ebe17d853 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_sequence_def_v_10_type.ts @@ -0,0 +1,20 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; + +export default __t.object('RawSequenceDefV10', { + sourceName: __t.option(__t.string()), + column: __t.u16(), + start: __t.option(__t.i128()), + minValue: __t.option(__t.i128()), + maxValue: __t.option(__t.i128()), + increment: __t.i128(), +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_table_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_table_def_v_10_type.ts new file mode 100644 index 00000000000..47d112d4506 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_table_def_v_10_type.ts @@ -0,0 +1,41 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import TableType from './table_type_type'; +import TableAccess from './table_access_type'; +import RawIndexDefV10 from './raw_index_def_v_10_type'; +import RawConstraintDefV10 from './raw_constraint_def_v_10_type'; +import RawSequenceDefV10 from './raw_sequence_def_v_10_type'; +import RawColumnDefaultValueV10 from './raw_column_default_value_v_10_type'; + +export default __t.object('RawTableDefV10', { + sourceName: __t.string(), + productTypeRef: __t.u32(), + primaryKey: __t.array(__t.u16()), + get indexes() { + return __t.array(RawIndexDefV10); + }, + get constraints() { + return __t.array(RawConstraintDefV10); + }, + get sequences() { + return __t.array(RawSequenceDefV10); + }, + get tableType() { + return TableType; + }, + get tableAccess() { + return TableAccess; + }, + get defaultValues() { + return __t.array(RawColumnDefaultValueV10); + }, +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_type_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_type_def_v_10_type.ts new file mode 100644 index 00000000000..e3800eff3d2 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_type_def_v_10_type.ts @@ -0,0 +1,20 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import RawScopedTypeNameV10 from './raw_scoped_type_name_v_10_type'; + +export default __t.object('RawTypeDefV10', { + get sourceName() { + return RawScopedTypeNameV10; + }, + ty: __t.u32(), + customOrdering: __t.bool(), +}); diff --git a/crates/bindings-typescript/src/lib/autogen/raw_view_def_v_10_type.ts b/crates/bindings-typescript/src/lib/autogen/raw_view_def_v_10_type.ts new file mode 100644 index 00000000000..755076ed315 --- /dev/null +++ b/crates/bindings-typescript/src/lib/autogen/raw_view_def_v_10_type.ts @@ -0,0 +1,26 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from '../../lib/type_builders'; +import AlgebraicType from './algebraic_type_type'; +import ProductType from './product_type_type'; + +export default __t.object('RawViewDefV10', { + sourceName: __t.string(), + index: __t.u32(), + isPublic: __t.bool(), + isAnonymous: __t.bool(), + get params() { + return ProductType; + }, + get returnType() { + return AlgebraicType; + }, +}); diff --git a/crates/bindings-typescript/src/lib/schema.ts b/crates/bindings-typescript/src/lib/schema.ts index 93efd8a40b2..1a4ad86bca5 100644 --- a/crates/bindings-typescript/src/lib/schema.ts +++ b/crates/bindings-typescript/src/lib/schema.ts @@ -5,8 +5,9 @@ import { type AlgebraicTypeType, type AlgebraicTypeVariants, } from './algebraic_type'; -import type RawModuleDefV9 from './autogen/raw_module_def_v_9_type'; -import type RawScopedTypeNameV9 from './autogen/raw_scoped_type_name_v_9_type'; +import type RawModuleDefV10Section from './autogen/raw_module_def_v_10_section_type'; +import type RawModuleDefV10 from './autogen/raw_module_def_v_10_type'; +import type RawScopedTypeNameV10 from './autogen/raw_scoped_type_name_v_10_type'; import type { UntypedIndex } from './indexes'; import type { UntypedTableDef } from './table'; import type { UntypedTableSchema } from './table_schema'; @@ -85,7 +86,7 @@ function tableToSchema( columns: schema.rowType.row, // typed as T[i]['rowType']['row'] under TablesToSchema rowType: schema.rowSpacetimeType, constraints: tableDef.constraints.map(c => ({ - name: c.name, + name: c.sourceName, constraint: 'unique', columns: c.data.value.columns.map(getColName) as [string], })), @@ -115,10 +116,17 @@ type CompoundTypeCache = Map< RefBuilder >; -type ModuleDef = Infer; +export type ModuleDef = { + [S in Infer as Uncapitalize< + S['tag'] + >]: S['value']; +}; + +type Section = Infer; export class ModuleContext { #compoundTypes: CompoundTypeCache = new Map(); + /** * The global module definition that gets populated by calls to `reducer()` and lifecycle hooks. */ @@ -127,14 +135,31 @@ export class ModuleContext { tables: [], reducers: [], types: [], - miscExports: [], rowLevelSecurity: [], + schedules: [], + procedures: [], + views: [], + lifeCycleReducers: [], }; - get moduleDef() { + get moduleDef(): ModuleDef { return this.#moduleDef; } + get RawModuleDefV10(): Infer { + const sections: Section[] = []; + + for (const [key, value] of Object.entries(this.#moduleDef)) { + const tag = key.charAt(0).toUpperCase() + key.slice(1); + sections.push({ + tag, + value, + } as Section); + } + + return { sections }; + } + get typespace() { return this.#moduleDef.typespace; } @@ -256,7 +281,7 @@ export class ModuleContext { } this.#moduleDef.types.push({ - name: splitName(name), + sourceName: splitName(name), ty: r.ref, customOrdering: true, }); @@ -272,7 +297,7 @@ function isUnit(typeBuilder: ProductBuilder): boolean { ); } -export function splitName(name: string): Infer { +export function splitName(name: string): Infer { const scope = name.split('.'); - return { name: scope.pop()!, scope }; + return { sourceName: scope.pop()!, scope }; } diff --git a/crates/bindings-typescript/src/lib/table.ts b/crates/bindings-typescript/src/lib/table.ts index 3e9d735d3fb..62d1d412499 100644 --- a/crates/bindings-typescript/src/lib/table.ts +++ b/crates/bindings-typescript/src/lib/table.ts @@ -1,9 +1,11 @@ import type { errors } from '../server/errors'; -import type RawConstraintDefV9 from './autogen/raw_constraint_def_v_9_type'; +import type RawConstraintDefV10 from './autogen/raw_constraint_def_v_10_type'; import RawIndexAlgorithm from './autogen/raw_index_algorithm_type'; -import type RawIndexDefV9 from './autogen/raw_index_def_v_9_type'; -import type RawSequenceDefV9 from './autogen/raw_sequence_def_v_9_type'; -import type RawTableDefV9 from './autogen/raw_table_def_v_9_type'; +import type RawIndexDefV10 from './autogen/raw_index_def_v_10_type'; +import type RawSequenceDefV10 from './autogen/raw_sequence_def_v_10_type'; +import type RawTableDefV10 from './autogen/raw_table_def_v_10_type'; +import type RawScheduleDefV10 from './autogen/raw_schedule_def_v_10_type'; +import type RawColumnDefaultValueV10 from './autogen/raw_column_default_value_v_10_type'; import type { AllUnique, ConstraintOpts } from './constraints'; import type { ColumnIndex, @@ -308,11 +310,12 @@ export function table>( // gather primary keys, per‑column indexes, uniques, sequences const pk: ColList = []; - const indexes: Infer[] = []; - const constraints: Infer[] = []; - const sequences: Infer[] = []; + const indexes: Infer[] = []; + const constraints: Infer[] = []; + const sequences: Infer[] = []; let scheduleAtCol: ColId | undefined; + const defaultValues: Infer[] = []; for (const [name, builder] of Object.entries(row.row)) { const meta: ColumnMetadata = builder.columnMetadata; @@ -337,7 +340,7 @@ export function table>( break; } indexes.push({ - name: undefined, // Unnamed indexes will be assigned a globally unique name + sourceName: undefined, // Unnamed indexes will be assigned a globally unique name accessorName: name, // The name of this column will be used as the accessor name algorithm, }); @@ -345,14 +348,14 @@ export function table>( if (isUnique) { constraints.push({ - name: undefined, + sourceName: undefined, data: { tag: 'Unique', value: { columns: [colIds.get(name)!] } }, }); } if (meta.isAutoIncrement) { sequences.push({ - name: undefined, + sourceName: undefined, start: undefined, minValue: undefined, maxValue: undefined, @@ -361,6 +364,13 @@ export function table>( }); } + if (meta.defaultValue) { + defaultValues.push({ + colId: colIds.get(name)!, + value: meta.defaultValue, + }); + } + // If this column is shaped like ScheduleAtAlgebraicType, mark it as the schedule‑at column if (scheduled) { const algebraicType = builder.typeBuilder.algebraicType; @@ -391,17 +401,21 @@ export function table>( // no actual way for the user to set the actual index name. // I think we should standardize: name and accessorName as the way to set // the name and accessor name of an index across all SDKs. - indexes.push({ name: undefined, accessorName: indexOpts.name, algorithm }); + indexes.push({ + sourceName: undefined, + accessorName: indexOpts.name, + algorithm, + }); } // add explicit constraints from options.constraints for (const constraintOpts of opts.constraints ?? []) { if (constraintOpts.constraint === 'unique') { - const data: Infer['data'] = { + const data: Infer['data'] = { tag: 'Unique', value: { columns: constraintOpts.columns.map(c => colIds.get(c)!) }, }; - constraints.push({ name: constraintOpts.name, data }); + constraints.push({ sourceName: constraintOpts.name, data }); continue; } } @@ -412,35 +426,38 @@ export function table>( ? [index.algorithm.value] : index.algorithm.value; const colS = cols.map(i => colNameList[i]).join('_'); - index.name = `${name}_${colS}_idx_${index.algorithm.tag.toLowerCase()}`; + index.sourceName = `${name}_${colS}_idx_${index.algorithm.tag.toLowerCase()}`; } // Temporarily set the type ref to 0. We will set this later // in the schema function. - const tableDef = (ctx: ModuleContext): Infer => ({ - name, + const tableDef = (ctx: ModuleContext): Infer => ({ + sourceName: name, productTypeRef: ctx.registerTypesRecursively(row).ref, primaryKey: pk, indexes, constraints, sequences, - schedule: - scheduled && scheduleAtCol !== undefined - ? { - name: undefined, - reducerName: scheduled, - scheduledAtColumn: scheduleAtCol, - } - : undefined, tableType: { tag: 'User' }, tableAccess: { tag: isPublic ? 'Public' : 'Private' }, + defaultValues, }); const productType = row.algebraicType.value as RowBuilder< CoerceRow >['algebraicType']['value']; + const schedule: Infer | undefined = + scheduled && scheduleAtCol !== undefined + ? { + sourceName: undefined, + tableName: name, + functionName: scheduled, + scheduleAtCol: scheduleAtCol, + } + : undefined; + return { rowType: row as RowBuilder>, tableName: name, @@ -448,5 +465,6 @@ export function table>( tableDef, idxs: {} as OptsIndices, constraints: constraints as OptsConstraints, + schedule, }; } diff --git a/crates/bindings-typescript/src/lib/table_schema.ts b/crates/bindings-typescript/src/lib/table_schema.ts index b48b33ca444..2c4c9ca9b8e 100644 --- a/crates/bindings-typescript/src/lib/table_schema.ts +++ b/crates/bindings-typescript/src/lib/table_schema.ts @@ -1,5 +1,6 @@ import type { ProductType } from './algebraic_type'; -import type RawTableDefV9 from './autogen/raw_table_def_v_9_type'; +import type RawTableDefV10 from './autogen/raw_table_def_v_10_type'; +import type RawScheduleDefV10 from './autogen/raw_schedule_def_v_10_type'; import type { IndexOpts } from './indexes'; import type { ModuleContext } from './schema'; import type { ColumnBuilder, Infer, RowBuilder } from './type_builders'; @@ -28,9 +29,9 @@ export type TableSchema< readonly rowSpacetimeType: RowBuilder['algebraicType']['value']; /** - * The {@link RawTableDefV9} of the configured table + * The {@link RawTableDefV10} of the configured table */ - tableDef(ctx: ModuleContext): Infer; + tableDef(ctx: ModuleContext): Infer; /** * The indexes defined on the table. @@ -45,6 +46,11 @@ export type TableSchema< constraint: 'unique'; columns: [any]; }[]; + + /** + * The schedule defined on the table, if any. + */ + readonly schedule?: Infer; }; export type UntypedTableSchema = TableSchema< diff --git a/crates/bindings-typescript/src/server/procedures.ts b/crates/bindings-typescript/src/server/procedures.ts index 3f2fca665ee..45fdeebac16 100644 --- a/crates/bindings-typescript/src/server/procedures.ts +++ b/crates/bindings-typescript/src/server/procedures.ts @@ -4,6 +4,7 @@ import { type Deserializer, type Serializer, } from '../lib/algebraic_type'; +import FunctionVisibility from '../lib/autogen/function_visibility_type'; import BinaryReader from '../lib/binary_reader'; import BinaryWriter from '../lib/binary_writer'; import type { ConnectionId } from '../lib/connection_id'; @@ -69,13 +70,11 @@ export function procedure< }; const returnType = ctx.registerTypesRecursively(ret).algebraicType; - ctx.moduleDef.miscExports.push({ - tag: 'Procedure', - value: { - name, - params: paramsType, - returnType, - }, + ctx.moduleDef.procedures.push({ + sourceName: name, + params: paramsType, + returnType, + visibility: FunctionVisibility.ClientCallable, }); const { typespace } = ctx; diff --git a/crates/bindings-typescript/src/server/reducers.ts b/crates/bindings-typescript/src/server/reducers.ts index f149e3e002d..9b396accdaf 100644 --- a/crates/bindings-typescript/src/server/reducers.ts +++ b/crates/bindings-typescript/src/server/reducers.ts @@ -1,5 +1,6 @@ +import { AlgebraicType } from '../lib/algebraic_type'; +import FunctionVisibility from '../lib/autogen/function_visibility_type'; import Lifecycle from '../lib/autogen/lifecycle_type'; -import type RawReducerDefV9 from '../lib/autogen/raw_reducer_def_v_9_type'; import type { ParamsAsObject, ParamsObj, @@ -30,7 +31,7 @@ export function pushReducer( name: string, params: RowObj | RowBuilder, fn: Reducer, - lifecycle?: Infer['lifecycle'] + lifecycle?: Infer ): void { ctx.defineFunction(name); @@ -44,13 +45,25 @@ export function pushReducer( const ref = ctx.registerTypesRecursively(params); const paramsType = ctx.resolveType(ref).value; + const isLifecycle = lifecycle != null; ctx.moduleDef.reducers.push({ - name, + sourceName: name, params: paramsType, - lifecycle, // <- lifecycle flag lands here + //ModuleDef validation code is responsible to mark private reducers + visibility: FunctionVisibility.ClientCallable, + //Hardcoded for now - reducers do not return values yet + okReturnType: AlgebraicType.Product({ elements: [] }), + errReturnType: AlgebraicType.String, }); + if (isLifecycle) { + ctx.moduleDef.lifeCycleReducers.push({ + lifecycleSpec: lifecycle, + functionName: name, + }); + } + // If the function isn't named (e.g. `function foobar() {}`), give it the same // name as the reducer so that it's clear what it is in in backtraces. if (!fn.name) { diff --git a/crates/bindings-typescript/src/server/runtime.ts b/crates/bindings-typescript/src/server/runtime.ts index 8942cd221fa..f7da04c2b07 100644 --- a/crates/bindings-typescript/src/server/runtime.ts +++ b/crates/bindings-typescript/src/server/runtime.ts @@ -9,8 +9,7 @@ import { type Deserializer, } from '../lib/algebraic_type'; import RawModuleDef from '../lib/autogen/raw_module_def_type'; -import type RawModuleDefV9 from '../lib/autogen/raw_module_def_v_9_type'; -import type RawTableDefV9 from '../lib/autogen/raw_table_def_v_9_type'; +import type RawTableDefV10 from '../lib/autogen/raw_table_def_v_10_type'; import type Typespace from '../lib/autogen/typespace_type'; import { ConnectionId } from '../lib/connection_id'; import { Identity } from '../lib/identity'; @@ -32,7 +31,7 @@ import { type ReducerCtx, type ReducerCtx as IReducerCtx, } from '../lib/reducers'; -import { type UntypedSchemaDef } from '../lib/schema'; +import { type ModuleDef, type UntypedSchemaDef } from '../lib/schema'; import { type RowType, type Table, type TableMethods } from '../lib/table'; import type { Infer } from '../lib/type_builders'; import { bsatnBaseSize, hasOwn, toCamelCase } from '../lib/util'; @@ -264,7 +263,7 @@ export const hooks: ModuleHooks = { const writer = new BinaryWriter(128); RawModuleDef.serialize( writer, - RawModuleDef.V9(getRegisteredSchema().moduleDef) + RawModuleDef.V10(getRegisteredSchema().RawModuleDefV10) ); return writer.getBuffer(); }, @@ -368,11 +367,11 @@ function getDbView() { return DB_VIEW; } -function makeDbView(moduleDef: Infer): DbView { +function makeDbView(moduleDef: ModuleDef): DbView { return freeze( Object.fromEntries( moduleDef.tables.map(table => [ - toCamelCase(table.name), + toCamelCase(table.sourceName), makeTableView(moduleDef.typespace, table), ]) ) @@ -381,9 +380,9 @@ function makeDbView(moduleDef: Infer): DbView { function makeTableView( typespace: Infer, - table: Infer + table: Infer ): Table { - const table_id = sys.table_id_from_name(table.name); + const table_id = sys.table_id_from_name(table.sourceName); const rowType = typespace.types[table.productTypeRef]; if (rowType.tag !== 'Product') { throw 'impossible'; @@ -476,7 +475,7 @@ function makeTableView( ) as Table; for (const indexDef of table.indexes) { - const index_id = sys.index_id_from_name(indexDef.name!); + const index_id = sys.index_id_from_name(indexDef.sourceName!); let column_ids: number[]; switch (indexDef.algorithm.tag) { diff --git a/crates/bindings-typescript/src/server/schema.ts b/crates/bindings-typescript/src/server/schema.ts index 8a69b055dcb..ca60f17b1cf 100644 --- a/crates/bindings-typescript/src/server/schema.ts +++ b/crates/bindings-typescript/src/server/schema.ts @@ -410,6 +410,8 @@ export function schema( const ctx = new SchemaInner(ctx => { const tableDefs = handles.map(h => h.tableDef(ctx)); ctx.moduleDef.tables.push(...tableDefs); + const schedules = handles.map(h => h.schedule).filter(s => s !== undefined); + ctx.moduleDef.schedules.push(...schedules); return tablesToSchema(ctx, handles); }); diff --git a/crates/bindings-typescript/src/server/views.ts b/crates/bindings-typescript/src/server/views.ts index dcd56d4e628..5535cfcb07c 100644 --- a/crates/bindings-typescript/src/server/views.ts +++ b/crates/bindings-typescript/src/server/views.ts @@ -106,16 +106,13 @@ export function defineView< ctx.registerTypesRecursively(paramsBuilder) ); - ctx.moduleDef.miscExports.push({ - tag: 'View', - value: { - name: opts.name, - index: (anon ? ctx.anonViews : ctx.views).length, - isPublic: opts.public, - isAnonymous: anon, - params: paramType, - returnType, - }, + ctx.moduleDef.views.push({ + sourceName: opts.name, + index: (anon ? ctx.anonViews : ctx.views).length, + isPublic: opts.public, + isAnonymous: anon, + params: paramType, + returnType, }); // If it is an option, we wrap the function to make the return look like an array. diff --git a/crates/lib/src/db/raw_def/v10.rs b/crates/lib/src/db/raw_def/v10.rs index 7474b6bedfe..102cf3916ae 100644 --- a/crates/lib/src/db/raw_def/v10.rs +++ b/crates/lib/src/db/raw_def/v10.rs @@ -912,43 +912,7 @@ impl RawModuleDefV10Builder { /// Finish building, consuming the builder and returning the module. /// The module should be validated before use. - /// - /// This method automatically marks functions used in lifecycle or schedule functions - /// as `Internal` visibility. - pub fn finish(mut self) -> RawModuleDefV10 { - let internal_functions = self - .module - .lifecycle_reducers() - .cloned() - .into_iter() - .flatten() - .map(|lcr| lcr.function_name.clone()) - .chain( - self.module - .schedules() - .cloned() - .into_iter() - .flatten() - .map(|sched| sched.function_name.clone()), - ); - - for internal_function in internal_functions { - if let Some(r) = self - .reducers_mut() - .iter_mut() - .find(|r| r.source_name == internal_function) - { - r.visibility = FunctionVisibility::Private; - } - - if let Some(p) = self - .procedures_mut() - .iter_mut() - .find(|p| p.source_name == internal_function) - { - p.visibility = FunctionVisibility::Private; - } - } + pub fn finish(self) -> RawModuleDefV10 { self.module } } diff --git a/crates/schema/src/def/validate/v10.rs b/crates/schema/src/def/validate/v10.rs index 1667bd63b1f..b4897b8b582 100644 --- a/crates/schema/src/def/validate/v10.rs +++ b/crates/schema/src/def/validate/v10.rs @@ -156,8 +156,8 @@ pub fn validate(def: RawModuleDefV10) -> Result { .combine_errors() .and_then( |(mut tables, types, reducers, procedures, views, schedules, lifecycles)| { - let (mut reducers, procedures, views) = check_function_names_are_unique(reducers, procedures, views)?; - + let (mut reducers, mut procedures, views) = + check_function_names_are_unique(reducers, procedures, views)?; // Attach lifecycles to their respective reducers attach_lifecycles_to_reducers(&mut reducers, lifecycles)?; @@ -165,11 +165,11 @@ pub fn validate(def: RawModuleDefV10) -> Result { attach_schedules_to_tables(&mut tables, schedules)?; check_scheduled_functions_exist(&mut tables, &reducers, &procedures)?; + change_scheduled_functions_and_lifetimes_visibility(&tables, &mut reducers, &mut procedures)?; Ok((tables, types, reducers, procedures, views)) }, ); - let CoreValidator { stored_in_table_def, typespace_for_generate, @@ -205,6 +205,50 @@ pub fn validate(def: RawModuleDefV10) -> Result { }) } +/// Change the visibility of scheduled functions and lifecycle reducers to Internal. +/// +fn change_scheduled_functions_and_lifetimes_visibility( + tables: &HashMap, + reducers: &mut IndexMap, + procedures: &mut IndexMap, +) -> Result<()> { + for sched_def in tables.iter().filter_map(|(_, t)| t.schedule.as_ref()) { + match sched_def.function_kind { + FunctionKind::Reducer => { + let def = reducers.get_mut(&sched_def.function_name).ok_or_else(|| { + ValidationError::MissingScheduledFunction { + schedule: sched_def.name.clone(), + function: sched_def.function_name.clone(), + } + })?; + + def.visibility = crate::def::FunctionVisibility::Private; + } + + FunctionKind::Procedure => { + let def = procedures.get_mut(&sched_def.function_name).ok_or_else(|| { + ValidationError::MissingScheduledFunction { + schedule: sched_def.name.clone(), + function: sched_def.function_name.clone(), + } + })?; + + def.visibility = crate::def::FunctionVisibility::Private; + } + + FunctionKind::Unknown => {} + } + } + + for red_def in reducers.iter_mut().map(|(_, r)| r) { + if red_def.lifecycle.is_some() { + red_def.visibility = crate::def::FunctionVisibility::Private; + } + } + + Ok(()) +} + struct ModuleValidatorV10<'a> { core: CoreValidator<'a>, } From 2eb5f3b482da3d43a46bef96ba9e994085fa1855 Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Sun, 8 Feb 2026 17:25:20 +0530 Subject: [PATCH 7/8] merge master --- .../diag/snapshots/Module#FFI.verified.cs | 21 +- .../server/snapshots/Module#FFI.verified.cs | 21 +- crates/bindings-csharp/Codegen/Module.cs | 20 +- .../Runtime/Internal/TxContext.cs | 7 +- .../Runtime/ProcedureContext.cs | 10 +- demo/Blackholio/server-csharp/Lib.cs | 16 +- .../00400-key-architecture.md | 2 +- .../00300-tutorials/00100-chat-app.md | 12 +- .../00300-unity-tutorial/00300-part-2.md | 4 +- .../00300-unity-tutorial/00400-part-3.md | 10 +- .../00300-unity-tutorial/00500-part-4.md | 4 +- .../00400-unreal-tutorial/00300-part-2.md | 4 +- .../00400-unreal-tutorial/00400-part-3.md | 10 +- .../00400-unreal-tutorial/00500-part-4.md | 4 +- .../00100-databases/00500-cheat-sheet.md | 4 +- .../00300-reducers/00400-reducer-context.md | 4 +- .../00300-reducers/00500-lifecycle.md | 6 +- .../00300-reducers/00600-error-handling.md | 2 +- .../00200-functions/00500-views.md | 6 +- docs/docs/00200-core-concepts/00300-tables.md | 2 +- .../00300-tables/00210-file-storage.md | 2 +- .../00300-tables/00400-access-permissions.md | 8 +- .../00100-how-to/00300-logging.md | 4 +- docs/llms/docs-benchmark-analysis.md | 196 +- docs/llms/docs-benchmark-comment.md | 16 +- docs/llms/docs-benchmark-details.json | 1695 +++++++++-------- docs/llms/docs-benchmark-summary.json | 68 +- docs/static/llms.md | 32 +- .../examples~/regression-tests/server/Lib.cs | 24 +- templates/chat-console-cs/spacetimedb/Lib.cs | 12 +- 30 files changed, 1083 insertions(+), 1143 deletions(-) diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs index af8b40f3f07..9064e3f7b3c 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs @@ -1,4 +1,4 @@ -//HintName: FFI.cs +//HintName: FFI.cs // #nullable enable // The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type. @@ -17,6 +17,7 @@ namespace SpacetimeDB { public sealed record ReducerContext : DbContext, Internal.IReducerContext { + public readonly Identity Sender; public readonly ConnectionId? ConnectionId; public readonly Random Rng; public readonly Timestamp Timestamp; @@ -28,8 +29,6 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // We need this property to be non-static for parity with client SDK. public Identity Identity => Internal.IReducerContext.GetIdentity(); - private readonly Identity _sender; - internal ReducerContext( Identity identity, ConnectionId? connectionId, @@ -38,7 +37,7 @@ internal ReducerContext( AuthCtx? senderAuth = null ) { - _sender = identity; + Sender = identity; ConnectionId = connectionId; Rng = random; Timestamp = time; @@ -46,11 +45,6 @@ internal ReducerContext( CounterUuid = 0; } - /// - /// The identity of the client that invoked the reducer. - /// - public Identity Sender() => _sender; - /// /// Create a new random `v4` using the built-in RNG. /// @@ -215,18 +209,13 @@ public sealed class Local : global::SpacetimeDB.LocalBase public sealed record ViewContext : DbContext, Internal.IViewContext { - private readonly Identity _sender; + public Identity Sender { get; } internal ViewContext(Identity sender, Internal.LocalReadOnly db) : base(db) { - _sender = sender; + Sender = sender; } - - /// - /// The identity of the client that invoked the view. - /// - public Identity Sender() => _sender; } public sealed record AnonymousViewContext diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs index 24b27497250..11c5b86ea18 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs @@ -1,4 +1,4 @@ -//HintName: FFI.cs +//HintName: FFI.cs // #nullable enable // The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type. @@ -17,6 +17,7 @@ namespace SpacetimeDB { public sealed record ReducerContext : DbContext, Internal.IReducerContext { + public readonly Identity Sender; public readonly ConnectionId? ConnectionId; public readonly Random Rng; public readonly Timestamp Timestamp; @@ -28,8 +29,6 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // We need this property to be non-static for parity with client SDK. public Identity Identity => Internal.IReducerContext.GetIdentity(); - private readonly Identity _sender; - internal ReducerContext( Identity identity, ConnectionId? connectionId, @@ -38,7 +37,7 @@ internal ReducerContext( AuthCtx? senderAuth = null ) { - _sender = identity; + Sender = identity; ConnectionId = connectionId; Rng = random; Timestamp = time; @@ -46,11 +45,6 @@ internal ReducerContext( CounterUuid = 0; } - /// - /// The identity of the client that invoked the reducer. - /// - public Identity Sender() => _sender; - /// /// Create a new random `v4` using the built-in RNG. /// @@ -205,18 +199,13 @@ public sealed class Local : global::SpacetimeDB.LocalBase public sealed record ViewContext : DbContext, Internal.IViewContext { - private readonly Identity _sender; + public Identity Sender { get; } internal ViewContext(Identity sender, Internal.LocalReadOnly db) : base(db) { - _sender = sender; + Sender = sender; } - - /// - /// The identity of the client that invoked the view. - /// - public Identity Sender() => _sender; } public sealed record AnonymousViewContext diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index d38f6e31bc5..93c44cf0c26 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -1743,6 +1743,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) namespace SpacetimeDB { public sealed record ReducerContext : DbContext, Internal.IReducerContext { + public readonly Identity Sender; public readonly ConnectionId? ConnectionId; public readonly Random Rng; public readonly Timestamp Timestamp; @@ -1752,24 +1753,16 @@ public sealed record ReducerContext : DbContext, Internal.IReducerContext // We need this property to be non-static for parity with client SDK. public Identity Identity => Internal.IReducerContext.GetIdentity(); - private readonly Identity _sender; - internal ReducerContext(Identity identity, ConnectionId? connectionId, Random random, Timestamp time, AuthCtx? senderAuth = null) { - _sender = identity; + Sender = identity; ConnectionId = connectionId; Rng = random; Timestamp = time; SenderAuth = senderAuth ?? AuthCtx.BuildFromSystemTables(connectionId, identity); CounterUuid = 0; } - - /// - /// The identity of the client that invoked the reducer. - /// - public Identity Sender() => _sender; - /// /// Create a new random `v4` using the built-in RNG. /// @@ -1904,18 +1897,13 @@ public sealed class Local : global::SpacetimeDB.LocalBase { public sealed record ViewContext : DbContext, Internal.IViewContext { - private readonly Identity _sender; + public Identity Sender { get; } internal ViewContext(Identity sender, Internal.LocalReadOnly db) : base(db) { - _sender = sender; + Sender = sender; } - - /// - /// The identity of the client that invoked the view. - /// - public Identity Sender() => _sender; } public sealed record AnonymousViewContext : DbContext, Internal.IAnonymousViewContext diff --git a/crates/bindings-csharp/Runtime/Internal/TxContext.cs b/crates/bindings-csharp/Runtime/Internal/TxContext.cs index f8465e78d56..d5bea2febd9 100644 --- a/crates/bindings-csharp/Runtime/Internal/TxContext.cs +++ b/crates/bindings-csharp/Runtime/Internal/TxContext.cs @@ -9,16 +9,13 @@ public sealed class TxContext( Random rng ) { - private readonly Identity _sender = sender; - public Local Db { get; } = db; + public Identity Sender { get; } = sender; public ConnectionId? ConnectionId { get; } = connectionId; public Timestamp Timestamp { get; } = timestamp; public AuthCtx SenderAuth { get; } = senderAuth; public Random Rng { get; } = rng; - public Identity Sender() => _sender; - public TxContext WithTimestamp(Timestamp ts) => - new(Db, _sender, ConnectionId, ts, SenderAuth, Rng); + new(Db, Sender, ConnectionId, ts, SenderAuth, Rng); } diff --git a/crates/bindings-csharp/Runtime/ProcedureContext.cs b/crates/bindings-csharp/Runtime/ProcedureContext.cs index 1b878b8e549..4eb8583b7d5 100644 --- a/crates/bindings-csharp/Runtime/ProcedureContext.cs +++ b/crates/bindings-csharp/Runtime/ProcedureContext.cs @@ -10,11 +10,8 @@ public abstract class ProcedureContextBase( Timestamp time ) : Internal.IInternalProcedureContext { - private readonly Identity _sender = sender; - - public Identity Sender() => _sender; - public static Identity Identity => Internal.IProcedureContext.GetIdentity(); + public Identity Sender { get; } = sender; public ConnectionId? ConnectionId { get; } = connectionId; public Random Rng { get; } = random; public Timestamp Timestamp { get; private set; } = time; @@ -50,7 +47,7 @@ public Internal.TxContext EnterTxContext(long timestampMicros) txContext?.WithTimestamp(timestamp) ?? new Internal.TxContext( CreateLocal(), - _sender, + Sender, ConnectionId, timestamp, SenderAuth, @@ -232,9 +229,8 @@ public abstract class ProcedureTxContextBase(Internal.TxContext inner) internal void Refresh(Internal.TxContext inner) => Inner = inner; - public Identity Sender() => Inner.Sender(); - public LocalBase Db => (LocalBase)Inner.Db; + public Identity Sender => Inner.Sender; public ConnectionId? ConnectionId => Inner.ConnectionId; public Timestamp Timestamp => Inner.Timestamp; public AuthCtx SenderAuth => Inner.SenderAuth; diff --git a/demo/Blackholio/server-csharp/Lib.cs b/demo/Blackholio/server-csharp/Lib.cs index 542a7040037..20e26cf99e6 100644 --- a/demo/Blackholio/server-csharp/Lib.cs +++ b/demo/Blackholio/server-csharp/Lib.cs @@ -138,7 +138,7 @@ public static void Init(ReducerContext ctx) [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender()); + var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender); if (player != null) { ctx.Db.player.Insert(player.Value); @@ -157,7 +157,7 @@ public static void Connect(ReducerContext ctx) { ctx.Db.player.Insert(new Player { - identity = ctx.Sender(), + identity = ctx.Sender, name = "", }); } @@ -166,7 +166,7 @@ public static void Connect(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { var entity = ctx.Db.entity.entity_id.Find(circle.entity_id) ?? throw new Exception("Could not find circle"); @@ -183,7 +183,7 @@ public static void Disconnect(ReducerContext ctx) public static void EnterGame(ReducerContext ctx, string name) { Log.Info($"Creating player with name {name}"); - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); player.name = name; ctx.Db.player.identity.Update(player); SpawnPlayerInitialCircle(ctx, player.player_id); @@ -192,7 +192,7 @@ public static void EnterGame(ReducerContext ctx, string name) [Reducer] public static void Respawn(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("No such player found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("No such player found"); SpawnPlayerInitialCircle(ctx, player.player_id); } @@ -200,7 +200,7 @@ public static void Respawn(ReducerContext ctx) [Reducer] public static void Suicide(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("No such player found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("No such player found"); foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { @@ -246,7 +246,7 @@ public static Entity SpawnCircleAt(ReducerContext ctx, int player_id, int mass, [Reducer] public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id)) { var circle = c; @@ -449,7 +449,7 @@ public static void DestroyEntity(ReducerContext ctx, int entityId) [Reducer] public static void PlayerSplit(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Sender has no player"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Sender has no player"); List circles = ctx.Db.circle.player_id.Filter(player.player_id).ToList(); var circle_count = circles.Count; if (circle_count >= MAX_CIRCLES_PER_PLAYER) diff --git a/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md b/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md index 86e37c54428..9c3e28a4e61 100644 --- a/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md +++ b/docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md @@ -439,7 +439,7 @@ A view can be written in C# like so: [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender()) as Player; + return ctx.Db.Player.Identity.Find(ctx.Sender) as Player; } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md b/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md index f8dc277f38c..06ef0c039ce 100644 --- a/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md +++ b/docs/docs/00100-intro/00300-tutorials/00100-chat-app.md @@ -322,7 +322,7 @@ public static void SetName(ReducerContext ctx, string name) { name = ValidateName(name); - if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) { user.Name = name; ctx.Db.User.Identity.Update(user); @@ -411,7 +411,7 @@ public static void SendMessage(ReducerContext ctx, string text) ctx.Db.Message.Insert( new Message { - Sender = ctx.Sender(), + Sender = ctx.Sender, Text = text, Sent = ctx.Timestamp, } @@ -504,9 +504,9 @@ In `spacetimedb/Lib.cs`, add to the `Module` class: [Reducer(ReducerKind.ClientConnected)] public static void ClientConnected(ReducerContext ctx) { - Log.Info($"Connect {ctx.Sender()}"); + Log.Info($"Connect {ctx.Sender}"); - if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) { user.Online = true; ctx.Db.User.Identity.Update(user); @@ -517,7 +517,7 @@ public static void ClientConnected(ReducerContext ctx) new User { Name = null, - Identity = ctx.Sender(), + Identity = ctx.Sender, Online = true, } ); @@ -527,7 +527,7 @@ public static void ClientConnected(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void ClientDisconnected(ReducerContext ctx) { - if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) { user.Online = false; ctx.Db.User.Identity.Update(user); diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md index 26f278f5051..b6766e12672 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md @@ -335,7 +335,7 @@ Add this function to the `Module` class in `Lib.cs`: [Reducer] public static void Debug(ReducerContext ctx) { - Log.Info($"This reducer was called by {ctx.Sender()}"); + Log.Info($"This reducer was called by {ctx.Sender}"); } ``` @@ -444,7 +444,7 @@ Next let's connect our client to our database. Let's start by modifying our `Deb [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - Log.Info($"{ctx.Sender()} just connected."); + Log.Info($"{ctx.Sender} just connected."); } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md index f1a0c99aa0d..ab95e71294d 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00400-part-3.md @@ -359,7 +359,7 @@ Next, modify your `Connect` reducer and add a new `Disconnect` reducer below it: [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender()); + var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender); if (player != null) { ctx.Db.player.Insert(player.Value); @@ -369,7 +369,7 @@ public static void Connect(ReducerContext ctx) { ctx.Db.player.Insert(new Player { - identity = ctx.Sender(), + identity = ctx.Sender, name = "", }); } @@ -378,7 +378,7 @@ public static void Connect(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); ctx.Db.logged_out_player.Insert(player); ctx.Db.player.identity.Delete(player.identity); } @@ -457,7 +457,7 @@ const int START_PLAYER_MASS = 15; public static void EnterGame(ReducerContext ctx, string name) { Log.Info($"Creating player with name {name}"); - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); player.name = name; ctx.Db.player.identity.Update(player); SpawnPlayerInitialCircle(ctx, player.player_id); @@ -579,7 +579,7 @@ Let's also modify our `disconnect` reducer to remove the circles from the arena [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); // Remove any circles from the arena foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { diff --git a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md index cdf062fd8d0..647efe78bcb 100644 --- a/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md +++ b/docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00500-part-4.md @@ -49,7 +49,7 @@ Next, add the following reducer to the `Module` class of your `Lib.cs` file. [Reducer] public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id)) { var circle = c; @@ -60,7 +60,7 @@ public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) } ``` -This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender()` value is not set by the client. Instead `ctx.Sender()` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. +This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender` value is not set by the client. Instead `ctx.Sender` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md index a97a65abec8..bde4659ba26 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00300-part-2.md @@ -333,7 +333,7 @@ Add this function to the `Module` class in `Lib.cs`: [Reducer] public static void Debug(ReducerContext ctx) { - Log.Info($"This reducer was called by {ctx.Sender()}"); + Log.Info($"This reducer was called by {ctx.Sender}"); } ``` @@ -440,7 +440,7 @@ Next let's connect our client to our database. Let's start by modifying our `Deb [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - Log.Info($"{ctx.Sender()} just connected."); + Log.Info($"{ctx.Sender} just connected."); } ``` diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md index d3543050874..192c7d3ebc8 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00400-part-3.md @@ -352,7 +352,7 @@ Next, modify your `Connect` reducer and add a new `Disconnect` reducer below it: [Reducer(ReducerKind.ClientConnected)] public static void Connect(ReducerContext ctx) { - var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender()); + var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender); if (player != null) { ctx.Db.player.Insert(player.Value); @@ -362,7 +362,7 @@ public static void Connect(ReducerContext ctx) { ctx.Db.player.Insert(new Player { - identity = ctx.Sender(), + identity = ctx.Sender, name = "", }); } @@ -371,7 +371,7 @@ public static void Connect(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); ctx.Db.logged_out_player.Insert(player); ctx.Db.player.identity.Delete(player.identity); } @@ -446,7 +446,7 @@ const int START_PLAYER_MASS = 15; public static void EnterGame(ReducerContext ctx, string name) { Log.Info($"Creating player with name {name}"); - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); player.name = name; ctx.Db.player.identity.Update(player); SpawnPlayerInitialCircle(ctx, player.player_id); @@ -566,7 +566,7 @@ Let's also modify our `disconnect` reducer to remove the circles from the arena [Reducer(ReducerKind.ClientDisconnected)] public static void Disconnect(ReducerContext ctx) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); // Remove any circles from the arena foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id)) { diff --git a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md index 2acda18aac8..ae8eb620633 100644 --- a/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md +++ b/docs/docs/00100-intro/00300-tutorials/00400-unreal-tutorial/00500-part-4.md @@ -50,7 +50,7 @@ Next, add the following reducer to the `Module` class of your `Lib.cs` file. [Reducer] public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) { - var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found"); + var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found"); foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id)) { var circle = c; @@ -61,7 +61,7 @@ public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction) } ``` -This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender()` value is not set by the client. Instead `ctx.Sender()` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. +This is a simple reducer that takes the movement input from the client and applies them to all circles that that player controls. Note that it is not possible for a player to move another player's circles using this reducer, because the `ctx.Sender` value is not set by the client. Instead `ctx.Sender` is set by SpacetimeDB after it has authenticated that sender. You can rest assured that the caller has been authenticated as that player by the time this reducer is called. Let's start by building out a simple math library to help us do collision calculations. Create a new `math.rs` file in the `blackholio/spacetimedb/src` directory and add the following contents. Let's also move the `DbVector2` type from `lib.rs` into this file. diff --git a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md index d1e2624b343..416475c0bc3 100644 --- a/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md +++ b/docs/docs/00200-core-concepts/00100-databases/00500-cheat-sheet.md @@ -457,7 +457,7 @@ using SpacetimeDB; [SpacetimeDB.View(Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender()); + return ctx.Db.Player.Identity.Find(ctx.Sender); } // Return multiple rows @@ -510,7 +510,7 @@ ctx.identity // Module's identity ```csharp ctx.Db // Database access -ctx.Sender() // Identity of caller +ctx.Sender // Identity of caller ctx.ConnectionId // ConnectionId? ctx.Timestamp // Timestamp ctx.Identity // Module's identity diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md index d789845ab29..38f447125d4 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md @@ -145,7 +145,7 @@ public static partial class Module public static void UpdateScore(ReducerContext ctx, uint newScore) { // Get the caller's identity - Identity caller = ctx.Sender(); + Identity caller = ctx.Sender; // Find and update their player record if (ctx.Db.Player.Identity.Find(caller) is Player player) @@ -262,7 +262,7 @@ public static partial class Module public static void SendReminder(ReducerContext ctx, ScheduledTask task) { // Only allow the scheduler (module identity) to call this - if (ctx.Sender() != ctx.Identity) + if (ctx.Sender != ctx.Identity) { throw new Exception("This reducer can only be called by the scheduler"); } diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md index e9c6b1cff61..22afb7de483 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00500-lifecycle.md @@ -110,7 +110,7 @@ spacetimedb.clientConnected((ctx) => { [SpacetimeDB.Reducer(ReducerKind.ClientConnected)] public static void OnConnect(ReducerContext ctx) { - Log.Info($"Client connected: {ctx.Sender()}"); + Log.Info($"Client connected: {ctx.Sender}"); // ctx.ConnectionId is guaranteed to be non-null var connId = ctx.ConnectionId!.Value; @@ -119,7 +119,7 @@ public static void OnConnect(ReducerContext ctx) ctx.Db.Session.Insert(new Session { ConnectionId = connId, - Identity = ctx.Sender(), + Identity = ctx.Sender, ConnectedAt = ctx.Timestamp }); } @@ -182,7 +182,7 @@ spacetimedb.clientDisconnected((ctx) => { [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)] public static void OnDisconnect(ReducerContext ctx) { - Log.Info($"Client disconnected: {ctx.Sender()}"); + Log.Info($"Client disconnected: {ctx.Sender}"); // ctx.ConnectionId is guaranteed to be non-null var connId = ctx.ConnectionId!.Value; diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md index 661e5870853..714f68d1110 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md +++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00600-error-handling.md @@ -61,7 +61,7 @@ Throw an exception: [SpacetimeDB.Reducer] public static void TransferCredits(ReducerContext ctx, ulong toUser, uint amount) { - var fromUser = ctx.Db.User.Id.Find(ctx.Sender()); + var fromUser = ctx.Db.User.Id.Find(ctx.Sender); if (fromUser == null) { throw new InvalidOperationException("User not found"); diff --git a/docs/docs/00200-core-concepts/00200-functions/00500-views.md b/docs/docs/00200-core-concepts/00200-functions/00500-views.md index 7b8c43ea1b7..0603fa97dad 100644 --- a/docs/docs/00200-core-concepts/00200-functions/00500-views.md +++ b/docs/docs/00200-core-concepts/00200-functions/00500-views.md @@ -130,7 +130,7 @@ public static partial class Module [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender()) as Player; + return ctx.Db.Player.Identity.Find(ctx.Sender) as Player; } // Multiple rows: return a list @@ -283,7 +283,7 @@ spacetimedb.view( [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender()); + return ctx.Db.Player.Identity.Find(ctx.Sender); } ``` @@ -485,7 +485,7 @@ public partial class Module [SpacetimeDB.View(Name = "EntitiesInMyChunk", Public = true)] public static List EntitiesInMyChunk(ViewContext ctx) { - if (ctx.Db.Player.Identity.Find(ctx.Sender()) is not Player player) + if (ctx.Db.Player.Identity.Find(ctx.Sender) is not Player player) { return new List(); } diff --git a/docs/docs/00200-core-concepts/00300-tables.md b/docs/docs/00200-core-concepts/00300-tables.md index c09cf9b832c..cf3727b18d8 100644 --- a/docs/docs/00200-core-concepts/00300-tables.md +++ b/docs/docs/00200-core-concepts/00300-tables.md @@ -348,7 +348,7 @@ ctx.Db.Player.Insert(new Player { /* ... */ }); ctx.Db.LoggedOutPlayer.Insert(new Player { /* ... */ }); // Move a row between tables -var player = ctx.Db.LoggedOutPlayer.Identity.Find(ctx.Sender()); +var player = ctx.Db.LoggedOutPlayer.Identity.Find(ctx.Sender); if (player != null) { ctx.Db.Player.Insert(player.Value); diff --git a/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md b/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md index 239737330c8..33e617c542a 100644 --- a/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md +++ b/docs/docs/00200-core-concepts/00300-tables/00210-file-storage.md @@ -221,7 +221,7 @@ public static partial class Module ctx.Db.Document.Insert(new Document { Id = 0, // auto-increment - OwnerId = ctx.Sender(), + OwnerId = ctx.Sender, Filename = filename, MimeType = mimeType, SizeBytes = sizeBytes, diff --git a/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md b/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md index 6fe4e6d9833..0f3c83978ed 100644 --- a/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md +++ b/docs/docs/00200-core-concepts/00300-tables/00400-access-permissions.md @@ -393,8 +393,8 @@ public partial class Module public static List MyMessages(ViewContext ctx) { // Look up messages by index where caller is sender or recipient - var sent = ctx.Db.Message.Sender.Filter(ctx.Sender()).ToList(); - var received = ctx.Db.Message.Recipient.Filter(ctx.Sender()).ToList(); + var sent = ctx.Db.Message.Sender.Filter(ctx.Sender).ToList(); + var received = ctx.Db.Message.Recipient.Filter(ctx.Sender).ToList(); sent.AddRange(received); return sent; } @@ -526,7 +526,7 @@ public partial class Module public static PublicUserProfile? MyProfile(ViewContext ctx) { // Look up the caller's account by their identity (unique index) - if (ctx.Db.UserAccount.Identity.Find(ctx.Sender()) is not UserAccount user) + if (ctx.Db.UserAccount.Identity.Find(ctx.Sender) is not UserAccount user) { return null; } @@ -676,7 +676,7 @@ public partial class Module public static List MyColleagues(ViewContext ctx) { // Find the caller's employee record by identity (unique index) - if (ctx.Db.Employee.Identity.Find(ctx.Sender()) is not Employee me) + if (ctx.Db.Employee.Identity.Find(ctx.Sender) is not Employee me) { return new List(); } diff --git a/docs/docs/00300-resources/00100-how-to/00300-logging.md b/docs/docs/00300-resources/00100-how-to/00300-logging.md index 1b77fd7bcc7..1958b01634e 100644 --- a/docs/docs/00300-resources/00100-how-to/00300-logging.md +++ b/docs/docs/00300-resources/00100-how-to/00300-logging.md @@ -69,7 +69,7 @@ public static partial class Module throw new ArgumentException("Value cannot be zero"); } - Log.Debug($"Debug information: ctx.Sender() = {ctx.Sender()}"); + Log.Debug($"Debug information: ctx.Sender = {ctx.Sender}"); } } ``` @@ -202,7 +202,7 @@ Include relevant context in your log messages: [SpacetimeDB.Reducer] public static void TransferCredits(ReducerContext ctx, ulong toUser, uint amount) { - Log.Info($"Credit transfer: from={ctx.Sender()}, to={toUser}, amount={amount}"); + Log.Info($"Credit transfer: from={ctx.Sender}, to={toUser}, amount={amount}"); // ... transfer logic } diff --git a/docs/llms/docs-benchmark-analysis.md b/docs/llms/docs-benchmark-analysis.md index f2f69378b8e..faa301f26fc 100644 --- a/docs/llms/docs-benchmark-analysis.md +++ b/docs/llms/docs-benchmark-analysis.md @@ -8,21 +8,18 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do --- -# Analysis of SpacetimeDB Benchmark Test Failures +## Analysis of SpacetimeDB Benchmark Test Failures -This document analyzes the SpacetimeDB benchmark test failures organized by language and mode. Each section addresses specific failures, providing insights into their causes and recommending actionable solutions. +### Rust / rustdoc_json Failures -## Rust / rustdoc_json Failures - -### Compile/Publish Errors - -#### t_002_scheduled_table & t_017_scheduled_columns +#### Compile/Publish Errors (2 Failures) +##### Failure Group 1: `t_002_scheduled_table` and `t_017_scheduled_columns` 1. **The generated code**: ```rust use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt}; - #[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))] + #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))] pub struct TickTimer { #[primary_key] #[auto_inc] @@ -32,10 +29,12 @@ This document analyzes the SpacetimeDB benchmark test failures organized by lang #[reducer(init)] pub fn init(ctx: &ReducerContext) { - ctx.db.tick_timer().insert(TickTimer { - scheduled_id: 0, - scheduled_at: ScheduleAt::repeat_micros(50_000), - }); + if ctx.db.tick_timer().count() == 0 { + ctx.db.tick_timer().insert(TickTimer { + scheduled_id: 0, + scheduled_at: ScheduleAt::RepeatMicros(50_000), + }); + } } #[reducer] @@ -74,161 +73,97 @@ This document analyzes the SpacetimeDB benchmark test failures organized by lang - `publish_error: spacetime publish failed (exit=1)` 4. **Explain the difference**: - - The LLM generated code uses `ScheduleAt::repeat_micros(50_000)` while the expected code uses `ScheduleAt::Interval(Duration::from_millis(50).into())`. - - The `scheduled` attribute is incorrectly set. + - The generated code used `ScheduleAt::RepeatMicros(50_000)` instead of the correct `ScheduleAt::Interval(Duration::from_millis(50).into())`. The way the scheduling was set up was incorrect. 5. **Root cause**: - - The documentation lacks clear guidance on using the `ScheduleAt` type effectively and the format for specifying scheduled actions. + - The documentation does not clearly specify the constructor syntax for `ScheduleAt` nor how to correctly set up the scheduled tasks in this context. 6. **Recommendation**: - - Update documentation to clarify how to define timing for scheduled entries, using `ScheduleAt::Interval` instead of `ScheduleAt::repeat_*` methods. + - Update documentation to provide examples of different constructors for `ScheduleAt`, specifically emphasizing how to define intervals correctly. -### Compile/Publish Errors (3 Failures) +--- -#### t_003_struct_in_table +#### Other Failures (5 failures) +##### Failure Group 2: `t_013_spacetime_sum_type`, `t_015_product_type_columns`, `t_016_sum_type_columns`, `t_018_constraints`, `t_020_ecs` 1. **The generated code**: ```rust use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType}; #[derive(SpacetimeType)] - pub struct Position { - x: i32, - y: i32, + pub struct Rect { + width: i32, + height: i32, } - #[table(name = entity)] - pub struct Entity { + #[table(name = result)] + pub struct ResultRow { #[primary_key] id: i32, - pos: Position, + value: Shape, } #[reducer] - pub fn add_entity(ctx: &ReducerContext, id: i32, x: i32, y: i32) { - ctx.db.entity().insert(Entity { id, pos: Position { x, y } }); + pub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) { + ctx.db.result().insert(ResultRow { + id, + value: Shape::Circle(radius), + }); } ``` 2. **The golden example**: ```rust - use spacetimedb::{table, SpacetimeType}; + use spacetimedb::{reducer, table, ReducerContext, SpacetimeType, Table}; #[derive(SpacetimeType, Clone, Debug)] - pub struct Position { - pub x: i32, - pub y: i32, + pub struct Rect { + pub width: i32, + pub height: i32, } - #[table(name = entity)] - pub struct Entity { + #[table(name = result)] + pub struct ResultRow { #[primary_key] pub id: i32, - pub pos: Position, - } - ``` - -3. **The error**: - - `schema_parity: reducers differ - expected [], got ["add_entity()"]` - -4. **Explain the difference**: - - The expected code does not include any reducers, while the generated code has an unnecessary `add_entity` reducer. - -5. **Root cause**: - - Misrepresentation of structural requirements regarding reducers in the schema. - -6. **Recommendation**: - - Update the documentation to clarify when reducers should or should not be defined for schema parity. - ---- - -#### t_018_constraints - -1. **The generated code**: - ```rust - use spacetimedb::{table, reducer, ReducerContext, Table}; - - #[table(name = account, index(name = by_name, btree(columns = [name])))] - pub struct Account { - #[primary_key] - id: i32, - #[unique] - email: String, - name: String, + pub value: Shape, } #[reducer] - pub fn seed(ctx: &ReducerContext) { - let t = ctx.db.account(); - t.insert(Account { id: 1, email: "a@example.com".to_string(), name: "Alice".to_string() }); - t.insert(Account { id: 2, email: "b@example.com".to_string(), name: "Bob".to_string() }); + pub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) { + ctx.db.result().insert(ResultRow { id, value: Shape::Circle(radius) }); } ``` -2. **The golden example**: - ```rust - use spacetimedb::{reducer, table, ReducerContext, Table}; - - #[table( - name = account, - index(name = by_name, btree(columns = [name])) - )] - pub struct Account { - #[primary_key] - pub id: i32, - #[unique] - pub email: String, - pub name: String, - } - - #[reducer] - pub fn seed(ctx: &ReducerContext) { - ctx.db.account().insert(Account { id: 1, email: "a@example.com".into(), name: "Alice".into() }); - ctx.db.account().insert(Account { id: 2, email: "b@example.com".into(), name: "Bob".into() }); - } - ``` - -3. **The error**: - - `constraints_row_parity_after_seed: spacetime sql failed: no such table: 'account'` - +3. **The error**: + - `spacetime sql failed: no such table: result` + - `spacetime sql failed: no such table: profile` + - `spacetime sql failed: no such table: drawings` + 4. **Explain the difference**: - - The generated code did not include the `pub` keyword in front of fields, which results in private access. + - The generated code omits the `pub` visibility keyword for fields and structs, which prevents proper access by the macros that generate the expected database schema. Additionally, the enum `Shape` wasn't declared correctly in the generated code. 5. **Root cause**: - - Lack of explicit guidelines on visibility modifiers for database fields and schema definition. + - Lack of proper visibility (missing `pub`) for structs and enum fields was not clearly emphasized in the documentation, leading to access issues. 6. **Recommendation**: - - Update the documentation to emphasize that struct fields in database models must be public. + - Provide clear guidelines in the documentation regarding the necessity of using `pub` for struct and enum fields when working with SpacetimeDB components. Include example schemas with visibility marked. --- -### Additional Recommendations +### Rust / docs Failures (22 total) -1. **Documentation Clarity**: - - Ensure clear examples defining the expected syntax for all relevant SpacetimeDB features (e.g., table structure, reducer signatures). - -2. **Example Consistency**: - - Modify the examples to guarantee consistency in field access levels (public/private) across all instances. +#### Timeout Issues (1 failure) -3. **Error Handling**: - - Include a section on expected error messages and discrepancies that developers should look out for, which could help in debugging similar errors effectively. +1. **Failure Group**: `t_015_product_type_columns` + - **Expected**: Modify the query logic to ensure no unnecessary long-running operations exist. + - **Recommendation**: Provide timeout considerations in the documentation to ensure optimization options are explored to prevent long-running tasks. --- -## Rust / docs Failures - -### Timeout Issues - -- **Failures**: t_013_spacetime_sum_type, t_015_product_type_columns, t_016_sum_type_columns, t_018_constraints, t_019_many_to_many, t_020_ecs -- **Recommendation**: - - Review the execution time of these benchmarks and possibly optimize the code for performance or provide a timeout setting for testing. - ---- - -## C# / docs Failures - -### t_014_elementary_columns +### C# / docs Failures (4 total) +#### C# Failure Group: `t_014_elementary_columns`, `t_016_sum_type_columns`, `t_017_scheduled_columns`, `t_020_ecs` 1. **The generated code**: ```csharp using SpacetimeDB; @@ -299,30 +234,17 @@ This document analyzes the SpacetimeDB benchmark test failures organized by lang } ``` -3. **The error**: - - `no such table: 'primitive'` - +3. **The error**: `no such table: primitive` + 4. **Explain the difference**: - - The generated code has an extra public field visibility which is redundant in this context, leading to distraction. + - Missing the `public` access modifier in the declaration of the `Table` attribute. The expected syntax properly utilizes attributes defined in the library. 5. **Root cause**: - - Inconsistent handling of public annotations for struct attributes. + - Documentation may lack clarity about access modifiers, especially when it comes to how they affect visibility in entities. 6. **Recommendation**: - - Align the documentation to show proper usage of attributes and visibility appropriately. + - Ensure C# documentation includes explicit examples where `public` is required in class and struct declarations to prevent access issues with tables. ---- +--- -#### 10. **t_017_scheduled_columns** -- **Generated Code**: - ```csharp - [Table(Name = "TickTimer", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))] - public partial struct TickTimer - { - [PrimaryKey, AutoInc] - public ulong ScheduledId; - public ScheduleAt ScheduledAt; - } - ``` - -This analysis serves to highlight the discrepancies noted in the benchmark test failures across Rust and C#, with actionable steps to amend recurring issues. Essential areas of improvement focus on explicit documentation, consistent field access levels, and clearer definitions of API requirements. By implementing these recommendations, we can streamline the development process and avoid common pitfalls. +By addressing the above gaps in documentation and ensuring that generated samples adhere to the expected outcomes, we can significantly reduce the number of failures in future benchmarks. diff --git a/docs/llms/docs-benchmark-comment.md b/docs/llms/docs-benchmark-comment.md index 907eb0e9b50..b26d4820585 100644 --- a/docs/llms/docs-benchmark-comment.md +++ b/docs/llms/docs-benchmark-comment.md @@ -2,16 +2,16 @@ | Language | Mode | Category | Tests Passed | Task Pass % | |----------|------|----------|--------------|-------------| -| Rust | rustdoc_json | basics | 25/27 | 83.3% ⬆️ +6.9% | -| Rust | rustdoc_json | schema | 24/34 | 68.7% ⬇️ -6.7% | -| Rust | rustdoc_json | **total** | 49/61 | **76.7%** ⬆️ +0.8% | +| Rust | rustdoc_json | basics | 26/27 | 91.7% ⬆️ +8.3% | +| Rust | rustdoc_json | schema | 23/34 | 65.3% ⬆️ +10.0% | +| Rust | rustdoc_json | **total** | 49/61 | **79.7%** ⬆️ +9.1% | | Rust | docs | basics | 5/27 | 11.1% | -| Rust | docs | schema | 4/18 | 12.5% ⬇️ -8.0% | -| Rust | docs | **total** | 9/45 | **11.7%** ⬇️ -3.6% | +| Rust | docs | schema | 8/32 | 20.5% ⬆️ +8.0% | +| Rust | docs | **total** | 13/59 | **15.4%** ⬆️ +3.6% | | C# | docs | basics | 27/27 | 100.0% | -| C# | docs | schema | 24/32 | 70.3% ⬆️ +6.7% | -| C# | docs | **total** | 51/59 | **86.5%** ⬆️ +3.0% | +| C# | docs | schema | 25/34 | 73.7% | +| C# | docs | **total** | 52/61 | **88.0%** | _Compared against master branch baseline_ -Generated at: 2026-01-26T19:41:35.586Z +Generated at: 2026-01-27T20:01:19.767Z diff --git a/docs/llms/docs-benchmark-details.json b/docs/llms/docs-benchmark-details.json index fc7a2432196..5d08c34e832 100644 --- a/docs/llms/docs-benchmark-details.json +++ b/docs/llms/docs-benchmark-details.json @@ -5,21 +5,21 @@ "modes": [ { "mode": "rustdoc_json", - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_000_empty_reducers", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &ReducerContext, _count: i32) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &ReducerContext, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &ReducerContext, _count: i32, _name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &ReducerContext, _active: bool, _ratio: f32, _label: String) {\n}", + "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &ReducerContext, count: i32) {\n let _ = count;\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &ReducerContext, name: String) {\n let _ = name;\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &ReducerContext, count: i32, name: String) {\n let _ = (count, name);\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &ReducerContext, active: bool, ratio: f32, label: String) {\n let _ = (active, ratio, label);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-000-empty-reducers-golden", @@ -35,18 +35,18 @@ "llm_db": "basics-t-000-empty-reducers-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:52.325853523Z", - "finished_at": "2026-01-26T19:28:19.691117111Z" + "started_at": "2026-01-27T19:50:33.923590167Z", + "finished_at": "2026-01-27T19:51:02.622615452Z" }, "t_001_basic_tables": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_001_basic_tables", "lang": "rust", "golden_published": true, @@ -69,25 +69,25 @@ "llm_db": "basics-t-001-basic-tables-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:55.244006331Z", - "finished_at": "2026-01-26T19:28:22.209162875Z" + "started_at": "2026-01-27T19:50:58.838771838Z", + "finished_at": "2026-01-27T19:51:33.707208916Z" }, "t_002_scheduled_table": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_002_scheduled_table", "lang": "rust", "golden_published": false, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _scheduled_id: u64) {\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db\n .tick_timer()\n .insert(TickTimer { scheduled_id: 0, scheduled_at: ScheduleAt::repeat_micros(50_000) });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext) {\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -99,24 +99,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling heck v0.5.0\n Compiling serde_core v1.0.228\n Compiling cfg-if v1.0.4\n Compiling find-msvc-tools v0.1.8\n Compiling either v1.15.0\n Compiling shlex v1.3.0\n Compiling serde v1.0.228\n Compiling zerocopy v0.8.34\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling bytes v1.11.0\n Compiling arrayvec v0.7.6\n Compiling humantime v2.3.0\n Compiling keccak v0.1.5\n Compiling zmij v1.0.17\n Compiling heck v0.4.1\n Compiling convert_case v0.4.0\n Compiling smallvec v1.15.1\n Compiling hex v0.4.3\n Compiling second-stack v0.3.5\n Compiling constant_time_eq v0.4.2\n Compiling arrayref v0.3.9\n Compiling getrandom v0.2.17\n Compiling itertools v0.12.1\n Compiling cc v1.2.54\n Compiling itoa v1.0.17\n Compiling spacetimedb-lib v1.11.1\n Compiling serde_json v1.0.149\n Compiling rand_core v0.6.4\n Compiling bytemuck v1.24.0\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling block-buffer v0.10.4\n Compiling crypto-common v0.1.7\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ethnum v1.5.2\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_002_scheduled_table/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:15:36\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:15:16\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:39\n |\n17 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nSome errors have detailed explanations: E0422, E0599.\nFor more information about an error, try `rustc --explain E0422`.\nerror: could not compile `spacetime-module` (lib) due to 5 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling quote v1.0.44\n Compiling unicode-ident v1.0.22\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling serde_core v1.0.228\n Compiling heck v0.5.0\n Compiling cfg-if v1.0.4\n Compiling shlex v1.3.0\n Compiling either v1.15.0\n Compiling serde v1.0.228\n Compiling find-msvc-tools v0.1.8\n Compiling zerocopy v0.8.34\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling keccak v0.1.5\n Compiling bytes v1.11.0\n Compiling humantime v2.3.0\n Compiling convert_case v0.4.0\n Compiling zmij v1.0.17\n Compiling heck v0.4.1\n Compiling arrayvec v0.7.6\n Compiling second-stack v0.3.5\n Compiling serde_json v1.0.149\n Compiling hex v0.4.3\n Compiling bytemuck v1.24.0\n Compiling getrandom v0.2.17\n Compiling itoa v1.0.17\n Compiling smallvec v1.15.1\n Compiling arrayref v0.3.9\n Compiling itertools v0.12.1\n Compiling spacetimedb-lib v1.11.1\n Compiling constant_time_eq v0.4.2\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling rand_core v0.6.4\n Compiling cc v1.2.54\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling num-traits v0.2.19\n Compiling syn v2.0.114\n Compiling http v1.4.0\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling ethnum v1.5.2\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/basics/t_002_scheduled_table/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:17:21\n |\n17 | .insert(TickTimer { scheduled_id: 0, scheduled_at: ScheduleAt::repeat_micros(50_000) });\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:16:14\n |\n15 | / ctx.db\n16 | | .tick_timer()\n | | -^^^^^^^^^^ method not found in `Local`\n | |_____________|\n |\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:76\n |\n17 | .insert(TickTimer { scheduled_id: 0, scheduled_at: ScheduleAt::repeat_micros(50_000) });\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nSome errors have detailed explanations: E0422, E0599.\nFor more information about an error, try `rustc --explain E0422`.\nerror: could not compile `spacetime-module` (lib) due to 5 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:28:10.719260484Z", - "finished_at": "2026-01-26T19:29:24.230351153Z" + "started_at": "2026-01-27T19:51:00.465423417Z", + "finished_at": "2026-01-27T19:51:47.339587032Z" }, "t_003_struct_in_table": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_003_struct_in_table", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, - "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n pos: Position,\n}\n\n#[reducer]\npub fn add_entity(ctx: &ReducerContext, id: i32, x: i32, y: i32) {\n ctx.db.entity().insert(Entity { id, pos: Position { x, y } });\n}", + "passed_tests": 1, + "llm_output": "use spacetimedb::SpacetimeType;\n\n#[derive(SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n pos: Position,\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-003-struct-in-table-golden", @@ -125,30 +125,25 @@ "work_dir_llm": "target/llm-runs/basics/t_003_struct_in_table/rust/server/gpt-5/llm", "scorer_details": { "schema_parity": { - "pass": false, - "partial": 0.0, + "pass": true, + "partial": 1.0, "notes": { "golden_db": "basics-t-003-struct-in-table-golden", "llm_db": "basics-t-003-struct-in-table-gpt-5-llm", - "reducers_diff": { - "only_golden": [], - "only_llm": [ - "add_entity()" - ] - }, - "reducers_equal": false, - "server": "http://127.0.0.1:44233", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:53.381607365Z", - "finished_at": "2026-01-26T19:28:20.526037052Z" + "started_at": "2026-01-27T19:50:43.120116357Z", + "finished_at": "2026-01-27T19:51:34.789700080Z" }, "t_004_insert": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_004_insert", "lang": "rust", "golden_published": true, @@ -163,6 +158,19 @@ "work_dir_golden": "target/llm-runs/basics/t_004_insert/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_004_insert/rust/server/gpt-5/llm", "scorer_details": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-004-insert-golden", + "llm_db": "basics-t-004-insert-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:33615", + "tables_diff": null, + "tables_equal": true + } + }, "data_parity_insert_user": { "pass": true, "partial": 1.0, @@ -179,36 +187,23 @@ "llm_out": "id | name | age | active ----+---------+-----+-------- 1 | \"Alice\" | 30 | true", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "insert_user", - "server": "http://127.0.0.1:44233" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-004-insert-golden", - "llm_db": "basics-t-004-insert-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44233", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:33615" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:28:03.162962728Z", - "finished_at": "2026-01-26T19:28:30.365311126Z" + "started_at": "2026-01-27T19:51:00.012104606Z", + "finished_at": "2026-01-27T19:51:27.169795394Z" }, "t_005_update": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_005_update", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, UniqueColumn};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn update_user(ctx: &ReducerContext, id: i32, name: String, age: i32, active: bool) {\n ctx.db.user().id().update(User { id, name, age, active });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn update_user(ctx: &ReducerContext, id: i32, name: String, age: i32, active: bool) {\n let row = User { id, name, age, active };\n ctx.db.user().id().update(row);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-005-update-golden", @@ -224,18 +219,11 @@ "llm_db": "basics-t-005-update-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } }, - "seed_users_row": { - "pass": true, - "partial": 1.0, - "notes": { - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" - } - }, "data_parity_update_user": { "pass": true, "partial": 1.0, @@ -252,23 +240,30 @@ "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "update_user", - "server": "http://127.0.0.1:44233" + "server": "http://127.0.0.1:33615" + } + }, + "seed_users_row": { + "pass": true, + "partial": 1.0, + "notes": { + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:50.273973455Z", - "finished_at": "2026-01-26T19:28:39.660285285Z" + "started_at": "2026-01-27T19:50:22.268945837Z", + "finished_at": "2026-01-27T19:51:01.660325703Z" }, "t_006_delete": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_006_delete", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn delete_user(ctx: &ReducerContext, id: i32) {\n ctx.db.user().id().delete(&id);\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn delete_user(ctx: &ReducerContext, id: i32) {\n ctx.db.user().id().delete(&id);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-006-delete-golden", @@ -276,6 +271,13 @@ "work_dir_golden": "target/llm-runs/basics/t_006_delete/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_006_delete/rust/server/gpt-5/llm", "scorer_details": { + "seed_users_row": { + "pass": true, + "partial": 1.0, + "notes": { + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -284,7 +286,7 @@ "llm_db": "basics-t-006-delete-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -297,28 +299,21 @@ "expected": 0, "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" } - }, - "seed_users_row": { - "pass": true, - "partial": 1.0, - "notes": { - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:19.862018853Z", - "finished_at": "2026-01-26T19:27:52.325711770Z" + "started_at": "2026-01-27T19:50:18.814239252Z", + "finished_at": "2026-01-27T19:51:00.465380864Z" }, "t_007_crud": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_007_crud", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn crud(ctx: &ReducerContext) {\n let users = ctx.db.user();\n\n users.insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n users.insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n\n let updated = User { id: 1, name: \"Alice2\".to_string(), age: 31, active: false };\n users.id().update(updated);\n\n users.id().delete(&2);\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[reducer]\npub fn crud(ctx: &ReducerContext) {\n let users = ctx.db.user();\n\n // insert (id=1, name=\"Alice\", age=30, active=true)\n users.insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n\n // insert (id=2, name=\"Bob\", age=22, active=false)\n users.insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n\n // update (id=1, name=\"Alice2\", age=31, active=false)\n users.id().update(User {\n id: 1,\n name: \"Alice2\".to_string(),\n age: 31,\n active: false,\n });\n\n // delete id=2\n users.id().delete(&2);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -335,6 +330,19 @@ "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2" } }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-007-crud-golden", + "llm_db": "basics-t-007-crud-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:33615", + "tables_diff": null, + "tables_equal": true + } + }, "crud_total_count_one": { "pass": true, "partial": 1.0, @@ -355,36 +363,23 @@ "llm_out": "id | name | age | active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT id, name, age, active FROM user WHERE id=1", "reducer": "crud", - "server": "http://127.0.0.1:44233" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-007-crud-golden", - "llm_db": "basics-t-007-crud-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44233", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:33615" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:23.893528453Z", - "finished_at": "2026-01-26T19:28:07.775124578Z" + "started_at": "2026-01-27T19:50:19.572189963Z", + "finished_at": "2026-01-27T19:51:00.012056746Z" }, "t_008_index_lookup": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_008_index_lookup", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, UniqueColumn};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(user) = ctx.db.user().id().find(id) {\n let _ = ctx.db.result().id().delete(&id);\n ctx.db.result().insert(ResultRow { id: user.id, name: user.name });\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(user) = ctx.db.user().id().find(id) {\n let _ = ctx.db.result().try_insert(ResultRow {\n id: user.id,\n name: user.name.clone(),\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -392,6 +387,13 @@ "work_dir_golden": "target/llm-runs/basics/t_008_index_lookup/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_008_index_lookup/rust/server/gpt-5/llm", "scorer_details": { + "seed_user_row": { + "pass": true, + "partial": 1.0, + "notes": { + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -400,7 +402,7 @@ "llm_db": "basics-t-008-index-lookup-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -418,30 +420,23 @@ "llm_out": "id | name ----+--------- 1 | \"Alice\"", "query": "SELECT id, name FROM result WHERE id=1", "reducer": "lookup_user_name", - "server": "http://127.0.0.1:44233" - } - }, - "seed_user_row": { - "pass": true, - "partial": 1.0, - "notes": { - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + "server": "http://127.0.0.1:33615" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:28:01.265667865Z", - "finished_at": "2026-01-26T19:28:38.153772708Z" + "started_at": "2026-01-27T19:50:59.032238062Z", + "finished_at": "2026-01-27T19:51:34.520084103Z" }, "t_009_init": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_009_init", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) {\n let user = ctx.db.user();\n user.insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n user.insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) {\n ctx.db.user().insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n ctx.db.user().insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -458,6 +453,15 @@ "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2 AND name='Bob' AND age=22 AND active=false" } }, + "init_seed_alice": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -466,7 +470,7 @@ "llm_db": "basics-t-009-init-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -479,30 +483,21 @@ "expected": 2, "sql": "SELECT COUNT(*) AS n FROM user" } - }, - "init_seed_alice": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:35.047568301Z", - "finished_at": "2026-01-26T19:28:10.719222494Z" + "started_at": "2026-01-27T19:50:21.549783Z", + "finished_at": "2026-01-27T19:50:59.032183836Z" }, "t_010_connect": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_010_connect", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = event)]\npub struct Event {\n #[primary_key]\n #[auto_inc]\n id: i32,\n kind: String,\n}\n\n#[reducer(client_connected)]\npub fn client_connected(ctx: &ReducerContext) {\n ctx.db.event().insert(Event { id: 0, kind: \"connected\".to_string() });\n}\n\n#[reducer(client_disconnected)]\npub fn client_disconnected(ctx: &ReducerContext) {\n ctx.db.event().insert(Event { id: 0, kind: \"disconnected\".to_string() });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = event)]\npub struct Event {\n #[primary_key]\n #[auto_inc]\n id: i32,\n kind: String,\n}\n\n#[spacetimedb::reducer(client_connected)]\npub fn client_connected(ctx: &ReducerContext) {\n let _ = ctx.db.event().insert(Event { id: 0, kind: \"connected\".to_string() });\n}\n\n#[spacetimedb::reducer(client_disconnected)]\npub fn client_disconnected(ctx: &ReducerContext) {\n let _ = ctx.db.event().insert(Event { id: 0, kind: \"disconnected\".to_string() });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-010-connect-golden", @@ -518,25 +513,25 @@ "llm_db": "basics-t-010-connect-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:22.864510006Z", - "finished_at": "2026-01-26T19:28:01.265636007Z" + "started_at": "2026-01-27T19:50:19.565630879Z", + "finished_at": "2026-01-27T19:50:43.120012892Z" }, "t_011_helper_function": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_011_helper_function", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[reducer]\nfn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let sum = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n sum: i32,\n}\n\nfn add(a: i32, b: i32) -> i32 {\n a + b\n}\n\n#[reducer]\npub fn compute_sum(ctx: &ReducerContext, id: i32, a: i32, b: i32) {\n let sum = add(a, b);\n ctx.db.result().insert(ResultRow { id, sum });\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -559,20 +554,7 @@ "llm_out": "id | sum ----+----- 1 | 5", "query": "SELECT id, sum FROM result WHERE id=1", "reducer": "compute_sum", - "server": "http://127.0.0.1:44233" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-011-helper-function-golden", - "llm_db": "basics-t-011-helper-function-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44233", - "tables_diff": null, - "tables_equal": true + "server": "http://127.0.0.1:33615" } }, "helper_func_sum_abs": { @@ -584,24 +566,6 @@ "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" } }, - "helper_func_sum_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "args": [ - 1, - 2, - 3 - ], - "golden_db": "basics-t-011-helper-function-golden", - "golden_out": "id | sum ----+----- 1 | 5", - "llm_db": "basics-t-011-helper-function-gpt-5-llm", - "llm_out": "id | sum ----+----- 1 | 5", - "query": "SELECT id, sum FROM result WHERE id=1", - "reducer": "compute_sum", - "server": "http://127.0.0.1:41115" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -610,25 +574,25 @@ "llm_db": "basics-t-011-helper-function-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:41115", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:28:07.775155436Z", - "finished_at": "2026-01-26T19:28:36.996978868Z" + "started_at": "2026-01-27T19:51:00.227420335Z", + "finished_at": "2026-01-27T19:51:29.538171947Z" }, "t_012_spacetime_product_type": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_012_spacetime_product_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow { id, value: Score { left, right } });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[reducer]\nfn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -653,7 +617,7 @@ "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -673,23 +637,23 @@ "llm_out": "id | value ----+----------------------- 1 | (left = 2, right = 3)", "query": "SELECT id, value FROM result WHERE id=1", "reducer": "set_score", - "server": "http://127.0.0.1:44233" + "server": "http://127.0.0.1:33615" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:19.861773654Z", - "finished_at": "2026-01-26T19:27:55.243933613Z" + "started_at": "2026-01-27T19:50:17.029809591Z", + "finished_at": "2026-01-27T19:50:58.838714798Z" }, "t_013_spacetime_sum_type": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_013_spacetime_sum_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 2, - "llm_output": "use spacetimedb::{reducer, table, ReducerContext, SpacetimeType, Table};\n\n#[derive(SpacetimeType, Clone)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType, Clone)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[reducer]\npub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {\n ctx.db\n .result()\n .insert(ResultRow { id, value: Shape::Circle(radius) });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[reducer]\npub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Shape::Circle(radius),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-013-spacetime-sum-type-golden", @@ -701,19 +665,10 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `result`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200d2d3b6f126b42f6535fa1c89a272d1278f24e7645295553d055f0964bb68/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `result`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef5026b116b67d90edbd0acaca12a273f2a7e6e888cc7265a5d4a4fe7173/sql)\n", "phase": "sql_golden" } }, - "sum_type_row_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -722,25 +677,34 @@ "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } + }, + "sum_type_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" + } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.088386414Z", - "finished_at": "2026-01-26T19:27:19.723979899Z" + "started_at": "2026-01-27T19:49:28.665478058Z", + "finished_at": "2026-01-27T19:50:21.549671530Z" }, "t_014_elementary_columns": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_014_elementary_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3000000000,\n price: 1.5f32,\n ratio: 2.25,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000,\n price: 1.5,\n ratio: 2.25,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-014-elementary-columns-golden", @@ -748,15 +712,6 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/rust/server/gpt-5/llm", "scorer_details": { - "elementary_columns_row_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" - } - }, "elementary_columns_row_parity": { "pass": true, "partial": 1.0, @@ -768,7 +723,7 @@ "llm_out": "id | count | total | price | ratio | active | name ----+-------+------------+-------+-------+--------+--------- 1 | 2 | 3000000000 | 1.5 | 2.25 | true | \"Alice\"", "query": "SELECT id, count, total, price, ratio, active, name FROM primitive WHERE id=1", "reducer": "seed", - "server": "http://127.0.0.1:44233" + "server": "http://127.0.0.1:33615" } }, "schema_parity": { @@ -779,25 +734,34 @@ "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } + }, + "elementary_columns_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" + } } }, "vendor": "openai", - "started_at": "2026-01-26T19:27:08.469170041Z", - "finished_at": "2026-01-26T19:28:03.162920625Z" + "started_at": "2026-01-27T19:50:12.818589409Z", + "finished_at": "2026-01-27T19:51:00.227383147Z" }, "t_015_product_type_columns": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_015_product_type_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, - "passed_tests": 3, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Address {\n street: String,\n zip: i32,\n}\n\n#[derive(SpacetimeType)]\npub struct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = profile)]\npub struct Profile {\n #[primary_key]\n id: i32,\n home: Address,\n work: Address,\n pos: Position,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.profile().insert(Profile {\n id: 1,\n home: Address { street: \"1 Main\".to_string(), zip: 11111 },\n work: Address { street: \"2 Broad\".to_string(), zip: 22222 },\n pos: Position { x: 7, y: 9 },\n });\n}", + "passed_tests": 2, + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType, Clone)]\nstruct Address {\n street: String,\n zip: i32,\n}\n\n#[derive(SpacetimeType, Clone)]\nstruct Position {\n x: i32,\n y: i32,\n}\n\n#[table(name = profile)]\nstruct Profile {\n #[primary_key]\n id: i32,\n home: Address,\n work: Address,\n pos: Position,\n}\n\n#[reducer]\nfn seed(ctx: &ReducerContext) {\n let tbl = ctx.db.profile();\n if tbl.count() == 0 {\n let home = Address { street: \"1 Main\".to_string(), zip: 11111 };\n let work = Address { street: \"2 Broad\".to_string(), zip: 22222 };\n let pos = Position { x: 7, y: 9 };\n tbl.insert(Profile { id: 1, home, work, pos });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-015-product-type-columns-golden", @@ -814,6 +778,14 @@ "sql": "SELECT COUNT(*) AS n FROM profile WHERE id=1" } }, + "product_type_columns_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `profile`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200171a9841d8ed2a9c762ac4e081fe93ed52fe5c9e32ae9bbd874bb7e1a8b5/sql)\n", + "phase": "sql_golden" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -822,39 +794,25 @@ "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } - }, - "product_type_columns_row_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "args": [], - "golden_db": "schema-t-015-product-type-columns-golden", - "golden_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", - "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", - "llm_out": "id | home | work | pos ----+----------------------------------+-----------------------------------+---------------- 1 | (street = \"1 Main\", zip = 11111) | (street = \"2 Broad\", zip = 22222) | (x = 7, y = 9)", - "query": "SELECT id, home, work, pos FROM profile WHERE id=1", - "reducer": "seed", - "server": "http://127.0.0.1:44233" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.089258499Z", - "finished_at": "2026-01-26T19:27:08.469138831Z" + "started_at": "2026-01-27T19:49:28.666090278Z", + "finished_at": "2026-01-27T19:50:19.565536981Z" }, "t_016_sum_type_columns": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_016_sum_type_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 1, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let drawings = ctx.db.drawing();\n for row in drawings.iter() {\n drawings.id().delete(&row.id);\n }\n drawings.insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};\n\n#[derive(SpacetimeType)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n if ctx.db.drawing().id().find(1i32).is_none() {\n ctx.db.drawing().insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-016-sum-type-columns-golden", @@ -862,19 +820,11 @@ "work_dir_golden": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/gpt-5/llm", "scorer_details": { - "sum_type_columns_row_count": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c20072beef7cc108a057376dd8b6be7e2a74798bdfaea38dde4e2e708af5e427/sql)\n", - "phase": "sql" - } - }, "sum_type_columns_row_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c20076700591ec6cb5396663df5e1f56128de954277e753577b8dd7756ee998c/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200881b5220df4b060ef4c2656171f2f8326cecff55db6c3c11d3ebbd2f5cec/sql)\n", "phase": "sql_golden" } }, @@ -886,7 +836,7 @@ "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -895,24 +845,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:41115/v1/database/c2001257ca4ff5c673696324b8a29b10931896a2877a4425230bec1856988aad/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c20074c3ee57884fdd34989755bdcfa11644a8f79ecbbdbf8f5182f2be46b5ec/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.088020973Z", - "finished_at": "2026-01-26T19:27:22.864464632Z" + "started_at": "2026-01-27T19:49:28.665270093Z", + "finished_at": "2026-01-27T19:50:17.767945290Z" }, "t_017_scheduled_columns": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_017_scheduled_columns", "lang": "rust", "golden_published": false, "model_name": "GPT-5", "total_tests": 2, "passed_tests": 0, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::repeat_micros(50_000),\n });\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};\n\n#[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[reducer(init)]\npub fn init(ctx: &ReducerContext) {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::RepeatMicros(50_000),\n });\n }\n}\n\n#[reducer]\npub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -924,24 +874,24 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Blocking waiting for file lock on package cache\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Blocking waiting for file lock on package cache\n Blocking waiting for file lock on package cache\n Compiling proc-macro2 v1.0.106\n Compiling unicode-ident v1.0.22\n Compiling quote v1.0.44\n Compiling version_check v0.9.5\n Compiling typenum v1.19.0\n Compiling autocfg v1.5.0\n Compiling heck v0.5.0\n Compiling serde_core v1.0.228\n Compiling cfg-if v1.0.4\n Compiling find-msvc-tools v0.1.8\n Compiling serde v1.0.228\n Compiling either v1.15.0\n Compiling zerocopy v0.8.34\n Compiling shlex v1.3.0\n Compiling anyhow v1.0.100\n Compiling bitflags v2.10.0\n Compiling thiserror v1.0.69\n Compiling nohash-hasher v0.2.0\n Compiling heck v0.4.1\n Compiling arrayvec v0.7.6\n Compiling zmij v1.0.17\n Compiling convert_case v0.4.0\n Compiling keccak v0.1.5\n Compiling humantime v2.3.0\n Compiling bytes v1.11.0\n Compiling itoa v1.0.17\n Compiling arrayref v0.3.9\n Compiling second-stack v0.3.5\n Compiling smallvec v1.15.1\n Compiling getrandom v0.2.17\n Compiling constant_time_eq v0.4.2\n Compiling cc v1.2.54\n Compiling itertools v0.12.1\n Compiling serde_json v1.0.149\n Compiling hex v0.4.3\n Compiling spacetimedb-lib v1.11.1\n Compiling bytemuck v1.24.0\n Compiling memchr v2.7.6\n Compiling generic-array v0.14.7\n Compiling log v0.4.29\n Compiling scoped-tls v1.0.1\n Compiling rand_core v0.6.4\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling blake3 v1.8.3\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling decorum v0.3.1\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ppv-lite86 v0.2.21\n Compiling ethnum v1.5.2\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm)\nerror: expected `at`\n --> src/lib.rs:4:38\n |\n4 | #[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]\n | ^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:14:32\n |\n14 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0412]: cannot find type `TickTimer` in this scope\n --> src/lib.rs:21:42\n |\n21 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:12\n |\n14 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `repeat_micros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:16:35\n |\n16 | scheduled_at: ScheduleAt::repeat_micros(50_000),\n | ^^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:21:8\n |\n 20 | #[reducer]\n | ---------- required by a bound introduced by this call\n 21 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `register_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:746:81\n |\n746 | pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) {\n | ^^^^^^^^^^^^^^ required by this bound in `register_reducer`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:21:8\n |\n20 | #[reducer]\n | ---------- required by a bound introduced by this call\n21 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `invoke_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:45:19\n |\n44 | pub fn invoke_reducer<'a, A: Args<'a>>(\n | -------------- required by a bound in this function\n45 | reducer: impl Reducer<'a, A>,\n | ^^^^^^^^^^^^^^ required by this bound in `invoke_reducer`\n\nSome errors have detailed explanations: E0277, E0412, E0422, E0599.\nFor more information about an error, try `rustc --explain E0277`.\nerror: could not compile `spacetime-module` (lib) due to 7 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", + "error": "spacetime publish failed (exit=1)\n--- stderr ---\n Updating crates.io index\n Locking 72 packages to latest compatible versions\n Adding generic-array v0.14.7 (available: v0.14.9)\n Adding spacetimedb v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-macro v1.11.1 (available: v1.11.3)\n Adding spacetimedb-bindings-sys v1.11.1 (available: v1.11.3)\n Adding spacetimedb-lib v1.11.1 (available: v1.11.3)\n Adding spacetimedb-primitives v1.11.1 (available: v1.11.3)\n Adding spacetimedb-sats v1.11.1 (available: v1.11.3)\n Compiling proc-macro2 v1.0.106\n Compiling unicode-ident v1.0.22\n Compiling quote v1.0.44\n Compiling typenum v1.19.0\n Compiling version_check v0.9.5\n Compiling autocfg v1.5.0\n Compiling heck v0.5.0\n Compiling serde_core v1.0.228\n Compiling cfg-if v1.0.4\n Compiling either v1.15.0\n Compiling serde v1.0.228\n Compiling find-msvc-tools v0.1.8\n Compiling shlex v1.3.0\n Compiling zerocopy v0.8.34\n Compiling nohash-hasher v0.2.0\n Compiling anyhow v1.0.100\n Compiling thiserror v1.0.69\n Compiling bitflags v2.10.0\n Compiling keccak v0.1.5\n Compiling convert_case v0.4.0\n Compiling zmij v1.0.17\n Compiling arrayvec v0.7.6\n Compiling humantime v2.3.0\n Compiling bytes v1.11.0\n Compiling heck v0.4.1\n Compiling second-stack v0.3.5\n Compiling hex v0.4.3\n Compiling serde_json v1.0.149\n Compiling constant_time_eq v0.4.2\n Compiling itoa v1.0.17\n Compiling arrayref v0.3.9\n Compiling getrandom v0.2.17\n Compiling spacetimedb-lib v1.11.1\n Compiling bytemuck v1.24.0\n Compiling smallvec v1.15.1\n Compiling rand_core v0.6.4\n Compiling cc v1.2.54\n Compiling log v0.4.29\n Compiling memchr v2.7.6\n Compiling scoped-tls v1.0.1\n Compiling generic-array v0.14.7\n Compiling itertools v0.12.1\n Compiling num-traits v0.2.19\n Compiling http v1.4.0\n Compiling syn v2.0.114\n Compiling approx v0.3.2\n Compiling chrono v0.4.43\n Compiling decorum v0.3.1\n Compiling blake3 v1.8.3\n Compiling crypto-common v0.1.7\n Compiling block-buffer v0.10.4\n Compiling digest v0.10.7\n Compiling sha3 v0.10.8\n Compiling ethnum v1.5.2\n Compiling ppv-lite86 v0.2.21\n Compiling rand_chacha v0.3.1\n Compiling rand v0.8.5\n Compiling enum-as-inner v0.6.1\n Compiling thiserror-impl v1.0.69\n Compiling derive_more v0.99.20\n Compiling spacetimedb-primitives v1.11.1\n Compiling spacetimedb-bindings-macro v1.11.1\n Compiling spacetimedb-bindings-sys v1.11.1\n Compiling spacetimedb-sats v1.11.1\n Compiling spacetimedb v1.11.1\n Compiling spacetime-module v0.1.0 (/__w/SpacetimeDB/SpacetimeDB/target/llm-runs/schema/t_017_scheduled_columns/rust/server/gpt-5/llm)\nerror: expected one of: `public`, `private`, `name`, `index`, `scheduled`\n --> src/lib.rs:4:28\n |\n4 | #[table(name = tick_timer, schedule(reducer = tick, column = scheduled_at))]\n | ^^^^^^^^\n\nerror[E0422]: cannot find struct, variant or union type `TickTimer` in this scope\n --> src/lib.rs:15:36\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0412]: cannot find type `TickTimer` in this scope\n --> src/lib.rs:23:42\n |\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^^^^^^ not found in this scope\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:14:15\n |\n14 | if ctx.db.tick_timer().count() == 0 {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no method named `tick_timer` found for struct `Local` in the current scope\n --> src/lib.rs:15:16\n |\n15 | ctx.db.tick_timer().insert(TickTimer {\n | ^^^^^^^^^^ method not found in `Local`\n\nerror[E0599]: no variant or associated item named `RepeatMicros` found for enum `ScheduleAt` in the current scope\n --> src/lib.rs:17:39\n |\n17 | scheduled_at: ScheduleAt::RepeatMicros(50_000),\n | ^^^^^^^^^^^^ variant or associated item not found in `ScheduleAt`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n 22 | #[reducer]\n | ---------- required by a bound introduced by this call\n 23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `register_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:746:81\n |\n746 | pub fn register_reducer<'a, A: Args<'a>, I: FnInfo>(_: impl Reducer<'a, A>) {\n | ^^^^^^^^^^^^^^ required by this bound in `register_reducer`\n\nerror[E0277]: invalid reducer signature\n --> src/lib.rs:23:8\n |\n22 | #[reducer]\n | ---------- required by a bound introduced by this call\n23 | pub fn tick(_ctx: &ReducerContext, _row: TickTimer) {\n | ^^^^ this reducer signature is not valid\n |\n = help: the trait `Reducer<'_, _>` is not implemented for fn item `for<'a> fn(&'a ReducerContext, {type error}) {tick}`\n = note: \n = note: reducer signatures must match the following pattern:\n = note: `Fn(&ReducerContext, [T1, ...]) [-> Result<(), impl Display>]`\n = note: where each `Ti` type implements `SpacetimeType`.\n = note: \nnote: required by a bound in `invoke_reducer`\n --> /root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/spacetimedb-1.11.1/src/rt.rs:45:19\n |\n44 | pub fn invoke_reducer<'a, A: Args<'a>>(\n | -------------- required by a bound in this function\n45 | reducer: impl Reducer<'a, A>,\n | ^^^^^^^^^^^^^^ required by this bound in `invoke_reducer`\n\nSome errors have detailed explanations: E0277, E0412, E0422, E0599.\nFor more information about an error, try `rustc --explain E0277`.\nerror: could not compile `spacetime-module` (lib) due to 8 previous errors\nError: command [\"cargo\", \"build\", \"--config=net.git-fetch-with-cli=true\", \"--target=wasm32-unknown-unknown\", \"--release\", \"--message-format=json-render-diagnostics\"] exited with code 101\n\n--- stdout ---\n", "phase": "build_or_publish" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.087192758Z", - "finished_at": "2026-01-26T19:27:53.381568310Z" + "started_at": "2026-01-27T19:49:28.664841535Z", + "finished_at": "2026-01-27T19:50:33.923572352Z" }, "t_018_constraints": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_018_constraints", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 2, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let t = ctx.db.account();\n t.insert(Account { id: 1, email: \"a@example.com\".to_string(), name: \"Alice\".to_string() });\n t.insert(Account { id: 2, email: \"b@example.com\".to_string(), name: \"Bob\".to_string() });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let accounts = ctx.db.account();\n let _ = accounts.try_insert(Account { id: 1, email: \"a@example.com\".to_string(), name: \"Alice\".to_string() });\n let _ = accounts.try_insert(Account { id: 2, email: \"b@example.com\".to_string(), name: \"Bob\".to_string() });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-018-constraints-golden", @@ -949,12 +899,17 @@ "work_dir_golden": "target/llm-runs/schema/t_018_constraints/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_018_constraints/rust/server/gpt-5/llm", "scorer_details": { - "constraints_row_parity_after_seed": { - "pass": false, - "partial": 0.0, + "schema_parity": { + "pass": true, + "partial": 1.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `account`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200ce532d202b333f35de1400d0f2b40c51bd06fe40198129dd9b2a5b0d196e/sql)\n", - "phase": "sql_golden" + "golden_db": "schema-t-018-constraints-golden", + "llm_db": "schema-t-018-constraints-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:33615", + "tables_diff": null, + "tables_equal": true } }, "constraints_seed_two_rows": { @@ -970,43 +925,24 @@ "pass": false, "partial": 0.0, "notes": { - "args": [], - "golden_db": "schema-t-018-constraints-golden", - "golden_out": "id | email | name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", - "llm_db": "schema-t-018-constraints-gpt-5-llm", - "llm_out": "id | email | name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", - "query": "SELECT id, email, name FROM account WHERE id=1", - "reducer": "seed", - "server": "http://127.0.0.1:41115" - } - }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-018-constraints-golden", - "llm_db": "schema-t-018-constraints-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44233", - "tables_diff": null, - "tables_equal": true + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `account`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c2002f3e10afac17bd0350f8d8feb90d1ae94d73c7c44c6824e7324679a8e5b9/sql)\n", + "phase": "sql_golden" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.086684099Z", - "finished_at": "2026-01-26T19:27:19.861734913Z" + "started_at": "2026-01-27T19:49:28.664543506Z", + "finished_at": "2026-01-27T19:50:17.029704757Z" }, "t_019_many_to_many": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_019_many_to_many", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 5, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = user)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[table(name = group)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[table(\n name = membership,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n {\n let tbl = ctx.db.membership();\n let ids: Vec = tbl.iter().map(|r| r.id).collect();\n for id in ids {\n tbl.id().delete(&id);\n }\n }\n {\n let tbl = ctx.db.user();\n let ids: Vec = tbl.iter().map(|r| r.user_id).collect();\n for id in ids {\n tbl.user_id().delete(&id);\n }\n }\n {\n let tbl = ctx.db.group();\n let ids: Vec = tbl.iter().map(|r| r.group_id).collect();\n for id in ids {\n tbl.group_id().delete(&id);\n }\n }\n\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".to_string() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".to_string() });\n\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".to_string() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".to_string() });\n\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[spacetimedb::table(name = group)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[spacetimedb::table(\n name = membership,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n // Clear existing rows to ensure the database contains exactly the specified rows.\n let membership_ids: Vec = ctx.db.membership().iter().map(|m| m.id).collect();\n for id in membership_ids {\n ctx.db.membership().id().delete(&id);\n }\n\n let user_ids: Vec = ctx.db.user().iter().map(|u| u.user_id).collect();\n for id in user_ids {\n ctx.db.user().user_id().delete(&id);\n }\n\n let group_ids: Vec = ctx.db.group().iter().map(|g| g.group_id).collect();\n for id in group_ids {\n ctx.db.group().group_id().delete(&id);\n }\n\n // Insert users\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".to_string() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".to_string() });\n\n // Insert groups\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".to_string() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".to_string() });\n\n // Insert memberships\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-019-many-to-many-golden", @@ -1014,13 +950,26 @@ "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/rust/server/gpt-5/llm", "scorer_details": { - "m2m_has_1_10": { + "m2m_has_2_20": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-019-many-to-many-golden", + "llm_db": "schema-t-019-many-to-many-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:33615", + "tables_diff": null, + "tables_equal": true } }, "m2m_has_1_20": { @@ -1032,51 +981,38 @@ "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" } }, - "memberships_three_rows": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM membership" - } - }, - "m2m_has_2_20": { + "m2m_has_1_10": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=10" } }, - "schema_parity": { + "memberships_three_rows": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "schema-t-019-many-to-many-golden", - "llm_db": "schema-t-019-many-to-many-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44233", - "tables_diff": null, - "tables_equal": true + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM membership" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.088752482Z", - "finished_at": "2026-01-26T19:27:50.273815091Z" + "started_at": "2026-01-27T19:49:28.665682949Z", + "finished_at": "2026-01-27T19:50:22.268882588Z" }, "t_020_ecs": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_020_ecs", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 1, - "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.entity().insert(Entity { id: 1 });\n ctx.db.position().insert(Position { entity_id: 1, x: 0, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n ctx.db.entity().insert(Entity { id: 2 });\n ctx.db.position().insert(Position { entity_id: 2, x: 10, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n}\n\n#[reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let next = NextPosition {\n entity_id: pos.entity_id,\n x: pos.x + vel.vx,\n y: pos.y + vel.vy,\n };\n\n if ctx.db.next_position().entity_id().find(pos.entity_id).is_some() {\n ctx.db.next_position().entity_id().update(next);\n } else {\n ctx.db.next_position().insert(next);\n }\n }\n }\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let _ = ctx.db.entity().try_insert(Entity { id: 1 });\n let _ = ctx.db.entity().try_insert(Entity { id: 2 });\n\n let _ = ctx.db.position().try_insert(Position { entity_id: 1, x: 0, y: 0 });\n let _ = ctx.db.velocity().try_insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n let _ = ctx.db.position().try_insert(Position { entity_id: 2, x: 10, y: 0 });\n let _ = ctx.db.velocity().try_insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n}\n\n#[reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let nx = pos.x + vel.vx;\n let ny = pos.y + vel.vy;\n\n if let Some(mut existing) = ctx.db.next_position().entity_id().find(pos.entity_id) {\n existing.x = nx;\n existing.y = ny;\n let _ = ctx.db.next_position().entity_id().update(existing);\n } else {\n let _ = ctx.db.next_position().try_insert(NextPosition {\n entity_id: pos.entity_id,\n x: nx,\n y: ny,\n });\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-020-ecs-golden", @@ -1088,7 +1024,7 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", "phase": "sql" } }, @@ -1096,15 +1032,7 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", - "phase": "sql" - } - }, - "ecs_seed_positions_count": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", "phase": "sql" } }, @@ -1116,7 +1044,7 @@ "llm_db": "schema-t-020-ecs-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -1125,24 +1053,32 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", + "phase": "sql" + } + }, + "ecs_seed_positions_count": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:33615/v1/database/c200ef190fe9bac0d026751d082f663c75cb0435d300fdc35e1bc1f038529566/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.089004480Z", - "finished_at": "2026-01-26T19:27:35.047523671Z" + "started_at": "2026-01-27T19:49:28.665885964Z", + "finished_at": "2026-01-27T19:50:18.814108696Z" }, "t_021_multi_column_index": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "task": "t_021_multi_column_index", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = log, index(name = by_user_day, btree(columns = [user_id, day])))]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let ids: Vec = ctx.db.log().iter().map(|r| r.id).collect();\n for id in ids {\n ctx.db.log().id().delete(&id);\n }\n\n ctx.db.log().insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".to_string() });\n ctx.db.log().insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".to_string() });\n ctx.db.log().insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".to_string() });\n}", + "llm_output": "use spacetimedb::{table, reducer, ReducerContext, Table};\n\n#[table(name = log, index(name = by_user_day, btree(columns = [user_id, day])))]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[reducer]\npub fn seed(ctx: &ReducerContext) {\n let table = ctx.db.log();\n table.insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".to_string() });\n table.insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".to_string() });\n table.insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".to_string() });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-021-multi-column-index-golden", @@ -1158,7 +1094,7 @@ "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44233", + "server": "http://127.0.0.1:33615", "tables_diff": null, "tables_equal": true } @@ -1172,16 +1108,16 @@ "sql": "SELECT COUNT(*) AS n FROM log" } }, - "mcindex_lookup_u7_d2": { + "mcindex_lookup_u7_d1": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2" + "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" } }, - "mcindex_lookup_u7_d1": { + "mcindex_lookup_u7_d2": { "pass": true, "partial": 1.0, "notes": { @@ -1192,8 +1128,8 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:26:39.087595992Z", - "finished_at": "2026-01-26T19:27:23.893472645Z" + "started_at": "2026-01-27T19:49:28.665048738Z", + "finished_at": "2026-01-27T19:50:12.818516478Z" } } } @@ -1201,21 +1137,21 @@ }, { "mode": "docs", - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_000_empty_reducers", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(_ctx: &ReducerContext) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(_ctx: &ReducerContext, count: i32) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(_ctx: &ReducerContext, name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(_ctx: &ReducerContext, count: i32, name: String) {\n}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(_ctx: &ReducerContext, active: bool, ratio: f32, label: String) {\n}", + "llm_output": "use spacetimedb::ReducerContext;\n\n#[spacetimedb::reducer]\npub fn empty_reducer_no_args(ctx: &ReducerContext) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_int(ctx: &ReducerContext, count: i32) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_string(ctx: &ReducerContext, name: String) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_two_args(ctx: &ReducerContext, count: i32, name: String) {}\n\n#[spacetimedb::reducer]\npub fn empty_reducer_with_three_args(ctx: &ReducerContext, active: bool, ratio: f32, label: String) {}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-000-empty-reducers-golden", @@ -1233,11 +1169,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:54.611008723Z", - "finished_at": "2026-01-26T19:31:59.326178772Z" + "started_at": "2026-01-27T19:53:02.635478741Z", + "finished_at": "2026-01-27T19:53:40.787269737Z" }, "t_001_basic_tables": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_001_basic_tables", "lang": "rust", "golden_published": true, @@ -1262,18 +1198,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:31:23.564110648Z", - "finished_at": "2026-01-26T19:32:09.696102989Z" + "started_at": "2026-01-27T19:53:04.338845678Z", + "finished_at": "2026-01-27T19:53:39.243226783Z" }, "t_002_scheduled_table": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_002_scheduled_table", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 0, - "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().try_insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n })?;\n }\n Ok(())\n}", + "llm_output": "use spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) -> Result<(), String> {\n Ok(())\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n if ctx.db.tick_timer().count() == 0 {\n use std::time::Duration;\n ctx.db.tick_timer().insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n });\n }\n Ok(())\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -1291,11 +1227,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:32:03.232154280Z", - "finished_at": "2026-01-26T19:32:55.980604615Z" + "started_at": "2026-01-27T19:53:38.403872273Z", + "finished_at": "2026-01-27T19:54:31.831288022Z" }, "t_003_struct_in_table": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_003_struct_in_table", "lang": "rust", "golden_published": true, @@ -1320,11 +1256,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:31:11.581070012Z", - "finished_at": "2026-01-26T19:32:09.839951728Z" + "started_at": "2026-01-27T19:53:02.638916802Z", + "finished_at": "2026-01-27T19:53:40.055864699Z" }, "t_004_insert": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_004_insert", "lang": "rust", "golden_published": true, @@ -1339,29 +1275,29 @@ "work_dir_golden": "target/llm-runs/basics/t_004_insert/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_004_insert/rust/server/gpt-5/llm", "scorer_details": { - "data_parity_insert_user": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", - "phase": "call_reducer_golden" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", + "phase": "describe_golden" } }, - "schema_parity": { + "data_parity_insert_user": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", - "phase": "describe_golden" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-004-insert-golden`.\n", + "phase": "call_reducer_golden" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:31:53.617759187Z", - "finished_at": "2026-01-26T19:32:28.129265268Z" + "started_at": "2026-01-27T19:53:33.748279444Z", + "finished_at": "2026-01-27T19:53:56.014195443Z" }, "t_005_update": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_005_update", "lang": "rust", "golden_published": true, @@ -1376,13 +1312,12 @@ "work_dir_golden": "target/llm-runs/basics/t_005_update/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_005_update/rust/server/gpt-5/llm", "scorer_details": { - "seed_users_row": { + "data_parity_update_user": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", - "phase": "sql_golden", - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", + "phase": "call_reducer_golden" } }, "schema_parity": { @@ -1393,21 +1328,22 @@ "phase": "describe_golden" } }, - "data_parity_update_user": { + "seed_users_row": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", - "phase": "call_reducer_golden" + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-005-update-golden`.\n", + "phase": "sql_golden", + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:54.604964500Z", - "finished_at": "2026-01-26T19:31:53.617639721Z" + "started_at": "2026-01-27T19:53:00.578961998Z", + "finished_at": "2026-01-27T19:53:38.403844461Z" }, "t_006_delete": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_006_delete", "lang": "rust", "golden_published": true, @@ -1430,6 +1366,15 @@ "phase": "describe_golden" } }, + "seed_users_row": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-006-delete-golden`.\n", + "phase": "sql_golden", + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + } + }, "delete_user_count_zero": { "pass": true, "partial": 1.0, @@ -1438,29 +1383,21 @@ "expected": 0, "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1" } - }, - "schema_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-006-delete-golden`.\n", - "phase": "describe_golden" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:54.580009457Z", - "finished_at": "2026-01-26T19:32:03.232098066Z" + "started_at": "2026-01-27T19:52:31.910165978Z", + "finished_at": "2026-01-27T19:52:58.192517311Z" }, "t_007_crud": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_007_crud", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 1, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer]\npub fn crud(ctx: &ReducerContext) {\n ctx.db.user().insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n ctx.db.user().insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n\n if ctx.db.user().id().find(1).is_some() {\n ctx.db.user().id().update(User { id: 1, name: \"Alice2\".to_string(), age: 31, active: false });\n }\n\n ctx.db.user().id().delete(2);\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer]\npub fn crud(ctx: &ReducerContext) {\n ctx.db.user().insert(User { id: 1, name: \"Alice\".into(), age: 30, active: true });\n ctx.db.user().insert(User { id: 2, name: \"Bob\".into(), age: 22, active: false });\n ctx.db.user().id().update(User { id: 1, name: \"Alice2\".into(), age: 31, active: false });\n ctx.db.user().id().delete(2);\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -1468,12 +1405,12 @@ "work_dir_golden": "target/llm-runs/basics/t_007_crud/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_007_crud/rust/server/gpt-5/llm", "scorer_details": { - "schema_parity": { + "crud_row_id1_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", - "phase": "describe_golden" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", + "phase": "call_reducer_golden" } }, "crud_total_count_one": { @@ -1485,12 +1422,12 @@ "sql": "SELECT COUNT(*) AS n FROM user" } }, - "crud_row_id1_parity": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", - "phase": "call_reducer_golden" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-007-crud-golden`.\n", + "phase": "describe_golden" } }, "crud_row_id2_deleted": { @@ -1504,18 +1441,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:54.591258099Z", - "finished_at": "2026-01-26T19:32:19.735936055Z" + "started_at": "2026-01-27T19:52:42.328837521Z", + "finished_at": "2026-01-27T19:53:33.740284067Z" }, "t_008_index_lookup": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_008_index_lookup", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user, public)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::table(name = result, public)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(u) = ctx.db.user().id().find(id) {\n ctx.db.result().id().delete(&id);\n ctx.db.result().insert(ResultRow { id: u.id, name: u.name });\n }\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn lookup_user_name(ctx: &ReducerContext, id: i32) {\n if let Some(user) = ctx.db.user().id().find(id) {\n let row = ResultRow { id: user.id, name: user.name.clone() };\n if ctx.db.result().id().find(user.id).is_some() {\n ctx.db.result().id().update(row);\n } else {\n ctx.db.result().insert(row);\n }\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -1523,15 +1460,6 @@ "work_dir_golden": "target/llm-runs/basics/t_008_index_lookup/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_008_index_lookup/rust/server/gpt-5/llm", "scorer_details": { - "seed_user_row": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-008-index-lookup-golden`.\n", - "phase": "sql_golden", - "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" - } - }, "schema_parity": { "pass": false, "partial": 0.0, @@ -1547,21 +1475,30 @@ "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-008-index-lookup-golden`.\n", "phase": "call_reducer_golden" } + }, + "seed_user_row": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-008-index-lookup-golden`.\n", + "phase": "sql_golden", + "sql": "INSERT INTO user(id, name, age, active) VALUES (1, 'Alice', 30, true)" + } } }, "vendor": "openai", - "started_at": "2026-01-26T19:31:52.996077836Z", - "finished_at": "2026-01-26T19:32:44.567947473Z" + "started_at": "2026-01-27T19:53:17.657026192Z", + "finished_at": "2026-01-27T19:53:54.093778910Z" }, "t_009_init": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_009_init", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 3, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.user().insert(User {\n id: 1,\n name: \"Alice\".to_string(),\n age: 30,\n active: true,\n });\n ctx.db.user().insert(User {\n id: 2,\n name: \"Bob\".to_string(),\n age: 22,\n active: false,\n });\n Ok(())\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = user)]\npub struct User {\n #[primary_key]\n id: i32,\n name: String,\n age: i32,\n active: bool,\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.user().insert(User { id: 1, name: \"Alice\".to_string(), age: 30, active: true });\n ctx.db.user().insert(User { id: 2, name: \"Bob\".to_string(), age: 22, active: false });\n Ok(())\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-009-init-golden", @@ -1569,13 +1506,13 @@ "work_dir_golden": "target/llm-runs/basics/t_009_init/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_009_init/rust/server/gpt-5/llm", "scorer_details": { - "init_seed_alice": { + "init_seed_bob": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2 AND name='Bob' AND age=22 AND active=false" } }, "schema_parity": { @@ -1595,22 +1532,22 @@ "sql": "SELECT COUNT(*) AS n FROM user" } }, - "init_seed_bob": { + "init_seed_alice": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM user WHERE id=2 AND name='Bob' AND age=22 AND active=false" + "sql": "SELECT COUNT(*) AS n FROM user WHERE id=1 AND name='Alice' AND age=30 AND active=true" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:54.597845517Z", - "finished_at": "2026-01-26T19:32:17.483969682Z" + "started_at": "2026-01-27T19:52:58.192552680Z", + "finished_at": "2026-01-27T19:53:38.342926441Z" }, "t_010_connect": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_010_connect", "lang": "rust", "golden_published": true, @@ -1635,11 +1572,11 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:54.585220084Z", - "finished_at": "2026-01-26T19:31:52.995965049Z" + "started_at": "2026-01-27T19:52:35.522740907Z", + "finished_at": "2026-01-27T19:53:02.635440935Z" }, "t_011_helper_function": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_011_helper_function", "lang": "rust", "golden_published": true, @@ -1654,29 +1591,21 @@ "work_dir_golden": "target/llm-runs/basics/t_011_helper_function/rust/server/golden", "work_dir_llm": "target/llm-runs/basics/t_011_helper_function/rust/server/gpt-5/llm", "scorer_details": { - "helper_func_sum_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-011-helper-function-golden`.\n", - "phase": "call_reducer_golden" - } - }, - "schema_parity": { + "helper_func_sum_abs": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-011-helper-function-golden`.\n", - "phase": "describe_golden" + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" } }, - "helper_func_sum_abs": { + "helper_func_sum_parity": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1 AND sum=5" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `basics-t-011-helper-function-golden`.\n", + "phase": "call_reducer_golden" } }, "schema_parity": { @@ -1689,18 +1618,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:31:59.326285562Z", - "finished_at": "2026-01-26T19:32:34.857458085Z" + "started_at": "2026-01-27T19:53:37.773674958Z", + "finished_at": "2026-01-27T19:53:57.689433966Z" }, "t_012_spacetime_product_type": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_012_spacetime_product_type", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[derive(spacetimedb::SpacetimeType, Clone)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[spacetimedb::reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db\n .result()\n .insert(ResultRow { id, value: Score { left, right } });\n}", + "llm_output": "use spacetimedb::{ReducerContext, SpacetimeType, Table};\n\n#[derive(SpacetimeType)]\npub struct Score {\n left: i32,\n right: i32,\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Score,\n}\n\n#[spacetimedb::reducer]\npub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Score { left, right },\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -1708,13 +1637,12 @@ "work_dir_golden": "target/llm-runs/schema/t_012_spacetime_product_type/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_012_spacetime_product_type/rust/server/gpt-5/llm", "scorer_details": { - "product_type_row_count": { + "product_type_row_parity": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-012-spacetime-product-type-golden`.\n", + "phase": "call_reducer_golden" } }, "schema_parity": { @@ -1725,57 +1653,75 @@ "phase": "describe_golden" } }, - "product_type_row_parity": { + "product_type_row_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-012-spacetime-product-type-golden`.\n", - "phase": "call_reducer_golden" + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:31.399995435Z", - "finished_at": "2026-01-26T19:31:11.581019739Z" + "started_at": "2026-01-27T19:52:29.436388253Z", + "finished_at": "2026-01-27T19:53:04.338818518Z" }, "t_013_spacetime_sum_type": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_013_spacetime_sum_type", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, + "total_tests": 3, "passed_tests": 0, - "llm_output": null, + "llm_output": "use spacetimedb::Table;\n\n#[derive(spacetimedb::SpacetimeType, Clone, Debug)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(spacetimedb::SpacetimeType, Clone, Debug)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[spacetimedb::table(name = result)]\npub struct ResultRow {\n #[primary_key]\n id: i32,\n value: Shape,\n}\n\n#[spacetimedb::reducer]\npub fn set_circle(ctx: &spacetimedb::ReducerContext, id: i32, radius: i32) {\n ctx.db.result().insert(ResultRow {\n id,\n value: Shape::Circle(radius),\n });\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-013-spacetime-sum-type-golden", + "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_013_spacetime_sum_type/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-013-spacetime-sum-type-golden`.\n", + "phase": "describe_golden" + } + }, + "sum_type_row_count": { + "pass": false, + "partial": 0.0, + "notes": { + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM result WHERE id=1" + } + }, + "sum_type_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-013-spacetime-sum-type-golden`.\n", + "phase": "call_reducer_golden" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:32:55.980673255Z", - "finished_at": "2026-01-26T19:32:55.980673255Z" + "started_at": "2026-01-27T19:51:47.638500741Z", + "finished_at": "2026-01-27T19:53:00.578888253Z" }, "t_014_elementary_columns": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_014_elementary_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 0, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive, public)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000,\n price: 1.5f32,\n ratio: 2.25,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = primitive)]\npub struct Primitive {\n #[primary_key]\n id: i32,\n count: i32,\n total: i64,\n price: f32,\n ratio: f64,\n active: bool,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.primitive().insert(Primitive {\n id: 1,\n count: 2,\n total: 3_000_000_000i64,\n price: 1.5f32,\n ratio: 2.25f64,\n active: true,\n name: \"Alice\".to_string(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-014-elementary-columns-golden", @@ -1791,30 +1737,30 @@ "phase": "call_reducer_golden" } }, - "schema_parity": { + "elementary_columns_row_count": { "pass": false, "partial": 0.0, "notes": { - "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", - "phase": "describe_golden" + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" } }, - "elementary_columns_row_count": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "actual": 0, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM primitive WHERE id=1" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-014-elementary-columns-golden`.\n", + "phase": "describe_golden" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:30:30.882003264Z", - "finished_at": "2026-01-26T19:31:23.563975616Z" + "started_at": "2026-01-27T19:52:27.568323309Z", + "finished_at": "2026-01-27T19:53:02.605112864Z" }, "t_015_product_type_columns": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_015_product_type_columns", "lang": "rust", "golden_published": false, @@ -1839,47 +1785,63 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:32:55.980689378Z", - "finished_at": "2026-01-26T19:32:55.980689378Z" + "started_at": "2026-01-27T19:54:31.831326960Z", + "finished_at": "2026-01-27T19:54:31.831326960Z" }, "t_016_sum_type_columns": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_016_sum_type_columns", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, + "total_tests": 3, "passed_tests": 0, - "llm_output": null, + "llm_output": "use spacetimedb::{ReducerContext, SpacetimeType, Table};\n\n#[derive(SpacetimeType, Clone, Debug)]\npub struct Rect {\n width: i32,\n height: i32,\n}\n\n#[derive(SpacetimeType, Clone, Debug)]\npub enum Shape {\n Circle(i32),\n Rectangle(Rect),\n}\n\n#[spacetimedb::table(name = drawing)]\npub struct Drawing {\n #[primary_key]\n id: i32,\n a: Shape,\n b: Shape,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n if ctx.db.drawing().count() == 0 {\n ctx.db.drawing().insert(Drawing {\n id: 1,\n a: Shape::Circle(10),\n b: Shape::Rectangle(Rect { width: 4, height: 6 }),\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-016-sum-type-columns-golden", + "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_016_sum_type_columns/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-016-sum-type-columns-golden`.\n", + "phase": "describe_golden" + } + }, + "sum_type_columns_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-016-sum-type-columns-golden`.\n", + "phase": "call_reducer_golden" + } + }, + "sum_type_columns_row_count": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c200596b7e7f2350abeb00119177ef3448e7673481a61aeaa7c22e4dd952cb52/sql)\n", + "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:32:55.980668485Z", - "finished_at": "2026-01-26T19:32:55.980668485Z" + "started_at": "2026-01-27T19:51:47.634170474Z", + "finished_at": "2026-01-27T19:52:27.568235316Z" }, "t_017_scheduled_columns": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_017_scheduled_columns", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 2, "passed_tests": 1, - "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n ctx.db.tick_timer().try_insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n })?;\n Ok(())\n}", + "llm_output": "use std::time::Duration;\nuse spacetimedb::{ReducerContext, ScheduleAt, Table};\n\n#[spacetimedb::table(name = tick_timer, scheduled(tick))]\npub struct TickTimer {\n #[primary_key]\n #[auto_inc]\n scheduled_id: u64,\n scheduled_at: ScheduleAt,\n}\n\n#[spacetimedb::reducer]\npub fn tick(_ctx: &ReducerContext, _tick_timer: TickTimer) -> Result<(), String> {\n Ok(())\n}\n\n#[spacetimedb::reducer(init)]\npub fn init(ctx: &ReducerContext) -> Result<(), String> {\n if ctx.db.tick_timer().count() == 0 {\n ctx.db.tick_timer().try_insert(TickTimer {\n scheduled_id: 0,\n scheduled_at: ScheduleAt::Interval(Duration::from_micros(50_000).into()),\n })?;\n }\n Ok(())\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -1906,105 +1868,190 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:29:24.576470966Z", - "finished_at": "2026-01-26T19:30:31.399943290Z" + "started_at": "2026-01-27T19:51:47.625840249Z", + "finished_at": "2026-01-27T19:52:35.522695487Z" }, "t_018_constraints": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_018_constraints", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, + "total_tests": 3, "passed_tests": 0, - "llm_output": null, + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = account, index(name = by_name, btree(columns = [name])))]\npub struct Account {\n #[primary_key]\n id: i32,\n #[unique]\n email: String,\n name: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let ids: Vec = ctx.db.account().iter().map(|a| a.id).collect();\n for id in ids {\n ctx.db.account().id().delete(id);\n }\n\n ctx.db.account().insert(Account {\n id: 1,\n email: \"a@example.com\".into(),\n name: \"Alice\".into(),\n });\n ctx.db.account().insert(Account {\n id: 2,\n email: \"b@example.com\".into(),\n name: \"Bob\".into(),\n });\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-018-constraints-golden", + "llm_db": "schema-t-018-constraints-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_018_constraints/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_018_constraints/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "constraints_row_parity_after_seed": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "spacetime call failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-018-constraints-golden`.\n", + "phase": "call_reducer_golden" } - } - }, + }, + "schema_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-018-constraints-golden`.\n", + "phase": "describe_golden" + } + }, + "constraints_seed_two_rows": { + "pass": false, + "partial": 0.0, + "notes": { + "actual": 0, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM account WHERE id=2" + } + } + }, "vendor": "openai", - "started_at": "2026-01-26T19:32:55.980661308Z", - "finished_at": "2026-01-26T19:32:55.980661308Z" + "started_at": "2026-01-27T19:51:47.622424031Z", + "finished_at": "2026-01-27T19:53:37.773579225Z" }, "t_019_many_to_many": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_019_many_to_many", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, - "passed_tests": 0, - "llm_output": null, + "total_tests": 5, + "passed_tests": 4, + "llm_output": "use spacetimedb::Table;\n\n#[spacetimedb::table(name = user, public)]\npub struct User {\n #[primary_key]\n user_id: i32,\n name: String,\n}\n\n#[spacetimedb::table(name = group, public)]\npub struct Group {\n #[primary_key]\n group_id: i32,\n title: String,\n}\n\n#[spacetimedb::table(\n name = membership,\n public,\n index(name = by_user, btree(columns = [user_id])),\n index(name = by_group, btree(columns = [group_id]))\n)]\npub struct Membership {\n #[primary_key]\n id: i32,\n user_id: i32,\n group_id: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &spacetimedb::ReducerContext) {\n ctx.db.user().insert(User { user_id: 1, name: \"Alice\".into() });\n ctx.db.user().insert(User { user_id: 2, name: \"Bob\".into() });\n\n ctx.db.group().insert(Group { group_id: 10, title: \"Admin\".into() });\n ctx.db.group().insert(Group { group_id: 20, title: \"Dev\".into() });\n\n ctx.db.membership().insert(Membership { id: 1, user_id: 1, group_id: 10 });\n ctx.db.membership().insert(Membership { id: 2, user_id: 1, group_id: 20 });\n ctx.db.membership().insert(Membership { id: 3, user_id: 2, group_id: 20 });\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-019-many-to-many-golden", + "llm_db": "schema-t-019-many-to-many-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "memberships_three_rows": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM membership" + } + }, + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-019-many-to-many-golden`.\n", + "phase": "describe_golden" + } + }, + "m2m_has_1_20": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20" + } + }, + "m2m_has_1_10": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=10" + } + }, + "m2m_has_2_20": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=2 AND group_id=20" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:32:55.980679692Z", - "finished_at": "2026-01-26T19:32:55.980679692Z" + "started_at": "2026-01-27T19:51:47.642788029Z", + "finished_at": "2026-01-27T19:52:31.910080797Z" }, "t_020_ecs": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_020_ecs", "lang": "rust", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, + "total_tests": 5, "passed_tests": 0, - "llm_output": null, + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = entity)]\npub struct Entity {\n #[primary_key]\n id: i32,\n}\n\n#[spacetimedb::table(name = position)]\npub struct Position {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::table(name = velocity)]\npub struct Velocity {\n #[primary_key]\n entity_id: i32,\n vx: i32,\n vy: i32,\n}\n\n#[spacetimedb::table(name = next_position)]\npub struct NextPosition {\n #[primary_key]\n entity_id: i32,\n x: i32,\n y: i32,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n // First entity: id=1, pos=(0,0), vel=(1,0)\n ctx.db.entity().id().delete(1);\n ctx.db.position().entity_id().delete(1);\n ctx.db.velocity().entity_id().delete(1);\n ctx.db.entity().insert(Entity { id: 1 });\n ctx.db.position().insert(Position { entity_id: 1, x: 0, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 1, vx: 1, vy: 0 });\n\n // Second entity: id=2, pos=(10,0), vel=(-2,3)\n ctx.db.entity().id().delete(2);\n ctx.db.position().entity_id().delete(2);\n ctx.db.velocity().entity_id().delete(2);\n ctx.db.entity().insert(Entity { id: 2 });\n ctx.db.position().insert(Position { entity_id: 2, x: 10, y: 0 });\n ctx.db.velocity().insert(Velocity { entity_id: 2, vx: -2, vy: 3 });\n}\n\n#[spacetimedb::reducer]\npub fn step(ctx: &ReducerContext) {\n for pos in ctx.db.position().iter() {\n if let Some(vel) = ctx.db.velocity().entity_id().find(pos.entity_id) {\n let nx = pos.x + vel.vx;\n let ny = pos.y + vel.vy;\n if let Some(_existing) = ctx.db.next_position().entity_id().find(pos.entity_id) {\n ctx.db\n .next_position()\n .entity_id()\n .update(NextPosition { entity_id: pos.entity_id, x: nx, y: ny });\n } else {\n ctx.db\n .next_position()\n .insert(NextPosition { entity_id: pos.entity_id, x: nx, y: ny });\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-020-ecs-golden", + "llm_db": "schema-t-020-ecs-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_020_ecs/rust/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_020_ecs/rust/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "schema_parity": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "describe failed: WARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: failed to find database `schema-t-020-ecs-golden`.\n", + "phase": "describe_golden" + } + }, + "ecs_step_next_positions_count": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", + "phase": "sql" + } + }, + "ecs_next_pos_entity1": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", + "phase": "sql" + } + }, + "ecs_seed_positions_count": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", + "phase": "sql" + } + }, + "ecs_next_pos_entity2": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:38927/v1/database/c2000dfb254023618a83b1182de85ff2f9590dae5ce1c9301d7d8cc01c8bff6e/sql)\n", + "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:32:55.980684633Z", - "finished_at": "2026-01-26T19:32:55.980684633Z" + "started_at": "2026-01-27T19:51:47.647113172Z", + "finished_at": "2026-01-27T19:52:42.328754582Z" }, "t_021_multi_column_index": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "task": "t_021_multi_column_index", "lang": "rust", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 3, - "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(\n name = log,\n index(name = by_user_day, btree(columns = [user_id, day]))\n)]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n let _ = ctx.db.log().try_insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".to_string() });\n let _ = ctx.db.log().try_insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".to_string() });\n let _ = ctx.db.log().try_insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".to_string() });\n}", + "llm_output": "use spacetimedb::{ReducerContext, Table};\n\n#[spacetimedb::table(name = log, index(name = by_user_day, btree(columns = [user_id, day])))]\npub struct Log {\n #[primary_key]\n id: i32,\n user_id: i32,\n day: i32,\n message: String,\n}\n\n#[spacetimedb::reducer]\npub fn seed(ctx: &ReducerContext) {\n ctx.db.log().insert(Log { id: 1, user_id: 7, day: 1, message: \"a\".into() });\n ctx.db.log().insert(Log { id: 2, user_id: 7, day: 2, message: \"b\".into() });\n ctx.db.log().insert(Log { id: 3, user_id: 9, day: 1, message: \"c\".into() });\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-021-multi-column-index-golden", @@ -2012,15 +2059,6 @@ "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/rust/server/golden", "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/rust/server/gpt-5/llm", "scorer_details": { - "mcindex_lookup_u7_d2": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2" - } - }, "schema_parity": { "pass": false, "partial": 0.0, @@ -2029,6 +2067,15 @@ "phase": "describe_golden" } }, + "mcindex_seed_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM log" + } + }, "mcindex_lookup_u7_d1": { "pass": true, "partial": 1.0, @@ -2038,19 +2085,19 @@ "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=1" } }, - "mcindex_seed_count": { + "mcindex_lookup_u7_d2": { "pass": true, "partial": 1.0, "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM log" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:29:24.579594233Z", - "finished_at": "2026-01-26T19:30:30.881922637Z" + "started_at": "2026-01-27T19:51:47.629929093Z", + "finished_at": "2026-01-27T19:52:29.436282461Z" } } } @@ -2241,14 +2288,14 @@ "modes": [ { "mode": "docs", - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "models": [ { "name": "GPT-5", "route_api_model": "gpt-5", "tasks": { "t_000_empty_reducers": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_000_empty_reducers", "lang": "csharp", "golden_published": true, @@ -2271,25 +2318,25 @@ "llm_db": "basics-t-000-empty-reducers-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:38:54.385915075Z", - "finished_at": "2026-01-26T19:40:03.912043999Z" + "started_at": "2026-01-27T19:59:45.341740044Z", + "finished_at": "2026-01-27T20:00:17.110354447Z" }, "t_001_basic_tables": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_001_basic_tables", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Product\", Public = true)]\n public partial struct Product\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Title;\n public float Price;\n public bool InStock;\n }\n\n [SpacetimeDB.Table(Name = \"Note\", Public = true)]\n public partial struct Note\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Body;\n public long Rating;\n public bool Pinned;\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Product\")]\n public partial struct Product\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Title;\n public float Price;\n public bool InStock;\n }\n\n [SpacetimeDB.Table(Name = \"Note\")]\n public partial struct Note\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Body;\n public long Rating;\n public bool Pinned;\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-001-basic-tables-golden", @@ -2305,25 +2352,25 @@ "llm_db": "basics-t-001-basic-tables-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:39:06.588178775Z", - "finished_at": "2026-01-26T19:40:26.686164444Z" + "started_at": "2026-01-27T20:00:10.594319009Z", + "finished_at": "2026-01-27T20:00:39.454473930Z" }, "t_002_scheduled_table": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_002_scheduled_table", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [PrimaryKey, AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n }\n\n [Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledId = 0,\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n}", + "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n foreach (var row in ctx.Db.TickTimer.Iter())\n {\n ctx.Db.TickTimer.ScheduledId.Delete(row.ScheduledId);\n }\n\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledId = 0,\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n // Tick scheduled reducer. Intentionally left blank.\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-002-scheduled-table-golden", @@ -2339,25 +2386,25 @@ "llm_db": "basics-t-002-scheduled-table-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:40:26.686215935Z", - "finished_at": "2026-01-26T19:41:35.359471807Z" + "started_at": "2026-01-27T20:00:39.454500245Z", + "finished_at": "2026-01-27T20:01:19.695962602Z" }, "t_003_struct_in_table": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_003_struct_in_table", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Entity\", Public = true)]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Position Pos;\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Entity\")]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Position Pos;\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-003-struct-in-table-golden", @@ -2373,18 +2420,18 @@ "llm_db": "basics-t-003-struct-in-table-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:39:03.248071954Z", - "finished_at": "2026-01-26T19:40:22.292027026Z" + "started_at": "2026-01-27T20:00:06.267861248Z", + "finished_at": "2026-01-27T20:00:37.823969244Z" }, "t_004_insert": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_004_insert", "lang": "csharp", "golden_published": true, @@ -2407,7 +2454,7 @@ "llm_db": "basics-t-004-insert-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } @@ -2428,23 +2475,23 @@ "llm_out": "Id | Name | Age | Active ----+---------+-----+-------- 1 | \"Alice\" | 30 | true", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "InsertUser", - "server": "http://127.0.0.1:44935" + "server": "http://127.0.0.1:34379" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:40:05.942682308Z", - "finished_at": "2026-01-26T19:41:00.825583459Z" + "started_at": "2026-01-27T20:00:17.336276015Z", + "finished_at": "2026-01-27T20:00:48.236577365Z" }, "t_005_update": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_005_update", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void UpdateUser(ReducerContext ctx, int id, string name, int age, bool active)\n {\n var user = ctx.Db.User.Id.Find(id) ?? throw new System.Exception(\"User not found\");\n user.Name = name;\n user.Age = age;\n user.Active = active;\n ctx.Db.User.Id.Update(user);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void UpdateUser(ReducerContext ctx, int id, string name, int age, bool active)\n {\n var user = ctx.Db.User.Id.Find(id) ?? throw new System.Exception(\"User not found\");\n user.Name = name;\n user.Age = age;\n user.Active = active;\n user.Id = id;\n ctx.Db.User.Id.Update(user);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-005-update-golden", @@ -2452,13 +2499,6 @@ "work_dir_golden": "target/llm-runs/basics/t_005_update/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_005_update/csharp/server/gpt-5/llm", "scorer_details": { - "seed_users_row": { - "pass": true, - "partial": 1.0, - "notes": { - "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" - } - }, "data_parity_update_user": { "pass": true, "partial": 1.0, @@ -2475,7 +2515,14 @@ "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "UpdateUser", - "server": "http://127.0.0.1:44935" + "server": "http://127.0.0.1:34379" + } + }, + "seed_users_row": { + "pass": true, + "partial": 1.0, + "notes": { + "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" } }, "schema_parity": { @@ -2486,18 +2533,18 @@ "llm_db": "basics-t-005-update-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:38:38.720018388Z", - "finished_at": "2026-01-26T19:40:05.937381701Z" + "started_at": "2026-01-27T19:59:43.681559749Z", + "finished_at": "2026-01-27T20:00:17.332627669Z" }, "t_006_delete": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_006_delete", "lang": "csharp", "golden_published": true, @@ -2512,19 +2559,6 @@ "work_dir_golden": "target/llm-runs/basics/t_006_delete/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_006_delete/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-006-delete-golden", - "llm_db": "basics-t-006-delete-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44935", - "tables_diff": null, - "tables_equal": true - } - }, "seed_users_row": { "pass": true, "partial": 1.0, @@ -2540,21 +2574,34 @@ "expected": 0, "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1" } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-006-delete-golden", + "llm_db": "basics-t-006-delete-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:34379", + "tables_diff": null, + "tables_equal": true + } } }, "vendor": "openai", - "started_at": "2026-01-26T19:37:37.167869929Z", - "finished_at": "2026-01-26T19:38:38.719937430Z" + "started_at": "2026-01-27T19:58:58.264033858Z", + "finished_at": "2026-01-27T19:59:39.007925686Z" }, "t_007_crud": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_007_crud", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void Crud(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n\n if (ctx.Db.User.Id.Find(1) is User user1)\n {\n user1.Name = \"Alice2\";\n user1.Age = 31;\n user1.Active = false;\n ctx.Db.User.Id.Update(user1);\n }\n\n ctx.Db.User.Id.Delete(2);\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Reducer]\n public static void Crud(ReducerContext ctx)\n {\n ctx.Db.User.Insert(new User { Id = 1, Name = \"Alice\", Age = 30, Active = true });\n ctx.Db.User.Insert(new User { Id = 2, Name = \"Bob\", Age = 22, Active = false });\n\n var found = ctx.Db.User.Id.Find(1);\n if (found is User user)\n {\n user.Name = \"Alice2\";\n user.Age = 31;\n user.Active = false;\n ctx.Db.User.Id.Update(user);\n }\n\n ctx.Db.User.Id.Delete(2);\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-007-crud-golden", @@ -2562,15 +2609,6 @@ "work_dir_golden": "target/llm-runs/basics/t_007_crud/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_007_crud/csharp/server/gpt-5/llm", "scorer_details": { - "crud_total_count_one": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM User" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2579,18 +2617,18 @@ "llm_db": "basics-t-007-crud-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } }, - "crud_row_id2_deleted": { + "crud_total_count_one": { "pass": true, "partial": 1.0, "notes": { - "actual": 0, - "expected": 0, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM User" } }, "crud_row_id2_deleted": { @@ -2613,23 +2651,23 @@ "llm_out": "Id | Name | Age | Active ----+----------+-----+-------- 1 | \"Alice2\" | 31 | false", "query": "SELECT Id, Name, Age, Active FROM User WHERE Id=1", "reducer": "Crud", - "server": "http://127.0.0.1:44935" + "server": "http://127.0.0.1:34379" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:37:59.027103288Z", - "finished_at": "2026-01-26T19:38:54.385590993Z" + "started_at": "2026-01-27T19:59:29.414134061Z", + "finished_at": "2026-01-27T20:00:06.267814536Z" }, "t_008_index_lookup": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_008_index_lookup", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void LookupUserName(ReducerContext ctx, int id)\n {\n if (ctx.Db.User.Id.Find(id) is User user)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = user.Id,\n Name = user.Name\n });\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial class User\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n public int Age;\n public bool Active;\n }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial class Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void LookupUserName(ReducerContext ctx, int id)\n {\n var user = ctx.Db.User.Id.Find(id);\n if (user != null)\n {\n ctx.Db.Result.Insert(new Result { Id = user.Id, Name = user.Name });\n }\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-008-index-lookup-golden", @@ -2637,6 +2675,22 @@ "work_dir_golden": "target/llm-runs/basics/t_008_index_lookup/csharp/server/golden", "work_dir_llm": "target/llm-runs/basics/t_008_index_lookup/csharp/server/gpt-5/llm", "scorer_details": { + "index_lookup_projection_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "args": [ + 1 + ], + "golden_db": "basics-t-008-index-lookup-golden", + "golden_out": "Id | Name ----+--------- 1 | \"Alice\"", + "llm_db": "basics-t-008-index-lookup-gpt-5-llm", + "llm_out": "Id | Name ----+--------- 1 | \"Alice\"", + "query": "SELECT Id, Name FROM Result WHERE Id=1", + "reducer": "LookupUserName", + "server": "http://127.0.0.1:34379" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2645,7 +2699,7 @@ "llm_db": "basics-t-008-index-lookup-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } @@ -2656,30 +2710,14 @@ "notes": { "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)" } - }, - "index_lookup_projection_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "args": [ - 1 - ], - "golden_db": "basics-t-008-index-lookup-golden", - "golden_out": "Id | Name ----+--------- 1 | \"Alice\"", - "llm_db": "basics-t-008-index-lookup-gpt-5-llm", - "llm_out": "Id | Name ----+--------- 1 | \"Alice\"", - "query": "SELECT Id, Name FROM Result WHERE Id=1", - "reducer": "LookupUserName", - "server": "http://127.0.0.1:44935" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:40:05.937447735Z", - "finished_at": "2026-01-26T19:41:10.697769188Z" + "started_at": "2026-01-27T20:00:17.332669093Z", + "finished_at": "2026-01-27T20:00:55.597420674Z" }, "t_009_init": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_009_init", "lang": "csharp", "golden_published": true, @@ -2702,27 +2740,27 @@ "llm_db": "basics-t-009-init-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } }, - "init_seed_alice": { + "init_seed_bob": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1 AND Name='Alice' AND Age=30 AND Active=true" + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2 AND Name='Bob' AND Age=22 AND Active=false" } }, - "init_seed_bob": { + "init_seed_alice": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=2 AND Name='Bob' AND Age=22 AND Active=false" + "sql": "SELECT COUNT(*) AS n FROM User WHERE Id=1 AND Name='Alice' AND Age=30 AND Active=true" } }, "init_total_two": { @@ -2736,18 +2774,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:38:16.753424300Z", - "finished_at": "2026-01-26T19:39:06.588120002Z" + "started_at": "2026-01-27T19:59:39.007990909Z", + "finished_at": "2026-01-27T20:00:10.594272918Z" }, "t_010_connect": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_010_connect", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 1, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Event\", Public = true)]\n public partial struct Event\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public int Id;\n public string Kind;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientConnected)]\n public static void ClientConnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"connected\" });\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)]\n public static void ClientDisconnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"disconnected\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Event\")]\n public partial struct Event\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public int Id;\n public string Kind;\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientConnected)]\n public static void ClientConnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"connected\" });\n }\n\n [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)]\n public static void ClientDisconnected(ReducerContext ctx)\n {\n ctx.Db.Event.Insert(new Event { Id = 0, Kind = \"disconnected\" });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-010-connect-golden", @@ -2763,25 +2801,25 @@ "llm_db": "basics-t-010-connect-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:37:47.380111761Z", - "finished_at": "2026-01-26T19:39:03.248030401Z" + "started_at": "2026-01-27T19:59:08.068058110Z", + "finished_at": "2026-01-27T19:59:45.341706421Z" }, "t_011_helper_function": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_011_helper_function", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int Sum;\n }\n\n private static int Add(int a, int b)\n {\n return a + b;\n }\n\n [SpacetimeDB.Reducer]\n public static void ComputeSum(ReducerContext ctx, int id, int a, int b)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Sum = Add(a, b)\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int Sum;\n }\n\n public static int Add(int a, int b)\n {\n return a + b;\n }\n\n [SpacetimeDB.Reducer]\n public static void ComputeSum(ReducerContext ctx, int id, int a, int b)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Sum = Add(a, b),\n });\n }\n}", "category": "basics", "route_api_model": "gpt-5", "golden_db": "basics-t-011-helper-function-golden", @@ -2798,19 +2836,6 @@ "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1 AND Sum=5" } }, - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "basics-t-011-helper-function-golden", - "llm_db": "basics-t-011-helper-function-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44935", - "tables_diff": null, - "tables_equal": true - } - }, "helper_func_sum_parity": { "pass": true, "partial": 1.0, @@ -2826,23 +2851,36 @@ "llm_out": "Id | Sum ----+----- 1 | 5", "query": "SELECT Id, Sum FROM Result WHERE Id=1", "reducer": "ComputeSum", - "server": "http://127.0.0.1:44935" + "server": "http://127.0.0.1:34379" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "basics-t-011-helper-function-golden", + "llm_db": "basics-t-011-helper-function-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:34379", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:40:22.292081947Z", - "finished_at": "2026-01-26T19:41:08.915943296Z" + "started_at": "2026-01-27T20:00:37.824007777Z", + "finished_at": "2026-01-27T20:01:12.698364118Z" }, "t_012_spacetime_product_type": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_012_spacetime_product_type", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Score\n {\n public int Left;\n public int Right;\n }\n\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Score Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetScore(ReducerContext ctx, int id, int left, int right)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = new Score\n {\n Left = left,\n Right = right\n }\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Score\n {\n public int Left;\n public int Right;\n }\n\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Score Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetScore(ReducerContext ctx, int id, int left, int right)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = new Score { Left = left, Right = right }\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-012-spacetime-product-type-golden", @@ -2865,16 +2903,7 @@ "llm_out": "Id | Value ----+----------------------- 1 | (Left = 2, Right = 3)", "query": "SELECT Id, Value FROM Result WHERE Id=1", "reducer": "SetScore", - "server": "http://127.0.0.1:44935" - } - }, - "product_type_row_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" + "server": "http://127.0.0.1:34379" } }, "schema_parity": { @@ -2885,25 +2914,34 @@ "llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } + }, + "product_type_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" + } } }, "vendor": "openai", - "started_at": "2026-01-26T19:37:30.236090594Z", - "finished_at": "2026-01-26T19:38:16.753346626Z" + "started_at": "2026-01-27T19:58:50.225754898Z", + "finished_at": "2026-01-27T19:59:29.413988946Z" }, "t_013_spacetime_sum_type": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_013_spacetime_sum_type", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Result\", Public = true)]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetCircle(ReducerContext ctx, int id, int radius)\n {\n var shape = new Shape.Circle(new Circle { Radius = radius });\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = shape\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Result\")]\n public partial struct Result\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape Value;\n }\n\n [SpacetimeDB.Reducer]\n public static void SetCircle(ReducerContext ctx, int id, int radius)\n {\n ctx.Db.Result.Insert(new Result\n {\n Id = id,\n Value = new Shape.Circle(new Circle { Radius = radius })\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-013-spacetime-sum-type-golden", @@ -2911,21 +2949,17 @@ "work_dir_golden": "target/llm-runs/schema/t_013_spacetime_sum_type/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_013_spacetime_sum_type/csharp/server/gpt-5/llm", "scorer_details": { - "sum_type_row_parity": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "args": [ - 1, - 10 - ], "golden_db": "schema-t-013-spacetime-sum-type-golden", - "golden_out": "Id | Value ----+-------------------------- 1 | (Circle = (Radius = 10))", "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", - "llm_out": "Id | Value ----+-------------------------- 1 | (Circle = (Radius = 10))", - "query": "SELECT Id, Value FROM Result WHERE Id=1", - "reducer": "SetCircle", - "server": "http://127.0.0.1:44935" + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:34379", + "tables_diff": null, + "tables_equal": true } }, "sum_type_row_count": { @@ -2937,26 +2971,30 @@ "sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1" } }, - "schema_parity": { + "sum_type_row_parity": { "pass": true, "partial": 1.0, "notes": { + "args": [ + 1, + 10 + ], "golden_db": "schema-t-013-spacetime-sum-type-golden", + "golden_out": "Id | Value ----+-------------------------- 1 | (Circle = (Radius = 10))", "llm_db": "schema-t-013-spacetime-sum-type-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44935", - "tables_diff": null, - "tables_equal": true + "llm_out": "Id | Value ----+-------------------------- 1 | (Circle = (Radius = 10))", + "query": "SELECT Id, Value FROM Result WHERE Id=1", + "reducer": "SetCircle", + "server": "http://127.0.0.1:34379" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:35:59.196578278Z", - "finished_at": "2026-01-26T19:37:03.535790946Z" + "started_at": "2026-01-27T19:57:55.737450825Z", + "finished_at": "2026-01-27T19:58:46.370198569Z" }, "t_014_elementary_columns": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_014_elementary_columns", "lang": "csharp", "golden_published": true, @@ -2971,14 +3009,6 @@ "work_dir_golden": "target/llm-runs/schema/t_014_elementary_columns/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_014_elementary_columns/csharp/server/gpt-5/llm", "scorer_details": { - "elementary_columns_row_parity": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2000e37e733499f47b57d9f488477b94fccf2e4c5c6c32182171721cbaba64a/sql)\n", - "phase": "sql_golden" - } - }, "schema_parity": { "pass": true, "partial": 1.0, @@ -2987,7 +3017,7 @@ "llm_db": "schema-t-014-elementary-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } @@ -2996,24 +3026,32 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c200e70d6c47b9f5b97a9584014efb7008b4c312687bfdbfe1b0ee1891420453/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c2006db3efe118f9e2be4d0996245799216709f62c09af27307321501d4ca96f/sql)\n", "phase": "sql" } + }, + "elementary_columns_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `primitive`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c2008bda321ec5b24f06db6690e57eaa2c1b3a9bada2318accf99feb7910837d/sql)\n", + "phase": "sql_golden" + } } }, "vendor": "openai", - "started_at": "2026-01-26T19:37:03.535862900Z", - "finished_at": "2026-01-26T19:37:59.026960569Z" + "started_at": "2026-01-27T19:58:46.370277696Z", + "finished_at": "2026-01-27T19:59:43.681502253Z" }, "t_015_product_type_columns": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_015_product_type_columns", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Address\n {\n public string Street;\n public int Zip;\n }\n\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Profile\", Public = true)]\n public partial struct Profile\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Address Home;\n public Address Work;\n public Position Pos;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Profile.Insert(new Profile\n {\n Id = 1,\n Home = new Address { Street = \"1 Main\", Zip = 11111 },\n Work = new Address { Street = \"2 Broad\", Zip = 22222 },\n Pos = new Position { X = 7, Y = 9 }\n });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Address\n {\n public string Street;\n public int Zip;\n }\n\n [SpacetimeDB.Type]\n public partial struct Position\n {\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Profile\", Public = true)]\n public partial struct Profile\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Address Home;\n public Address Work;\n public Position Pos;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n if (ctx.Db.Profile.Id.Find(1) == null)\n {\n ctx.Db.Profile.Insert(new Profile\n {\n Id = 1,\n Home = new Address { Street = \"1 Main\", Zip = 11111 },\n Work = new Address { Street = \"2 Broad\", Zip = 22222 },\n Pos = new Position { X = 7, Y = 9 },\n });\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-015-product-type-columns-golden", @@ -3029,20 +3067,11 @@ "llm_db": "schema-t-015-product-type-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } }, - "product_type_columns_row_count": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Profile WHERE Id=1" - } - }, "product_type_columns_row_parity": { "pass": true, "partial": 1.0, @@ -3054,52 +3083,82 @@ "llm_out": "Id | Home | Work | Pos ----+----------------------------------+-----------------------------------+---------------- 1 | (Street = \"1 Main\", Zip = 11111) | (Street = \"2 Broad\", Zip = 22222) | (X = 7, Y = 9)", "query": "SELECT Id, Home, Work, Pos FROM Profile WHERE Id=1", "reducer": "Seed", - "server": "http://127.0.0.1:44935" + "server": "http://127.0.0.1:34379" + } + }, + "product_type_columns_row_count": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Profile WHERE Id=1" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:36:38.953458698Z", - "finished_at": "2026-01-26T19:37:30.236009816Z" + "started_at": "2026-01-27T19:58:04.285909374Z", + "finished_at": "2026-01-27T19:58:50.225511855Z" }, "t_016_sum_type_columns": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_016_sum_type_columns", "lang": "csharp", - "golden_published": false, + "golden_published": true, "model_name": "GPT-5", - "total_tests": 1, - "passed_tests": 0, - "llm_output": null, + "total_tests": 3, + "passed_tests": 1, + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Type]\n public partial struct Circle\n {\n public int Radius;\n }\n\n [SpacetimeDB.Type]\n public partial struct Rectangle\n {\n public int Width;\n public int Height;\n }\n\n [SpacetimeDB.Type]\n public partial record Shape : TaggedEnum<(Circle Circle, Rectangle Rectangle)> { }\n\n [SpacetimeDB.Table(Name = \"Drawing\")]\n public partial struct Drawing\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public Shape A;\n public Shape B;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Drawing.Insert(new Drawing\n {\n Id = 1,\n A = new Shape.Circle(new Circle { Radius = 10 }),\n B = new Shape.Rectangle(new Rectangle { Width = 4, Height = 6 })\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", - "golden_db": null, - "llm_db": null, - "work_dir_golden": null, - "work_dir_llm": null, + "golden_db": "schema-t-016-sum-type-columns-golden", + "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", + "work_dir_golden": "target/llm-runs/schema/t_016_sum_type_columns/csharp/server/golden", + "work_dir_llm": "target/llm-runs/schema/t_016_sum_type_columns/csharp/server/gpt-5/llm", "scorer_details": { - "publish_error": { + "sum_type_columns_row_count": { "pass": false, "partial": 0.0, "notes": { - "error": "LLM call timed out", - "phase": "build_or_publish" + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c200a38bd5eaec739ca1bb5f49423cf455fb484e997f330a37dbe10a2f09faac/sql)\n", + "phase": "sql" + } + }, + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-016-sum-type-columns-golden", + "llm_db": "schema-t-016-sum-type-columns-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:34379", + "tables_diff": null, + "tables_equal": true + } + }, + "sum_type_columns_row_parity": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `drawings`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20028da21a53491f84d8895dbcf4906c6c844846426c39ae32b5fd1689a2641/sql)\n", + "phase": "sql_golden" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:41:35.359543125Z", - "finished_at": "2026-01-26T19:41:35.359543125Z" + "started_at": "2026-01-27T19:57:09.422528630Z", + "finished_at": "2026-01-27T19:58:04.281919840Z" }, "t_017_scheduled_columns": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_017_scheduled_columns", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 2, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMicroseconds(50_000))\n });\n }\n}", + "llm_output": "using System;\nusing SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"TickTimer\", Scheduled = nameof(Tick), ScheduledAt = nameof(ScheduledAt))]\n public partial struct TickTimer\n {\n [SpacetimeDB.PrimaryKey]\n [SpacetimeDB.AutoInc]\n public ulong ScheduledId;\n public ScheduleAt ScheduledAt;\n }\n\n [SpacetimeDB.Reducer]\n public static void Tick(ReducerContext ctx, TickTimer _timer)\n {\n }\n\n [SpacetimeDB.Reducer(ReducerKind.Init)]\n public static void Init(ReducerContext ctx)\n {\n ctx.Db.TickTimer.Insert(new TickTimer\n {\n ScheduledAt = new ScheduleAt.Interval(TimeSpan.FromMilliseconds(50))\n });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-017-scheduled-columns-golden", @@ -3107,6 +3166,14 @@ "work_dir_golden": "target/llm-runs/schema/t_017_scheduled_columns/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_017_scheduled_columns/csharp/server/gpt-5/llm", "scorer_details": { + "scheduled_seeded_one_row": { + "pass": false, + "partial": 0.0, + "notes": { + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `tick_timer`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c200bf2221f01a62dfa1acb5a397b4271a57cfc2f171562204bb3bcee2259214/sql)\n", + "phase": "sql" + } + }, "schema_parity": { "pass": true, "partial": 1.0, @@ -3115,33 +3182,25 @@ "llm_db": "schema-t-017-scheduled-columns-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } - }, - "scheduled_seeded_one_row": { - "pass": false, - "partial": 0.0, - "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `tick_timer`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2004563b2a3af718eb5a6d78c0e16523a6ad57949ac9dd820dbc2c2e11c8842/sql)\n", - "phase": "sql" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:35:08.495907944Z", - "finished_at": "2026-01-26T19:36:38.949408263Z" + "started_at": "2026-01-27T19:57:09.413847953Z", + "finished_at": "2026-01-27T19:57:55.737395054Z" }, "t_018_constraints": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_018_constraints", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 3, "passed_tests": 3, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Account\", Public = true)]\n [SpacetimeDB.Index.BTree(Name = \"by_name\", Columns = new[] { \"Name\" })]\n public partial struct Account\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n [SpacetimeDB.Unique]\n public string Email;\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Account.Insert(new Account { Id = 1, Email = \"a@example.com\", Name = \"Alice\" });\n ctx.Db.Account.Insert(new Account { Id = 2, Email = \"b@example.com\", Name = \"Bob\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Account\", Public = true)]\n public partial struct Account\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n\n [SpacetimeDB.Unique]\n public string Email;\n\n [SpacetimeDB.Index.BTree(Name = \"by_name\")]\n public string Name;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Account.Insert(new Account { Id = 1, Email = \"a@example.com\", Name = \"Alice\" });\n ctx.Db.Account.Insert(new Account { Id = 2, Email = \"b@example.com\", Name = \"Bob\" });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-018-constraints-golden", @@ -3149,6 +3208,20 @@ "work_dir_golden": "target/llm-runs/schema/t_018_constraints/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_018_constraints/csharp/server/gpt-5/llm", "scorer_details": { + "constraints_row_parity_after_seed": { + "pass": true, + "partial": 1.0, + "notes": { + "args": [], + "golden_db": "schema-t-018-constraints-golden", + "golden_out": "Id | Email | Name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", + "llm_db": "schema-t-018-constraints-gpt-5-llm", + "llm_out": "Id | Email | Name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", + "query": "SELECT Id, Email, Name FROM Account WHERE Id=1", + "reducer": "Seed", + "server": "http://127.0.0.1:34379" + } + }, "constraints_seed_two_rows": { "pass": true, "partial": 1.0, @@ -3166,39 +3239,25 @@ "llm_db": "schema-t-018-constraints-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } - }, - "constraints_row_parity_after_seed": { - "pass": true, - "partial": 1.0, - "notes": { - "args": [], - "golden_db": "schema-t-018-constraints-golden", - "golden_out": "Id | Email | Name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", - "llm_db": "schema-t-018-constraints-gpt-5-llm", - "llm_out": "Id | Email | Name ----+-----------------+--------- 1 | \"a@example.com\" | \"Alice\"", - "query": "SELECT Id, Email, Name FROM Account WHERE Id=1", - "reducer": "Seed", - "server": "http://127.0.0.1:44935" - } } }, "vendor": "openai", - "started_at": "2026-01-26T19:35:08.491947971Z", - "finished_at": "2026-01-26T19:35:59.196533076Z" + "started_at": "2026-01-27T19:57:09.410769526Z", + "finished_at": "2026-01-27T19:58:03.584746288Z" }, "t_019_many_to_many": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_019_many_to_many", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 5, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\", Public = true)]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int UserId;\n public string Name;\n }\n\n [SpacetimeDB.Table(Name = \"Group\", Public = true)]\n public partial struct Group\n {\n [SpacetimeDB.PrimaryKey]\n public int GroupId;\n public string Title;\n }\n\n [SpacetimeDB.Table(Name = \"Membership\", Public = true)]\n [SpacetimeDB.Index.BTree(Name = \"by_user\", Columns = new[] { \"UserId\" })]\n [SpacetimeDB.Index.BTree(Name = \"by_group\", Columns = new[] { \"GroupId\" })]\n public partial struct Membership\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int GroupId;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n // Ensure exactly these rows by clearing existing data first\n foreach (var m in ctx.Db.Membership.Iter())\n {\n ctx.Db.Membership.Id.Delete(m.Id);\n }\n foreach (var u in ctx.Db.User.Iter())\n {\n ctx.Db.User.UserId.Delete(u.UserId);\n }\n foreach (var g in ctx.Db.Group.Iter())\n {\n ctx.Db.Group.GroupId.Delete(g.GroupId);\n }\n\n // Users\n ctx.Db.User.Insert(new User { UserId = 1, Name = \"Alice\" });\n ctx.Db.User.Insert(new User { UserId = 2, Name = \"Bob\" });\n\n // Groups\n ctx.Db.Group.Insert(new Group { GroupId = 10, Title = \"Admin\" });\n ctx.Db.Group.Insert(new Group { GroupId = 20, Title = \"Dev\" });\n\n // Memberships\n ctx.Db.Membership.Insert(new Membership { Id = 1, UserId = 1, GroupId = 10 });\n ctx.Db.Membership.Insert(new Membership { Id = 2, UserId = 1, GroupId = 20 });\n ctx.Db.Membership.Insert(new Membership { Id = 3, UserId = 2, GroupId = 20 });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"User\")]\n public partial struct User\n {\n [SpacetimeDB.PrimaryKey]\n public int UserId;\n public string Name;\n }\n\n [SpacetimeDB.Table(Name = \"Group\")]\n public partial struct Group\n {\n [SpacetimeDB.PrimaryKey]\n public int GroupId;\n public string Title;\n }\n\n [SpacetimeDB.Table(Name = \"Membership\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user\", Columns = new[] { \"UserId\" })]\n [SpacetimeDB.Index.BTree(Name = \"by_group\", Columns = new[] { \"GroupId\" })]\n public partial struct Membership\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int GroupId;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n foreach (var m in ctx.Db.Membership.Iter())\n {\n ctx.Db.Membership.Id.Delete(m.Id);\n }\n\n foreach (var g in ctx.Db.Group.Iter())\n {\n ctx.Db.Group.GroupId.Delete(g.GroupId);\n }\n\n foreach (var u in ctx.Db.User.Iter())\n {\n ctx.Db.User.UserId.Delete(u.UserId);\n }\n\n ctx.Db.User.Insert(new User { UserId = 1, Name = \"Alice\" });\n ctx.Db.User.Insert(new User { UserId = 2, Name = \"Bob\" });\n\n ctx.Db.Group.Insert(new Group { GroupId = 10, Title = \"Admin\" });\n ctx.Db.Group.Insert(new Group { GroupId = 20, Title = \"Dev\" });\n\n ctx.Db.Membership.Insert(new Membership { Id = 1, UserId = 1, GroupId = 10 });\n ctx.Db.Membership.Insert(new Membership { Id = 2, UserId = 1, GroupId = 20 });\n ctx.Db.Membership.Insert(new Membership { Id = 3, UserId = 2, GroupId = 20 });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-019-many-to-many-golden", @@ -3206,6 +3265,15 @@ "work_dir_golden": "target/llm-runs/schema/t_019_many_to_many/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_019_many_to_many/csharp/server/gpt-5/llm", "scorer_details": { + "m2m_has_2_20": { + "pass": true, + "partial": 1.0, + "notes": { + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=2 AND GroupId=20" + } + }, "memberships_three_rows": { "pass": true, "partial": 1.0, @@ -3223,27 +3291,18 @@ "llm_db": "schema-t-019-many-to-many-gpt-5-llm", "reducers_diff": null, "reducers_equal": true, - "server": "http://127.0.0.1:44935", + "server": "http://127.0.0.1:34379", "tables_diff": null, "tables_equal": true } }, - "m2m_has_2_20": { - "pass": true, - "partial": 1.0, - "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=2 AND GroupId=20" - } - }, "m2m_has_1_20": { "pass": true, "partial": 1.0, "notes": { "actual": 1, "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=2 AND GroupId=20" + "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=1 AND GroupId=20" } }, "m2m_has_1_10": { @@ -3257,18 +3316,18 @@ } }, "vendor": "openai", - "started_at": "2026-01-26T19:36:32.689581659Z", - "finished_at": "2026-01-26T19:37:37.167783708Z" + "started_at": "2026-01-27T19:58:04.046511986Z", + "finished_at": "2026-01-27T19:58:58.263921552Z" }, "t_020_ecs": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_020_ecs", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 5, "passed_tests": 1, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Entity\", Public = true)]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n }\n\n [SpacetimeDB.Table(Name = \"Position\", Public = true)]\n public partial struct Position\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Velocity\", Public = true)]\n public partial struct Velocity\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int VX;\n public int VY;\n }\n\n [SpacetimeDB.Table(Name = \"NextPosition\", Public = true)]\n public partial struct NextPosition\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Entity.Insert(new Entity { Id = 1 });\n ctx.Db.Position.Insert(new Position { EntityId = 1, X = 0, Y = 0 });\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 1, VX = 1, VY = 0 });\n\n ctx.Db.Entity.Insert(new Entity { Id = 2 });\n ctx.Db.Position.Insert(new Position { EntityId = 2, X = 10, Y = 0 });\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 2, VX = -2, VY = 3 });\n }\n\n [SpacetimeDB.Reducer]\n public static void Step(ReducerContext ctx)\n {\n foreach (var pos in ctx.Db.Position.Iter())\n {\n if (ctx.Db.Velocity.EntityId.Find(pos.EntityId) is Velocity vel)\n {\n int nx = pos.X + vel.VX;\n int ny = pos.Y + vel.VY;\n\n if (ctx.Db.NextPosition.EntityId.Find(pos.EntityId) is NextPosition np)\n {\n np.X = nx;\n np.Y = ny;\n ctx.Db.NextPosition.EntityId.Update(np);\n }\n else\n {\n ctx.Db.NextPosition.Insert(new NextPosition { EntityId = pos.EntityId, X = nx, Y = ny });\n }\n }\n }\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Entity\")]\n public partial struct Entity\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n }\n\n [SpacetimeDB.Table(Name = \"Position\")]\n public partial struct Position\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Table(Name = \"Velocity\")]\n public partial struct Velocity\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int VX;\n public int VY;\n }\n\n [SpacetimeDB.Table(Name = \"NextPosition\")]\n public partial struct NextPosition\n {\n [SpacetimeDB.PrimaryKey]\n public int EntityId;\n public int X;\n public int Y;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n // Entities\n ctx.Db.Entity.Insert(new Entity { Id = 1 });\n ctx.Db.Entity.Insert(new Entity { Id = 2 });\n\n // Positions\n ctx.Db.Position.Insert(new Position { EntityId = 1, X = 0, Y = 0 });\n ctx.Db.Position.Insert(new Position { EntityId = 2, X = 10, Y = 0 });\n\n // Velocities\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 1, VX = 1, VY = 0 });\n ctx.Db.Velocity.Insert(new Velocity { EntityId = 2, VX = -2, VY = 3 });\n }\n\n [SpacetimeDB.Reducer]\n public static void Step(ReducerContext ctx)\n {\n foreach (var pos in ctx.Db.Position.Iter())\n {\n var vel = ctx.Db.Velocity.EntityId.Find(pos.EntityId);\n int vx = 0, vy = 0;\n if (vel != null)\n {\n vx = vel.Value.VX;\n vy = vel.Value.VY;\n }\n\n var next = new NextPosition\n {\n EntityId = pos.EntityId,\n X = pos.X + vx,\n Y = pos.Y + vy\n };\n\n var existing = ctx.Db.NextPosition.EntityId.Find(pos.EntityId);\n if (existing != null)\n {\n ctx.Db.NextPosition.EntityId.Update(next);\n }\n else\n {\n ctx.Db.NextPosition.Insert(next);\n }\n }\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-020-ecs-golden", @@ -3276,32 +3335,19 @@ "work_dir_golden": "target/llm-runs/schema/t_020_ecs/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_020_ecs/csharp/server/gpt-5/llm", "scorer_details": { - "schema_parity": { - "pass": true, - "partial": 1.0, - "notes": { - "golden_db": "schema-t-020-ecs-golden", - "llm_db": "schema-t-020-ecs-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44935", - "tables_diff": null, - "tables_equal": true - } - }, - "ecs_seed_positions_count": { + "ecs_step_next_positions_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", "phase": "sql" } }, - "ecs_step_next_positions_count": { + "ecs_next_pos_entity1": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", "phase": "sql" } }, @@ -3309,32 +3355,45 @@ "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", "phase": "sql" } }, - "ecs_next_pos_entity1": { + "schema_parity": { + "pass": true, + "partial": 1.0, + "notes": { + "golden_db": "schema-t-020-ecs-golden", + "llm_db": "schema-t-020-ecs-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:34379", + "tables_diff": null, + "tables_equal": true + } + }, + "ecs_seed_positions_count": { "pass": false, "partial": 0.0, "notes": { - "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `next_positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n", + "error": "spacetime sql failed:\nWARNING: This command is UNSTABLE and subject to breaking changes.\n\nError: no such table: `positions`. If the table exists, it may be marked private.\n\nCaused by:\n HTTP status client error (400 Bad Request) for url (http://127.0.0.1:34379/v1/database/c20015874a697116ed39e7f80d0fb9c484518ec19d2cf28ab6bbc9a525d697e0/sql)\n", "phase": "sql" } } }, "vendor": "openai", - "started_at": "2026-01-26T19:36:38.949546269Z", - "finished_at": "2026-01-26T19:37:47.379943704Z" + "started_at": "2026-01-27T19:58:04.281975972Z", + "finished_at": "2026-01-27T19:59:08.067949434Z" }, "t_021_multi_column_index": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "task": "t_021_multi_column_index", "lang": "csharp", "golden_published": true, "model_name": "GPT-5", "total_tests": 4, "passed_tests": 4, - "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Log\", Public = true)]\n [SpacetimeDB.Index.BTree(Name = \"by_user_day\", Columns = new[] { \"UserId\", \"Day\" })]\n public partial struct Log\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int Day;\n public string Message;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Log.Insert(new Log { Id = 1, UserId = 7, Day = 1, Message = \"a\" });\n ctx.Db.Log.Insert(new Log { Id = 2, UserId = 7, Day = 2, Message = \"b\" });\n ctx.Db.Log.Insert(new Log { Id = 3, UserId = 9, Day = 1, Message = \"c\" });\n }\n}", + "llm_output": "using SpacetimeDB;\n\npublic static partial class Module\n{\n [SpacetimeDB.Table(Name = \"Log\")]\n [SpacetimeDB.Index.BTree(Name = \"by_user_day\", Columns = new[] { \"UserId\", \"Day\" })]\n public partial struct Log\n {\n [SpacetimeDB.PrimaryKey]\n public int Id;\n public int UserId;\n public int Day;\n public string Message;\n }\n\n [SpacetimeDB.Reducer]\n public static void Seed(ReducerContext ctx)\n {\n ctx.Db.Log.Insert(new Log { Id = 1, UserId = 7, Day = 1, Message = \"a\" });\n ctx.Db.Log.Insert(new Log { Id = 2, UserId = 7, Day = 2, Message = \"b\" });\n ctx.Db.Log.Insert(new Log { Id = 3, UserId = 9, Day = 1, Message = \"c\" });\n }\n}", "category": "schema", "route_api_model": "gpt-5", "golden_db": "schema-t-021-multi-column-index-golden", @@ -3342,26 +3401,22 @@ "work_dir_golden": "target/llm-runs/schema/t_021_multi_column_index/csharp/server/golden", "work_dir_llm": "target/llm-runs/schema/t_021_multi_column_index/csharp/server/gpt-5/llm", "scorer_details": { - "mcindex_seed_count": { + "mcindex_lookup_u7_d2": { "pass": true, "partial": 1.0, "notes": { - "actual": 3, - "expected": 3, - "sql": "SELECT COUNT(*) AS n FROM Log" + "actual": 1, + "expected": 1, + "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2" } }, - "schema_parity": { + "mcindex_seed_count": { "pass": true, "partial": 1.0, "notes": { - "golden_db": "schema-t-021-multi-column-index-golden", - "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", - "reducers_diff": null, - "reducers_equal": true, - "server": "http://127.0.0.1:44935", - "tables_diff": null, - "tables_equal": true + "actual": 3, + "expected": 3, + "sql": "SELECT COUNT(*) AS n FROM Log" } }, "mcindex_lookup_u7_d1": { @@ -3373,19 +3428,23 @@ "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=1" } }, - "mcindex_lookup_u7_d2": { + "schema_parity": { "pass": true, "partial": 1.0, "notes": { - "actual": 1, - "expected": 1, - "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2" + "golden_db": "schema-t-021-multi-column-index-golden", + "llm_db": "schema-t-021-multi-column-index-gpt-5-llm", + "reducers_diff": null, + "reducers_equal": true, + "server": "http://127.0.0.1:34379", + "tables_diff": null, + "tables_equal": true } } }, "vendor": "openai", - "started_at": "2026-01-26T19:35:08.500770472Z", - "finished_at": "2026-01-26T19:36:32.689520614Z" + "started_at": "2026-01-27T19:57:09.418092225Z", + "finished_at": "2026-01-27T19:58:04.046455117Z" } } } diff --git a/docs/llms/docs-benchmark-summary.json b/docs/llms/docs-benchmark-summary.json index fa057f8e85f..bf684185512 100644 --- a/docs/llms/docs-benchmark-summary.json +++ b/docs/llms/docs-benchmark-summary.json @@ -1,11 +1,11 @@ { "version": 1, - "generated_at": "2026-01-26T19:41:35.586Z", + "generated_at": "2026-01-27T20:01:19.767Z", "by_language": { "csharp": { "modes": { "docs": { - "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0", + "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b", "models": { "GPT-5": { "categories": { @@ -19,20 +19,20 @@ }, "schema": { "tasks": 10, - "total_tests": 32, - "passed_tests": 24, - "pass_pct": 75.0, - "task_pass_equiv": 7.033333, - "task_pass_pct": 70.33333 + "total_tests": 34, + "passed_tests": 25, + "pass_pct": 73.52941, + "task_pass_equiv": 7.3666663, + "task_pass_pct": 73.666664 } }, "totals": { "tasks": 22, - "total_tests": 59, - "passed_tests": 51, - "pass_pct": 86.44068, - "task_pass_equiv": 19.033333, - "task_pass_pct": 86.515144 + "total_tests": 61, + "passed_tests": 52, + "pass_pct": 85.2459, + "task_pass_equiv": 19.366667, + "task_pass_pct": 88.030304 } } } @@ -42,7 +42,7 @@ "rust": { "modes": { "docs": { - "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117", + "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9", "models": { "GPT-5": { "categories": { @@ -56,44 +56,44 @@ }, "schema": { "tasks": 10, - "total_tests": 18, - "passed_tests": 4, - "pass_pct": 22.222221, - "task_pass_equiv": 1.25, - "task_pass_pct": 12.5 + "total_tests": 32, + "passed_tests": 8, + "pass_pct": 25.0, + "task_pass_equiv": 2.05, + "task_pass_pct": 20.5 } }, "totals": { "tasks": 22, - "total_tests": 45, - "passed_tests": 9, - "pass_pct": 20.0, - "task_pass_equiv": 2.5833335, - "task_pass_pct": 11.742425 + "total_tests": 59, + "passed_tests": 13, + "pass_pct": 22.033897, + "task_pass_equiv": 3.3833334, + "task_pass_pct": 15.378788 } } } }, "rustdoc_json": { - "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a", + "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a", "models": { "GPT-5": { "categories": { "basics": { "tasks": 12, "total_tests": 27, - "passed_tests": 25, - "pass_pct": 92.59259, - "task_pass_equiv": 10.0, - "task_pass_pct": 83.33333 + "passed_tests": 26, + "pass_pct": 96.296295, + "task_pass_equiv": 11.0, + "task_pass_pct": 91.66667 }, "schema": { "tasks": 10, "total_tests": 34, - "passed_tests": 24, - "pass_pct": 70.588234, - "task_pass_equiv": 6.8666663, - "task_pass_pct": 68.666664 + "passed_tests": 23, + "pass_pct": 67.64706, + "task_pass_equiv": 6.5333333, + "task_pass_pct": 65.33333 } }, "totals": { @@ -101,8 +101,8 @@ "total_tests": 61, "passed_tests": 49, "pass_pct": 80.327866, - "task_pass_equiv": 16.866667, - "task_pass_pct": 76.666664 + "task_pass_equiv": 17.533335, + "task_pass_pct": 79.696976 } } } diff --git a/docs/static/llms.md b/docs/static/llms.md index c7144f9f20f..a4fa11306fd 100644 --- a/docs/static/llms.md +++ b/docs/static/llms.md @@ -1449,7 +1449,7 @@ Reducers are the functions within your server module responsible for atomically - **Return Type:** Reducers should typically return `void`. Errors are signaled by throwing exceptions. - **Reducer Context:** The `ReducerContext` (`ctx`) provides access to: - `ctx.Db`: Handles for interacting with database tables. - - `ctx.Sender()`: The `Identity` of the caller. + - `ctx.Sender`: The `Identity` of the caller. - `ctx.Identity`: The `Identity` of the module itself. - `ctx.Timestamp`: The `Timestamp` of the invocation. - `ctx.ConnectionId`: The nullable `ConnectionId` of the caller. @@ -1478,7 +1478,7 @@ public static partial class Module [Reducer] public static void UpdatePlayerData(ReducerContext ctx, string? newName) { - var playerId = ctx.Sender(); + var playerId = ctx.Sender; // Find player by primary key var player = ctx.Db.player_state.PlayerId.Find(playerId); @@ -1521,10 +1521,10 @@ public static partial class Module if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name cannot be empty."); } - Log.Info($"Attempting to register player: {name} ({ctx.Sender()})"); + Log.Info($"Attempting to register player: {name} ({ctx.Sender})"); // Check if player identity or name already exists - if (ctx.Db.player_state.PlayerId.Find(ctx.Sender()) != null || ctx.Db.player_state.Name.Find(name) != null) + if (ctx.Db.player_state.PlayerId.Find(ctx.Sender) != null || ctx.Db.player_state.Name.Find(name) != null) { throw new Exception("Player already registered or name taken."); } @@ -1532,7 +1532,7 @@ public static partial class Module // Create new player instance var newPlayer = new PlayerState { - PlayerId = ctx.Sender(), + PlayerId = ctx.Sender, Name = name, Health = 100, Level = 1, @@ -1541,14 +1541,14 @@ public static partial class Module // Insert the new player. This will throw on constraint violation. ctx.Db.player_state.Insert(newPlayer); - Log.Info($"Player registered successfully: {ctx.Sender()}"); + Log.Info($"Player registered successfully: {ctx.Sender}"); } // Example: Basic reducer showing deletion [Reducer] public static void DeleteMyItems(ReducerContext ctx) { - var ownerId = ctx.Sender(); + var ownerId = ctx.Sender; int deletedCount = 0; // Find items by owner (Requires an index on OwnerId for efficiency) @@ -1632,13 +1632,13 @@ These reducers cannot take arguments beyond `&ReducerContext`. // Example init reducer is shown in Scheduled Reducers section [Reducer(ReducerKind.ClientConnected)] public static void HandleConnect(ReducerContext ctx) { - Log.Info($"Client connected: {ctx.Sender()}"); + Log.Info($"Client connected: {ctx.Sender}"); // ... setup initial state for ctx.sender ... } [Reducer(ReducerKind.ClientDisconnected)] public static void HandleDisconnect(ReducerContext ctx) { - Log.Info($"Client disconnected: {ctx.Sender()}"); + Log.Info($"Client disconnected: {ctx.Sender}"); // ... cleanup state for ctx.sender ... } ``` @@ -1692,7 +1692,7 @@ public static partial class Module public static void SendMessage(ReducerContext ctx, SendMessageSchedule scheduleArgs) { // Security check is important! - if (!ctx.Sender().Equals(ctx.Identity)) + if (!ctx.Sender.Equals(ctx.Identity)) { throw new Exception("Reducer SendMessage may not be invoked by clients, only via scheduling."); } @@ -1740,12 +1740,12 @@ public static partial class Module - **Best-Effort Scheduling:** Scheduled reducers are called on a best-effort basis and may be slightly delayed in their execution when a database is under heavy load. -- **Restricting Access (Security):** Scheduled reducers are normal reducers and _can_ still be called directly by clients. If a scheduled reducer should _only_ be called by the scheduler, it is crucial to begin the reducer with a check comparing the caller's identity (`ctx.Sender()`) to the module's own identity (`ctx.Identity`). +- **Restricting Access (Security):** Scheduled reducers are normal reducers and _can_ still be called directly by clients. If a scheduled reducer should _only_ be called by the scheduler, it is crucial to begin the reducer with a check comparing the caller's identity (`ctx.Sender`) to the module's own identity (`ctx.Identity`). ```csharp [Reducer] // Assuming linked via [Table(Scheduled=...)] public static void MyScheduledTask(ReducerContext ctx, MyScheduleArgs args) { - if (!ctx.Sender().Equals(ctx.Identity)) + if (!ctx.Sender.Equals(ctx.Identity)) { throw new Exception("Reducer MyScheduledTask may not be invoked by clients, only via scheduling."); } @@ -1757,7 +1757,7 @@ public static partial class Module ``` :::info Scheduled Reducers and Connections -Scheduled reducer calls originate from the SpacetimeDB scheduler itself, not from an external client connection. Therefore, within a scheduled reducer, `ctx.Sender()` will be the module's own identity, and `ctx.ConnectionId` will be `null`. +Scheduled reducer calls originate from the SpacetimeDB scheduler itself, not from an external client connection. Therefore, within a scheduled reducer, `ctx.Sender` will be the module's own identity, and `ctx.ConnectionId` will be `null`. ::: ##### Error Handling: Exceptions @@ -1827,7 +1827,7 @@ public static partial class Module [SpacetimeDB.View(Name = "MyPlayer", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.Player.Identity.Find(ctx.Sender()); + return ctx.Db.Player.Identity.Find(ctx.Sender); } // View that returns all players at a specific level (same for all callers) @@ -1858,7 +1858,7 @@ public static partial class Module Views use one of two context types: -- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.Sender()`. Use this when the view depends on who is querying it (e.g., "get my player"). +- **`ViewContext`**: Provides access to the caller's `Identity` through `ctx.Sender`. Use this when the view depends on who is querying it (e.g., "get my player"). - **`AnonymousViewContext`**: Does not provide caller information. Use this when the view produces the same results regardless of who queries it (e.g., "get top 10 players"). Both contexts provide read-only access to tables and indexes through `ctx.Db`. @@ -1887,7 +1887,7 @@ The query builder provides a fluent API for constructing type-safe SQL queries: public static Query MyMessages(ViewContext ctx) { return ctx.Db.Message - .Filter(msg => msg.Sender == ctx.Sender()) + .Filter(msg => msg.Sender == ctx.Sender) .Build(); } diff --git a/sdks/csharp/examples~/regression-tests/server/Lib.cs b/sdks/csharp/examples~/regression-tests/server/Lib.cs index 7a41a8312ac..a0d5600d39b 100644 --- a/sdks/csharp/examples~/regression-tests/server/Lib.cs +++ b/sdks/csharp/examples~/regression-tests/server/Lib.cs @@ -173,13 +173,13 @@ public partial struct NullStringNullable [SpacetimeDB.View(Name = "my_player", Public = true)] public static Player? MyPlayer(ViewContext ctx) { - return ctx.Db.player.Identity.Find(ctx.Sender()); + return ctx.Db.player.Identity.Find(ctx.Sender); } [SpacetimeDB.View(Name = "my_account", Public = true)] public static Account? MyAccount(ViewContext ctx) { - return ctx.Db.account.Identity.Find(ctx.Sender()) as Account; + return ctx.Db.account.Identity.Find(ctx.Sender) as Account; } [SpacetimeDB.View(Name = "my_account_missing", Public = true)] @@ -391,23 +391,23 @@ public static void InsertWhereTest(ReducerContext ctx, uint id, uint value, stri [Reducer(ReducerKind.ClientConnected)] public static void ClientConnected(ReducerContext ctx) { - Log.Info($"Connect {ctx.Sender()}"); + Log.Info($"Connect {ctx.Sender}"); - if (ctx.Db.player.Identity.Find(ctx.Sender()) is Player player) + if (ctx.Db.player.Identity.Find(ctx.Sender) is Player player) { // We are not logging player login status, so do nothing } else { // Lets setup a new player with a level of 1 - ctx.Db.player.Insert(new Player { Identity = ctx.Sender(), Name = "NewPlayer" }); - var playerId = (ctx.Db.player.Identity.Find(ctx.Sender())!).Value.Id; + ctx.Db.player.Insert(new Player { Identity = ctx.Sender, Name = "NewPlayer" }); + var playerId = (ctx.Db.player.Identity.Find(ctx.Sender)!).Value.Id; ctx.Db.player_level.Insert(new PlayerLevel { PlayerId = playerId, Level = 1 }); } - if (ctx.Db.account.Identity.Find(ctx.Sender()) is null) + if (ctx.Db.account.Identity.Find(ctx.Sender) is null) { - ctx.Db.account.Insert(new Account { Identity = ctx.Sender(), Name = "Account" }); + ctx.Db.account.Insert(new Account { Identity = ctx.Sender, Name = "Account" }); } if (ctx.Db.nullable_vec.Id.Find(1) is null) @@ -781,10 +781,10 @@ public static ReturnStruct TxContextCapabilities(ProcedureContext ctx) } // Test 3: Verify transaction context properties are accessible - var txSender = tx.Sender(); + var txSender = tx.Sender; var txTimestamp = tx.Timestamp; - if (txSender.Equals(ctx.Sender()) == false) + if (txSender.Equals(ctx.Sender) == false) { throw new InvalidOperationException( "Transaction sender should match procedure sender" @@ -825,14 +825,14 @@ public static ReturnStruct AuthenticationCapabilities(ProcedureContext ctx) { // Test 1: Verify authentication context is accessible from procedure context var procAuth = ctx.SenderAuth; - var procSender = ctx.Sender(); + var procSender = ctx.Sender; var procConnectionId = ctx.ConnectionId; var result = ctx.WithTx(tx => { // Test 2: Verify authentication context is accessible from transaction context var txAuth = tx.SenderAuth; - var txSender = tx.Sender(); + var txSender = tx.Sender; var txConnectionId = tx.ConnectionId; // Test 3: Authentication contexts should be consistent diff --git a/templates/chat-console-cs/spacetimedb/Lib.cs b/templates/chat-console-cs/spacetimedb/Lib.cs index 020bf6c072b..3d82175859a 100644 --- a/templates/chat-console-cs/spacetimedb/Lib.cs +++ b/templates/chat-console-cs/spacetimedb/Lib.cs @@ -24,7 +24,7 @@ public static void SetName(ReducerContext ctx, string name) { name = ValidateName(name); - if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) { user.Name = name; ctx.Db.User.Identity.Update(user); @@ -49,7 +49,7 @@ public static void SendMessage(ReducerContext ctx, string text) ctx.Db.Message.Insert( new Message { - Sender = ctx.Sender(), + Sender = ctx.Sender, Text = text, Sent = ctx.Timestamp, } @@ -69,9 +69,9 @@ private static string ValidateMessage(string text) [Reducer(ReducerKind.ClientConnected)] public static void ClientConnected(ReducerContext ctx) { - Log.Info($"Connect {ctx.Sender()}"); + Log.Info($"Connect {ctx.Sender}"); - if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) { // If this is a returning user, i.e., we already have a `User` with this `Identity`, // set `Online: true`, but leave `Name` and `Identity` unchanged. @@ -86,7 +86,7 @@ public static void ClientConnected(ReducerContext ctx) new User { Name = null, - Identity = ctx.Sender(), + Identity = ctx.Sender, Online = true, } ); @@ -96,7 +96,7 @@ public static void ClientConnected(ReducerContext ctx) [Reducer(ReducerKind.ClientDisconnected)] public static void ClientDisconnected(ReducerContext ctx) { - if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user) + if (ctx.Db.User.Identity.Find(ctx.Sender) is User user) { // This user should exist, so set `Online: false`. user.Online = false; From 8842c58c8713cec7233010779649836d3232f727 Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Sun, 8 Feb 2026 17:26:11 +0530 Subject: [PATCH 8/8] sync wiht master --- modules/module-test-cs/Lib.cs | 6 +++--- modules/sdk-test-connect-disconnect-cs/Lib.cs | 4 ++-- modules/sdk-test-cs/Lib.cs | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/module-test-cs/Lib.cs b/modules/module-test-cs/Lib.cs index 72b69649960..a8d7d7a05ba 100644 --- a/modules/module-test-cs/Lib.cs +++ b/modules/module-test-cs/Lib.cs @@ -219,7 +219,7 @@ static partial class Module [View(Name = "my_player", Public = true)] public static Player? my_player(ViewContext ctx) { - return (Player?)ctx.Db.player.identity.Find(ctx.Sender()); + return (Player?)ctx.Db.player.identity.Find(ctx.Sender); } // This reducer is run at module initialization. @@ -278,7 +278,7 @@ public static void log_module_identity(ReducerContext ctx) public static void test(ReducerContext ctx, TestAlias arg, TestB arg2, TestC arg3, TestF arg4) { Log.Info("BEGIN"); - Log.Info($"sender: {ctx.Sender()}"); + Log.Info($"sender: {ctx.Sender}"); Log.Info($"timestamp: {ctx.Timestamp}"); Log.Info($"bar: {arg2.foo}"); @@ -462,7 +462,7 @@ public static void test_btree_index_args(ReducerContext ctx) [Reducer] public static void assert_caller_identity_is_module_identity(ReducerContext ctx) { - var caller = ctx.Sender(); + var caller = ctx.Sender; var owner = ctx.Identity; if (!caller.Equals(owner)) { diff --git a/modules/sdk-test-connect-disconnect-cs/Lib.cs b/modules/sdk-test-connect-disconnect-cs/Lib.cs index 200457fa616..79af81d8cc4 100644 --- a/modules/sdk-test-connect-disconnect-cs/Lib.cs +++ b/modules/sdk-test-connect-disconnect-cs/Lib.cs @@ -19,12 +19,12 @@ static partial class Module [SpacetimeDB.Reducer(ReducerKind.ClientConnected)] public static void identity_connected(ReducerContext ctx) { - ctx.Db.connected.Insert(new Connected { identity = ctx.Sender()}); + ctx.Db.connected.Insert(new Connected { identity = ctx.Sender}); } [SpacetimeDB.Reducer(ReducerKind.ClientDisconnected)] public static void identity_disconnected(ReducerContext ctx) { - ctx.Db.disconnected.Insert(new Disconnected { identity = ctx.Sender()}); + ctx.Db.disconnected.Insert(new Disconnected { identity = ctx.Sender}); } } diff --git a/modules/sdk-test-cs/Lib.cs b/modules/sdk-test-cs/Lib.cs index 0387d77abae..06ddacbb631 100644 --- a/modules/sdk-test-cs/Lib.cs +++ b/modules/sdk-test-cs/Lib.cs @@ -1887,25 +1887,25 @@ public static void update_pk_simple_enum(ReducerContext ctx, SimpleEnum a, int d [SpacetimeDB.Reducer] public static void insert_caller_one_identity(ReducerContext ctx) { - ctx.Db.one_identity.Insert(new OneIdentity { i = ctx.Sender() }); + ctx.Db.one_identity.Insert(new OneIdentity { i = ctx.Sender }); } [SpacetimeDB.Reducer] public static void insert_caller_vec_identity(ReducerContext ctx) { - ctx.Db.vec_identity.Insert(new VecIdentity { i = new List { ctx.Sender() } }); + ctx.Db.vec_identity.Insert(new VecIdentity { i = new List { ctx.Sender } }); } [SpacetimeDB.Reducer] public static void insert_caller_unique_identity(ReducerContext ctx, int data) { - ctx.Db.unique_identity.Insert(new UniqueIdentity { i = ctx.Sender(), data = data }); + ctx.Db.unique_identity.Insert(new UniqueIdentity { i = ctx.Sender, data = data }); } [SpacetimeDB.Reducer] public static void insert_caller_pk_identity(ReducerContext ctx, int data) { - ctx.Db.pk_identity.Insert(new PkIdentity { i = ctx.Sender(), data = data }); + ctx.Db.pk_identity.Insert(new PkIdentity { i = ctx.Sender, data = data }); } [SpacetimeDB.Reducer]