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/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-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/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..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;
}
```
@@ -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..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);
@@ -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 {
@@ -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,
}
@@ -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,
});
@@ -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);
@@ -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..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()}");
}
```
@@ -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(())
}
```
@@ -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.");
}
```
@@ -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..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);
}
@@ -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(())
}
@@ -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 d00bd48fcf9..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.
@@ -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..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()}");
}
```
@@ -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(())
}
```
@@ -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.");
}
```
@@ -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..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);
}
@@ -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(())
}
@@ -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);
@@ -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);
@@ -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))
{
@@ -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..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.
@@ -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..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
@@ -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
@@ -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
@@ -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..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)
@@ -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) {
@@ -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");
}
@@ -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..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
});
}
@@ -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,
})?;
@@ -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;
@@ -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/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 97ec7e2077f..7b8c43ea1b7 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;
}
);
@@ -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
@@ -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:
@@ -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());
}
```
@@ -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())
}
```
@@ -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();
}
@@ -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..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);
@@ -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..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,
@@ -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..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
@@ -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.
@@ -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;
}
@@ -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()
}
```
@@ -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;
}
@@ -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,
@@ -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();
}
@@ -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..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()}");
}
}
```
@@ -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(())
}
@@ -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
}
@@ -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..f2f69378b8e 100644
--- a/docs/llms/docs-benchmark-analysis.md
+++ b/docs/llms/docs-benchmark-analysis.md
@@ -8,18 +8,21 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do
---
-## Analysis of SpacetimeDB Benchmark Test Failures
+# Analysis of SpacetimeDB Benchmark Test Failures
-### Rust / rustdoc_json 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.
-#### Compile/Publish Errors (2 Failures)
+## Rust / rustdoc_json Failures
+
+### Compile/Publish Errors
+
+#### t_002_scheduled_table & t_017_scheduled_columns
-##### 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))]
+ #[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]
pub struct TickTimer {
#[primary_key]
#[auto_inc]
@@ -29,12 +32,10 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do
#[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),
- });
- }
+ ctx.db.tick_timer().insert(TickTimer {
+ scheduled_id: 0,
+ scheduled_at: ScheduleAt::repeat_micros(50_000),
+ });
}
#[reducer]
@@ -73,97 +74,161 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do
- `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.
+ - 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 does not clearly specify the constructor syntax for `ScheduleAt` nor how to correctly set up the scheduled tasks in this context.
+ - The documentation lacks clear guidance on using the `ScheduleAt` type effectively and the format for specifying scheduled actions.
6. **Recommendation**:
- - Update documentation to provide examples of different constructors for `ScheduleAt`, specifically emphasizing how to define intervals correctly.
+ - Update documentation to clarify how to define timing for scheduled entries, using `ScheduleAt::Interval` instead of `ScheduleAt::repeat_*` methods.
----
+### Compile/Publish Errors (3 Failures)
-#### Other Failures (5 failures)
+#### t_003_struct_in_table
-##### 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,
+ pub struct Position {
+ x: i32,
+ y: i32,
}
- #[table(name = result)]
- pub struct ResultRow {
+ #[table(name = entity)]
+ pub struct Entity {
#[primary_key]
id: i32,
- value: Shape,
+ pos: Position,
}
#[reducer]
- pub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {
- ctx.db.result().insert(ResultRow {
- id,
- value: Shape::Circle(radius),
- });
+ 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::{reducer, table, ReducerContext, SpacetimeType, Table};
+ use spacetimedb::{table, SpacetimeType};
#[derive(SpacetimeType, Clone, Debug)]
- pub struct Rect {
- pub width: i32,
- pub height: i32,
+ pub struct Position {
+ pub x: i32,
+ pub y: i32,
}
- #[table(name = result)]
- pub struct ResultRow {
+ #[table(name = entity)]
+ pub struct Entity {
#[primary_key]
pub id: i32,
- pub value: Shape,
+ 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,
}
#[reducer]
- pub fn set_circle(ctx: &ReducerContext, id: i32, radius: i32) {
- ctx.db.result().insert(ResultRow { id, value: Shape::Circle(radius) });
+ 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() });
}
```
-3. **The error**:
- - `spacetime sql failed: no such table: result`
- - `spacetime sql failed: no such table: profile`
- - `spacetime sql failed: no such table: drawings`
-
+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 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.
+ - The generated code did not include the `pub` keyword in front of fields, which results in private access.
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.
+ - Lack of explicit guidelines on visibility modifiers for database fields and schema definition.
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.
+ - Update the documentation to emphasize that struct fields in database models must be public.
---
-### Rust / docs Failures (22 total)
+### Additional Recommendations
-#### Timeout Issues (1 failure)
+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.
-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.
+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.
---
-### C# / docs Failures (4 total)
+## 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# 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;
@@ -234,17 +299,30 @@ Generated from: `/__w/SpacetimeDB/SpacetimeDB/tools/xtask-llm-benchmark/../../do
}
```
-3. **The error**: `no such table: primitive`
-
+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.
+ - The generated code has an extra public field visibility which is redundant in this context, leading to distraction.
5. **Root cause**:
- - Documentation may lack clarity about access modifiers, especially when it comes to how they affect visibility in entities.
+ - Inconsistent handling of public annotations for struct attributes.
6. **Recommendation**:
- - Ensure C# documentation includes explicit examples where `public` is required in class and struct declarations to prevent access issues with tables.
+ - Align the documentation to show proper usage of attributes and visibility appropriately.
----
+---
-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.
+#### 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.
diff --git a/docs/llms/docs-benchmark-comment.md b/docs/llms/docs-benchmark-comment.md
index b26d4820585..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 | 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% ⬆️ +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 | 8/32 | 20.5% ⬆️ +8.0% |
-| Rust | docs | **total** | 13/59 | **15.4%** ⬆️ +3.6% |
+| 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-27T20:01:19.767Z
+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 5d08c34e832..fc7a2432196 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]\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,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:44233",
"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-26T19:27:52.325853523Z",
+ "finished_at": "2026-01-26T19:28:19.691117111Z"
},
"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:44233",
"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-26T19:27:55.244006331Z",
+ "finished_at": "2026-01-26T19:28:22.209162875Z"
},
"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, 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 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 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-27T19:51:00.465423417Z",
- "finished_at": "2026-01-27T19:51:47.339587032Z"
+ "started_at": "2026-01-26T19:28:10.719260484Z",
+ "finished_at": "2026-01-26T19:29:24.230351153Z"
},
"t_003_struct_in_table": {
- "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a",
+ "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a",
"task": "t_003_struct_in_table",
"lang": "rust",
"golden_published": true,
"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::{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",
@@ -125,25 +125,30 @@
"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,
+ "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",
+ "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-27T19:50:43.120116357Z",
- "finished_at": "2026-01-27T19:51:34.789700080Z"
+ "started_at": "2026-01-26T19:27:53.381607365Z",
+ "finished_at": "2026-01-26T19:28:20.526037052Z"
},
"t_004_insert": {
- "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a",
+ "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a",
"task": "t_004_insert",
"lang": "rust",
"golden_published": true,
@@ -158,19 +163,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,23 +179,36 @@
"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: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
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:51:00.012104606Z",
- "finished_at": "2026-01-27T19:51:27.169795394Z"
+ "started_at": "2026-01-26T19:28:03.162962728Z",
+ "finished_at": "2026-01-26T19:28:30.365311126Z"
},
"t_005_update": {
- "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a",
+ "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a",
"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};\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",
@@ -219,11 +224,18 @@
"llm_db": "basics-t-005-update-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:33615",
+ "server": "http://127.0.0.1:44233",
"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,
@@ -240,30 +252,23 @@
"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"
- }
- },
- "seed_users_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:44233"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:50:22.268945837Z",
- "finished_at": "2026-01-27T19:51:01.660325703Z"
+ "started_at": "2026-01-26T19:27:50.273973455Z",
+ "finished_at": "2026-01-26T19:28:39.660285285Z"
},
"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,13 +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": {
- "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,
@@ -286,7 +284,7 @@
"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:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -299,21 +297,28 @@
"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-27T19:50:18.814239252Z",
- "finished_at": "2026-01-27T19:51:00.465380864Z"
+ "started_at": "2026-01-26T19:27:19.862018853Z",
+ "finished_at": "2026-01-26T19:27:52.325711770Z"
},
"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};\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",
@@ -330,19 +335,6 @@
"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,
@@ -363,23 +355,36 @@
"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"
+ "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
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:50:19.572189963Z",
- "finished_at": "2026-01-27T19:51:00.012056746Z"
+ "started_at": "2026-01-26T19:27:23.893528453Z",
+ "finished_at": "2026-01-26T19:28:07.775124578Z"
},
"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, 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",
@@ -387,13 +392,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": 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,
@@ -402,7 +400,7 @@
"llm_db": "basics-t-008-index-lookup-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:33615",
+ "server": "http://127.0.0.1:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -420,23 +418,30 @@
"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:44233"
+ }
+ },
+ "seed_user_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:50:59.032238062Z",
- "finished_at": "2026-01-27T19:51:34.520084103Z"
+ "started_at": "2026-01-26T19:28:01.265667865Z",
+ "finished_at": "2026-01-26T19:28:38.153772708Z"
},
"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::{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",
@@ -453,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,
@@ -470,7 +466,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:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -483,21 +479,30 @@
"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-27T19:50:21.549783Z",
- "finished_at": "2026-01-27T19:50:59.032183836Z"
+ "started_at": "2026-01-26T19:27:35.047568301Z",
+ "finished_at": "2026-01-26T19:28:10.719222494Z"
},
"t_010_connect": {
- "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a",
+ "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a",
"task": "t_010_connect",
"lang": "rust",
"golden_published": true,
"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",
@@ -513,25 +518,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:44233",
"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-26T19:27:22.864510006Z",
+ "finished_at": "2026-01-26T19:28:01.265636007Z"
},
"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]\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",
@@ -554,7 +559,20 @@
"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"
+ "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": {
@@ -566,6 +584,24 @@
"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,
@@ -574,25 +610,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-26T19:28:07.775155436Z",
+ "finished_at": "2026-01-26T19:28:36.996978868Z"
},
"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 { id, value: Score { left, right } });\n}",
"category": "schema",
"route_api_model": "gpt-5",
"golden_db": "schema-t-012-spacetime-product-type-golden",
@@ -617,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:33615",
+ "server": "http://127.0.0.1:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -637,23 +673,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:44233"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:50:17.029809591Z",
- "finished_at": "2026-01-27T19:50:58.838714798Z"
+ "started_at": "2026-01-26T19:27:19.861773654Z",
+ "finished_at": "2026-01-26T19:27:55.243933613Z"
},
"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}",
+ "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",
@@ -665,10 +701,19 @@
"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:33615/v1/database/c200ef5026b116b67d90edbd0acaca12a273f2a7e6e888cc7265a5d4a4fe7173/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:44233/v1/database/c200d2d3b6f126b42f6535fa1c89a272d1278f24e7645295553d055f0964bb68/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,
@@ -677,34 +722,25 @@
"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:44233",
"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:49:28.665478058Z",
- "finished_at": "2026-01-27T19:50:21.549671530Z"
+ "started_at": "2026-01-26T19:26:39.088386414Z",
+ "finished_at": "2026-01-26T19:27:19.723979899Z"
},
"t_014_elementary_columns": {
- "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a",
+ "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a",
"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: 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",
@@ -712,6 +748,15 @@
"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,
@@ -723,7 +768,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:33615"
+ "server": "http://127.0.0.1:44233"
}
},
"schema_parity": {
@@ -734,34 +779,25 @@
"llm_db": "schema-t-014-elementary-columns-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:33615",
+ "server": "http://127.0.0.1:44233",
"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-27T19:50:12.818589409Z",
- "finished_at": "2026-01-27T19:51:00.227383147Z"
+ "started_at": "2026-01-26T19:27:08.469170041Z",
+ "finished_at": "2026-01-26T19:28:03.162920625Z"
},
"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)]\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",
@@ -778,14 +814,6 @@
"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,
@@ -794,25 +822,39 @@
"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:44233",
"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-27T19:49:28.666090278Z",
- "finished_at": "2026-01-27T19:50:19.565536981Z"
+ "started_at": "2026-01-26T19:26:39.089258499Z",
+ "finished_at": "2026-01-26T19:27:08.469138831Z"
},
"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::{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",
@@ -820,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: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:44233/v1/database/c20076700591ec6cb5396663df5e1f56128de954277e753577b8dd7756ee998c/sql)\n",
"phase": "sql_golden"
}
},
@@ -836,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:33615",
+ "server": "http://127.0.0.1:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -845,24 +895,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-26T19:26:39.088020973Z",
+ "finished_at": "2026-01-26T19:27:22.864464632Z"
},
"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, 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",
@@ -874,24 +924,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 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-27T19:49:28.664841535Z",
- "finished_at": "2026-01-27T19:50:33.923572352Z"
+ "started_at": "2026-01-26T19:26:39.087192758Z",
+ "finished_at": "2026-01-26T19:27:53.381568310Z"
},
"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}",
+ "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",
@@ -899,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": {
@@ -925,24 +970,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:44233",
+ "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-26T19:26:39.086684099Z",
+ "finished_at": "2026-01-26T19:27:19.861734913Z"
},
"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 {\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",
@@ -950,26 +1014,13 @@
"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": {
+ "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"
- }
- },
- "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
+ "sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20"
}
},
"m2m_has_1_20": {
@@ -981,38 +1032,51 @@
"sql": "SELECT COUNT(*) AS n FROM membership WHERE user_id=1 AND group_id=20"
}
},
- "m2m_has_1_10": {
+ "memberships_three_rows": {
"pass": true,
"partial": 1.0,
"notes": {
- "actual": 1,
+ "actual": 3,
+ "expected": 3,
+ "sql": "SELECT COUNT(*) AS n FROM membership"
+ }
+ },
+ "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": {
+ "schema_parity": {
"pass": true,
"partial": 1.0,
"notes": {
- "actual": 3,
- "expected": 3,
- "sql": "SELECT COUNT(*) AS n FROM membership"
+ "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-27T19:49:28.665682949Z",
- "finished_at": "2026-01-27T19:50:22.268882588Z"
+ "started_at": "2026-01-26T19:26:39.088752482Z",
+ "finished_at": "2026-01-26T19:27:50.273815091Z"
},
"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::{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",
@@ -1024,7 +1088,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: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:44233/v1/database/c200adf8fd49d0e7e167ec3aa9141c1b249dc335dfa97e666a41345612d7362a/sql)\n",
"phase": "sql"
}
},
@@ -1032,7 +1096,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: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",
"phase": "sql"
}
},
@@ -1044,7 +1116,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:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -1053,32 +1125,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: `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",
+ "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-27T19:49:28.665885964Z",
- "finished_at": "2026-01-27T19:50:18.814108696Z"
+ "started_at": "2026-01-26T19:26:39.089004480Z",
+ "finished_at": "2026-01-26T19:27:35.047523671Z"
},
"t_021_multi_column_index": {
- "hash": "2a0f4ec42cac03fb3da542793b311e4b399845c688bb0660a6c231c82e96c56a",
+ "hash": "da32ac1e4a22e29f27c1c75b3ce526f5ba909c184b9057d83384313a5e7b881a",
"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::{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",
@@ -1094,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:33615",
+ "server": "http://127.0.0.1:44233",
"tables_diff": null,
"tables_equal": true
}
@@ -1108,16 +1172,16 @@
"sql": "SELECT COUNT(*) AS n FROM log"
}
},
- "mcindex_lookup_u7_d1": {
+ "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=1"
+ "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2"
}
},
- "mcindex_lookup_u7_d2": {
+ "mcindex_lookup_u7_d1": {
"pass": true,
"partial": 1.0,
"notes": {
@@ -1128,8 +1192,8 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:49:28.665048738Z",
- "finished_at": "2026-01-27T19:50:12.818516478Z"
+ "started_at": "2026-01-26T19:26:39.087595992Z",
+ "finished_at": "2026-01-26T19:27:23.893472645Z"
}
}
}
@@ -1137,21 +1201,21 @@
},
{
"mode": "docs",
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"models": [
{
"name": "GPT-5",
"route_api_model": "gpt-5",
"tasks": {
"t_000_empty_reducers": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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": "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",
@@ -1169,11 +1233,11 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:53:02.635478741Z",
- "finished_at": "2026-01-27T19:53:40.787269737Z"
+ "started_at": "2026-01-26T19:30:54.611008723Z",
+ "finished_at": "2026-01-26T19:31:59.326178772Z"
},
"t_001_basic_tables": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_001_basic_tables",
"lang": "rust",
"golden_published": true,
@@ -1198,18 +1262,18 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:53:04.338845678Z",
- "finished_at": "2026-01-27T19:53:39.243226783Z"
+ "started_at": "2026-01-26T19:31:23.564110648Z",
+ "finished_at": "2026-01-26T19:32:09.696102989Z"
},
"t_002_scheduled_table": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "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 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\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",
@@ -1227,11 +1291,11 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:53:38.403872273Z",
- "finished_at": "2026-01-27T19:54:31.831288022Z"
+ "started_at": "2026-01-26T19:32:03.232154280Z",
+ "finished_at": "2026-01-26T19:32:55.980604615Z"
},
"t_003_struct_in_table": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_003_struct_in_table",
"lang": "rust",
"golden_published": true,
@@ -1256,11 +1320,11 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:53:02.638916802Z",
- "finished_at": "2026-01-27T19:53:40.055864699Z"
+ "started_at": "2026-01-26T19:31:11.581070012Z",
+ "finished_at": "2026-01-26T19:32:09.839951728Z"
},
"t_004_insert": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_004_insert",
"lang": "rust",
"golden_published": true,
@@ -1275,29 +1339,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-26T19:31:53.617759187Z",
+ "finished_at": "2026-01-26T19:32:28.129265268Z"
},
"t_005_update": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_005_update",
"lang": "rust",
"golden_published": true,
@@ -1312,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": {
@@ -1328,22 +1393,21 @@
"phase": "describe_golden"
}
},
- "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"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:53:00.578961998Z",
- "finished_at": "2026-01-27T19:53:38.403844461Z"
+ "started_at": "2026-01-26T19:30:54.604964500Z",
+ "finished_at": "2026-01-26T19:31:53.617639721Z"
},
"t_006_delete": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_006_delete",
"lang": "rust",
"golden_published": true,
@@ -1366,15 +1430,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 +1438,29 @@
"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-27T19:52:31.910165978Z",
- "finished_at": "2026-01-27T19:52:58.192517311Z"
+ "started_at": "2026-01-26T19:30:54.580009457Z",
+ "finished_at": "2026-01-26T19:32:03.232098066Z"
},
"t_007_crud": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "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 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 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",
@@ -1405,12 +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"
+ "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": {
@@ -1422,12 +1485,12 @@
"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": {
@@ -1441,18 +1504,18 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:52:42.328837521Z",
- "finished_at": "2026-01-27T19:53:33.740284067Z"
+ "started_at": "2026-01-26T19:30:54.591258099Z",
+ "finished_at": "2026-01-26T19:32:19.735936055Z"
},
"t_008_index_lookup": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "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) {\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, 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",
@@ -1460,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,
@@ -1475,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-27T19:53:17.657026192Z",
- "finished_at": "2026-01-27T19:53:54.093778910Z"
+ "started_at": "2026-01-26T19:31:52.996077836Z",
+ "finished_at": "2026-01-26T19:32:44.567947473Z"
},
"t_009_init": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "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",
@@ -1506,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": {
@@ -1532,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-27T19:52:58.192552680Z",
- "finished_at": "2026-01-27T19:53:38.342926441Z"
+ "started_at": "2026-01-26T19:30:54.597845517Z",
+ "finished_at": "2026-01-26T19:32:17.483969682Z"
},
"t_010_connect": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_010_connect",
"lang": "rust",
"golden_published": true,
@@ -1572,11 +1635,11 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:52:35.522740907Z",
- "finished_at": "2026-01-27T19:53:02.635440935Z"
+ "started_at": "2026-01-26T19:30:54.585220084Z",
+ "finished_at": "2026-01-26T19:31:52.995965049Z"
},
"t_011_helper_function": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_011_helper_function",
"lang": "rust",
"golden_published": true,
@@ -1591,21 +1654,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 +1689,18 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:53:37.773674958Z",
- "finished_at": "2026-01-27T19:53:57.689433966Z"
+ "started_at": "2026-01-26T19:31:59.326285562Z",
+ "finished_at": "2026-01-26T19:32:34.857458085Z"
},
"t_012_spacetime_product_type": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "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, 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)]\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",
@@ -1637,12 +1708,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 +1725,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-26T19:30:31.399995435Z",
+ "finished_at": "2026-01-26T19:31:11.581019739Z"
},
"t_013_spacetime_sum_type": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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-26T19:32:55.980673255Z",
+ "finished_at": "2026-01-26T19:32:55.980673255Z"
},
"t_014_elementary_columns": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "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_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, 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",
@@ -1737,30 +1791,30 @@
"phase": "call_reducer_golden"
}
},
- "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"
}
},
- "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"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:52:27.568323309Z",
- "finished_at": "2026-01-27T19:53:02.605112864Z"
+ "started_at": "2026-01-26T19:30:30.882003264Z",
+ "finished_at": "2026-01-26T19:31:23.563975616Z"
},
"t_015_product_type_columns": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"task": "t_015_product_type_columns",
"lang": "rust",
"golden_published": false,
@@ -1785,63 +1839,47 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:54:31.831326960Z",
- "finished_at": "2026-01-27T19:54:31.831326960Z"
+ "started_at": "2026-01-26T19:32:55.980689378Z",
+ "finished_at": "2026-01-26T19:32:55.980689378Z"
},
"t_016_sum_type_columns": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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-26T19:32:55.980668485Z",
+ "finished_at": "2026-01-26T19:32:55.980668485Z"
},
"t_017_scheduled_columns": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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, _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}",
+ "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": "schema-t-017-scheduled-columns-golden",
@@ -1868,190 +1906,105 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:51:47.625840249Z",
- "finished_at": "2026-01-27T19:52:35.522695487Z"
+ "started_at": "2026-01-26T19:29:24.576470966Z",
+ "finished_at": "2026-01-26T19:30:31.399943290Z"
},
"t_018_constraints": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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": {
+ "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-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"
+ "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-26T19:32:55.980661308Z",
+ "finished_at": "2026-01-26T19:32:55.980661308Z"
},
"t_019_many_to_many": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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-26T19:32:55.980679692Z",
+ "finished_at": "2026-01-26T19:32:55.980679692Z"
},
"t_020_ecs": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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-26T19:32:55.980684633Z",
+ "finished_at": "2026-01-26T19:32:55.980684633Z"
},
"t_021_multi_column_index": {
- "hash": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"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(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}",
+ "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": "schema-t-021-multi-column-index-golden",
@@ -2059,6 +2012,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_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,
@@ -2067,15 +2029,6 @@
"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,
@@ -2085,19 +2038,19 @@
"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": {
- "actual": 1,
- "expected": 1,
- "sql": "SELECT COUNT(*) AS n FROM log WHERE user_id=7 AND day=2"
+ "actual": 3,
+ "expected": 3,
+ "sql": "SELECT COUNT(*) AS n FROM log"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:51:47.629929093Z",
- "finished_at": "2026-01-27T19:52:29.436282461Z"
+ "started_at": "2026-01-26T19:29:24.579594233Z",
+ "finished_at": "2026-01-26T19:30:30.881922637Z"
}
}
}
@@ -2288,14 +2241,14 @@
"modes": [
{
"mode": "docs",
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0",
"models": [
{
"name": "GPT-5",
"route_api_model": "gpt-5",
"tasks": {
"t_000_empty_reducers": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0",
"task": "t_000_empty_reducers",
"lang": "csharp",
"golden_published": true,
@@ -2318,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:34379",
+ "server": "http://127.0.0.1:44935",
"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-26T19:38:54.385915075Z",
+ "finished_at": "2026-01-26T19:40:03.912043999Z"
},
"t_001_basic_tables": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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",
@@ -2352,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:34379",
+ "server": "http://127.0.0.1:44935",
"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-26T19:39:06.588178775Z",
+ "finished_at": "2026-01-26T19:40:26.686164444Z"
},
"t_002_scheduled_table": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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]\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 [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",
@@ -2386,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:34379",
+ "server": "http://127.0.0.1:44935",
"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-26T19:40:26.686215935Z",
+ "finished_at": "2026-01-26T19:41:35.359471807Z"
},
"t_003_struct_in_table": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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",
@@ -2420,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:34379",
+ "server": "http://127.0.0.1:44935",
"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-26T19:39:03.248071954Z",
+ "finished_at": "2026-01-26T19:40:22.292027026Z"
},
"t_004_insert": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0",
"task": "t_004_insert",
"lang": "csharp",
"golden_published": true,
@@ -2454,7 +2407,7 @@
"llm_db": "basics-t-004-insert-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:34379",
+ "server": "http://127.0.0.1:44935",
"tables_diff": null,
"tables_equal": true
}
@@ -2475,23 +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:34379"
+ "server": "http://127.0.0.1:44935"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T20:00:17.336276015Z",
- "finished_at": "2026-01-27T20:00:48.236577365Z"
+ "started_at": "2026-01-26T19:40:05.942682308Z",
+ "finished_at": "2026-01-26T19:41:00.825583459Z"
},
"t_005_update": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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\")]\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\")]\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",
@@ -2499,6 +2452,13 @@
"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,
@@ -2515,14 +2475,7 @@
"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,
- "notes": {
- "sql": "INSERT INTO User(Id, Name, Age, Active) VALUES (1, 'Alice', 30, true)"
+ "server": "http://127.0.0.1:44935"
}
},
"schema_parity": {
@@ -2533,18 +2486,18 @@
"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:44935",
"tables_diff": null,
"tables_equal": true
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:59:43.681559749Z",
- "finished_at": "2026-01-27T20:00:17.332627669Z"
+ "started_at": "2026-01-26T19:38:38.720018388Z",
+ "finished_at": "2026-01-26T19:40:05.937381701Z"
},
"t_006_delete": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0",
"task": "t_006_delete",
"lang": "csharp",
"golden_published": true,
@@ -2559,6 +2512,19 @@
"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,
@@ -2574,34 +2540,21 @@
"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-27T19:58:58.264033858Z",
- "finished_at": "2026-01-27T19:59:39.007925686Z"
+ "started_at": "2026-01-26T19:37:37.167869929Z",
+ "finished_at": "2026-01-26T19:38:38.719937430Z"
},
"t_007_crud": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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 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]\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",
@@ -2609,6 +2562,15 @@
"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,
@@ -2617,18 +2579,18 @@
"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: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": {
@@ -2651,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:34379"
+ "server": "http://127.0.0.1:44935"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:59:29.414134061Z",
- "finished_at": "2026-01-27T20:00:06.267814536Z"
+ "started_at": "2026-01-26T19:37:59.027103288Z",
+ "finished_at": "2026-01-26T19:38:54.385590993Z"
},
"t_008_index_lookup": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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 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 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",
@@ -2675,22 +2637,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 +2645,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:44935",
"tables_diff": null,
"tables_equal": true
}
@@ -2710,14 +2656,30 @@
"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-27T20:00:17.332669093Z",
- "finished_at": "2026-01-27T20:00:55.597420674Z"
+ "started_at": "2026-01-26T19:40:05.937447735Z",
+ "finished_at": "2026-01-26T19:41:10.697769188Z"
},
"t_009_init": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0",
"task": "t_009_init",
"lang": "csharp",
"golden_published": true,
@@ -2740,27 +2702,27 @@
"llm_db": "basics-t-009-init-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:34379",
+ "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"
}
},
"init_total_two": {
@@ -2774,18 +2736,18 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:59:39.007990909Z",
- "finished_at": "2026-01-27T20:00:10.594272918Z"
+ "started_at": "2026-01-26T19:38:16.753424300Z",
+ "finished_at": "2026-01-26T19:39:06.588120002Z"
},
"t_010_connect": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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",
@@ -2801,25 +2763,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:44935",
"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-26T19:37:47.380111761Z",
+ "finished_at": "2026-01-26T19:39:03.248030401Z"
},
"t_011_helper_function": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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\")]\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\")]\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",
@@ -2836,6 +2798,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:44935",
+ "tables_diff": null,
+ "tables_equal": true
+ }
+ },
"helper_func_sum_parity": {
"pass": true,
"partial": 1.0,
@@ -2851,36 +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: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:44935"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T20:00:37.824007777Z",
- "finished_at": "2026-01-27T20:01:12.698364118Z"
+ "started_at": "2026-01-26T19:40:22.292081947Z",
+ "finished_at": "2026-01-26T19:41:08.915943296Z"
},
"t_012_spacetime_product_type": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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",
@@ -2903,7 +2865,16 @@
"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"
+ "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"
}
},
"schema_parity": {
@@ -2914,34 +2885,25 @@
"llm_db": "schema-t-012-spacetime-product-type-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:34379",
+ "server": "http://127.0.0.1:44935",
"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-27T19:58:50.225754898Z",
- "finished_at": "2026-01-27T19:59:29.413988946Z"
+ "started_at": "2026-01-26T19:37:30.236090594Z",
+ "finished_at": "2026-01-26T19:38:16.753346626Z"
},
"t_013_spacetime_sum_type": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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 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\", 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",
@@ -2949,17 +2911,21 @@
"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": {
+ "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:34379",
- "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:44935"
}
},
"sum_type_row_count": {
@@ -2971,30 +2937,26 @@
"sql": "SELECT COUNT(*) AS n FROM Result WHERE Id=1"
}
},
- "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:34379"
+ "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-27T19:57:55.737450825Z",
- "finished_at": "2026-01-27T19:58:46.370198569Z"
+ "started_at": "2026-01-26T19:35:59.196578278Z",
+ "finished_at": "2026-01-26T19:37:03.535790946Z"
},
"t_014_elementary_columns": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "hash": "2f6071a69fd778167c45e20453bc018eebc468cc87681c455f819adfa10148a0",
"task": "t_014_elementary_columns",
"lang": "csharp",
"golden_published": true,
@@ -3009,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,
@@ -3017,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:34379",
+ "server": "http://127.0.0.1:44935",
"tables_diff": null,
"tables_equal": true
}
@@ -3026,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: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: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:34379/v1/database/c2008bda321ec5b24f06db6690e57eaa2c1b3a9bada2318accf99feb7910837d/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-26T19:37:03.535862900Z",
+ "finished_at": "2026-01-26T19:37:59.026960569Z"
},
"t_015_product_type_columns": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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",
@@ -3067,11 +3029,20 @@
"llm_db": "schema-t-015-product-type-columns-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:34379",
+ "server": "http://127.0.0.1:44935",
"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,
@@ -3083,82 +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: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"
+ "server": "http://127.0.0.1:44935"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:58:04.285909374Z",
- "finished_at": "2026-01-27T19:58:50.225511855Z"
+ "started_at": "2026-01-26T19:36:38.953458698Z",
+ "finished_at": "2026-01-26T19:37:30.236009816Z"
},
"t_016_sum_type_columns": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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: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": {
+ "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:34379/v1/database/c20028da21a53491f84d8895dbcf4906c6c844846426c39ae32b5fd1689a2641/sql)\n",
- "phase": "sql_golden"
+ "error": "LLM call timed out",
+ "phase": "build_or_publish"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:57:09.422528630Z",
- "finished_at": "2026-01-27T19:58:04.281919840Z"
+ "started_at": "2026-01-26T19:41:35.359543125Z",
+ "finished_at": "2026-01-26T19:41:35.359543125Z"
},
"t_017_scheduled_columns": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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 [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 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",
@@ -3166,14 +3107,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,25 +3115,33 @@
"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:44935",
"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-27T19:57:09.413847953Z",
- "finished_at": "2026-01-27T19:57:55.737395054Z"
+ "started_at": "2026-01-26T19:35:08.495907944Z",
+ "finished_at": "2026-01-26T19:36:38.949408263Z"
},
"t_018_constraints": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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",
@@ -3208,20 +3149,6 @@
"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,
@@ -3239,25 +3166,39 @@
"llm_db": "schema-t-018-constraints-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:34379",
+ "server": "http://127.0.0.1:44935",
"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-27T19:57:09.410769526Z",
- "finished_at": "2026-01-27T19:58:03.584746288Z"
+ "started_at": "2026-01-26T19:35:08.491947971Z",
+ "finished_at": "2026-01-26T19:35:59.196533076Z"
},
"t_019_many_to_many": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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\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\", 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",
@@ -3265,15 +3206,6 @@
"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,
@@ -3291,18 +3223,27 @@
"llm_db": "schema-t-019-many-to-many-gpt-5-llm",
"reducers_diff": null,
"reducers_equal": true,
- "server": "http://127.0.0.1:34379",
+ "server": "http://127.0.0.1:44935",
"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=1 AND GroupId=20"
+ "sql": "SELECT COUNT(*) AS n FROM Membership WHERE UserId=2 AND GroupId=20"
}
},
"m2m_has_1_10": {
@@ -3316,18 +3257,18 @@
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:58:04.046511986Z",
- "finished_at": "2026-01-27T19:58:58.263921552Z"
+ "started_at": "2026-01-26T19:36:32.689581659Z",
+ "finished_at": "2026-01-26T19:37:37.167783708Z"
},
"t_020_ecs": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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\")]\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 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",
@@ -3335,19 +3276,32 @@
"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": {
+ "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": {
"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:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n",
"phase": "sql"
}
},
- "ecs_next_pos_entity1": {
+ "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: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:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n",
"phase": "sql"
}
},
@@ -3355,45 +3309,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: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:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/sql)\n",
"phase": "sql"
}
},
- "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": {
+ "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: `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:44935/v1/database/c2003766705eb1f0e9f55468e9bf8d13f967d7125178a2028f2dd6ca5f43756d/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-26T19:36:38.949546269Z",
+ "finished_at": "2026-01-26T19:37:47.379943704Z"
},
"t_021_multi_column_index": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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 = 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\", 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",
@@ -3401,22 +3342,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": {
+ "mcindex_seed_count": {
"pass": true,
"partial": 1.0,
"notes": {
- "actual": 1,
- "expected": 1,
- "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2"
+ "actual": 3,
+ "expected": 3,
+ "sql": "SELECT COUNT(*) AS n FROM Log"
}
},
- "mcindex_seed_count": {
+ "schema_parity": {
"pass": true,
"partial": 1.0,
"notes": {
- "actual": 3,
- "expected": 3,
- "sql": "SELECT COUNT(*) AS n FROM Log"
+ "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
}
},
"mcindex_lookup_u7_d1": {
@@ -3428,23 +3373,19 @@
"sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=1"
}
},
- "schema_parity": {
+ "mcindex_lookup_u7_d2": {
"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": 1,
+ "expected": 1,
+ "sql": "SELECT COUNT(*) AS n FROM Log WHERE UserId=7 AND Day=2"
}
}
},
"vendor": "openai",
- "started_at": "2026-01-27T19:57:09.418092225Z",
- "finished_at": "2026-01-27T19:58:04.046455117Z"
+ "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 bf684185512..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-27T20:01:19.767Z",
+ "generated_at": "2026-01-26T19:41:35.586Z",
"by_language": {
"csharp": {
"modes": {
"docs": {
- "hash": "e3621eaacfd5238fb514ff8c09c277ccd66170773959e5b391507110bf3ac17b",
+ "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": "d1bf0b033db905c668d016082c762eb4b91edd1299f7b8d4bcc6def5398610f9",
+ "hash": "a9b7f59b2c00330aa9e00220d45b9d8f7d257f9b10dc9f37b56a1e954c2b5117",
"models": {
"GPT-5": {
"categories": {
@@ -56,44 +56,44 @@
},
"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": 18,
+ "passed_tests": 4,
+ "pass_pct": 22.222221,
+ "task_pass_equiv": 1.25,
+ "task_pass_pct": 12.5
}
},
"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": 45,
+ "passed_tests": 9,
+ "pass_pct": 20.0,
+ "task_pass_equiv": 2.5833335,
+ "task_pass_pct": 11.742425
}
}
}
},
"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": 24,
+ "pass_pct": 70.588234,
+ "task_pass_equiv": 6.8666663,
+ "task_pass_pct": 68.666664
}
},
"totals": {
@@ -101,8 +101,8 @@
"total_tests": 61,
"passed_tests": 49,
"pass_pct": 80.327866,
- "task_pass_equiv": 17.533335,
- "task_pass_pct": 79.696976
+ "task_pass_equiv": 16.866667,
+ "task_pass_pct": 76.666664
}
}
}
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/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-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-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-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/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/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/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-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;
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());
}
}