Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
204 commits
Select commit Hold shift + click to select a range
837c1f7
Add Stack Bench and supporting SDK improvements
bradleyshep Sep 7, 2026
b2b28b9
Expose the repeated-finding limit in dependency campaigns
bradleyshep Sep 7, 2026
be1a236
Clarify repair failure observation counting
bradleyshep Sep 7, 2026
e4346d9
Improve dashboard clarity, responsive layout, and selected-run evidence
bradleyshep Sep 7, 2026
9434a29
Show metric help on labels without question-mark controls
bradleyshep Sep 7, 2026
7ace647
Separate feature progress navigation from comparison tables
bradleyshep Sep 7, 2026
6218b60
Simplify campaign dashboard around results, runs, and feature progress
bradleyshep Sep 7, 2026
56316aa
Show configuration directly and support arbitrary dashboard stacks
bradleyshep Sep 7, 2026
f526ad4
Lead dashboard comparison with mean cost per valid run
bradleyshep Sep 8, 2026
3eb2f4b
Combine campaign comparison metrics in one visible table
bradleyshep Sep 8, 2026
7f347e8
Add dashboard loading states, live clocks, and recorded running costs
bradleyshep Sep 8, 2026
b957545
Fix isolated-run audit and interrupted feature repair evidence
bradleyshep Sep 8, 2026
6d443c5
Refine dashboard loading feedback and partial spend labels
bradleyshep Sep 8, 2026
61a2b3d
Add shared provider adapters and auditable campaign continuation
bradleyshep Sep 8, 2026
e95c494
Remove redundant time request path wrapper
bradleyshep Sep 8, 2026
ce961b5
Fix responsive layout of live campaign rows
bradleyshep Sep 8, 2026
f48e03e
Remove dashboard clutter and hide unavailable report links
bradleyshep Sep 8, 2026
e4bfa39
Render dashboard data progressively and preserve cached pages
bradleyshep Sep 8, 2026
6d0e7f0
Place initial loading feedback inside dashboard tables
bradleyshep Sep 8, 2026
731e333
Reuse compiled recipes within a single resolution
bradleyshep Sep 8, 2026
918dba5
Record grading phase durations without changing check behavior
bradleyshep Sep 8, 2026
44a0f77
Show campaign completion over elapsed run time
bradleyshep Sep 8, 2026
a6ef76b
Preserve campaign grade timestamps by evidence identity
bradleyshep Sep 8, 2026
6b1200f
Add live and saved agent transcripts to run details
bradleyshep Sep 8, 2026
2554a79
Fix repair diagnostics and provide agent browser support
bradleyshep Sep 8, 2026
555cb88
Restore calibration pins and remove time-grant import cycle
bradleyshep Sep 8, 2026
aec778b
Add exact dependency L2 calibration scope
bradleyshep Sep 8, 2026
eeb5bae
Resolve campaign calibration at its declared level
bradleyshep Sep 8, 2026
7faf0c7
Add switchable cumulative cost chart to campaigns
bradleyshep Sep 8, 2026
2186529
Separate campaign chart header from results table
bradleyshep Sep 8, 2026
06af02c
Align live spend with checkpoints and simplify chart lines
bradleyshep Sep 8, 2026
98565d2
Use stable stack brand colors in campaign charts
bradleyshep Sep 8, 2026
a2a2d7b
Retain catalog context in upgrades and clarify missing stock feedback
bradleyshep Sep 8, 2026
c2c9acd
Unify dashboard typography, metric layouts, and status colors
bradleyshep Sep 8, 2026
47c4bb3
Use subtle activity dots for pending costs and features
bradleyshep Sep 8, 2026
244f5bd
Distinguish MongoDB charts with its tertiary purple
bradleyshep Sep 8, 2026
7e5efef
Use green activity indicators and static pass checks
bradleyshep Sep 8, 2026
659ae53
Include CLI guidance and correct repair feedback
bradleyshep Sep 8, 2026
2dd3ec4
Clarify dev module paths for configured publish targets
bradleyshep Sep 9, 2026
b767809
Cache Rust Git dependencies and toolchains in controller builds
bradleyshep Sep 9, 2026
c5473db
Add stack and run visibility controls to campaign charts
bradleyshep Sep 9, 2026
cbf61ed
Align chart controls in one row per stack
bradleyshep Sep 9, 2026
adfd367
Fix repair scope comparison and preserve rejected grade history
bradleyshep Sep 9, 2026
7b2a5a8
Add opt-in SpacetimeDB dev workflow guidance
bradleyshep Sep 9, 2026
3e5f25c
Allow twelve-hour campaign attempts and initialize Linux test containers
bradleyshep Sep 9, 2026
10677f0
Return atomic write errors and document complete dev configuration
bradleyshep Sep 9, 2026
83bb43b
Tighten repair disclosure and clarify first-build scores
bradleyshep Sep 9, 2026
101377a
Clarify connection and account identity in server skill
bradleyshep Sep 9, 2026
5f73ef0
Refresh pending calibration recipe identities
bradleyshep Sep 9, 2026
ce2d0b7
Add opt-in managed SpacetimeDB development command
bradleyshep Sep 9, 2026
8a0f490
Remove campaign list explanatory paragraph
bradleyshep Sep 9, 2026
804c442
Show attempt dependency graph and remove grading prose
bradleyshep Sep 9, 2026
4ea3dc8
Keep dependency graphs at their natural size
bradleyshep Sep 9, 2026
e828d2a
Add campaign completion distribution by provider
bradleyshep Sep 9, 2026
80a5c45
Clarify neutral benchmark prompts and separate completion metrics
bradleyshep Sep 9, 2026
33e07c6
Bind dependency L3 reference qualification scope
bradleyshep Sep 9, 2026
ce80335
Resolve qualification by exact level and catalog path
bradleyshep Sep 9, 2026
f4e1287
Default charts to features and retain disabled cost units
bradleyshep Sep 9, 2026
cb852eb
Accept linked Claude compaction during native continuation
bradleyshep Sep 9, 2026
932a95a
Restore full TypeScript skills and correct audited grading interfaces
bradleyshep Sep 9, 2026
e3bf73e
Allocate campaign resources and isolated subnets automatically
bradleyshep Sep 9, 2026
b59563d
Use shared resource keys in legacy reservation fixture
bradleyshep Sep 9, 2026
37f4c73
Add durable execution jobs and named credential assignments
bradleyshep Sep 9, 2026
2a92334
Add automatic job workers and harden concurrent admission
bradleyshep Sep 9, 2026
44b8238
Harden repair feedback and production probes
bradleyshep Sep 9, 2026
173ec5c
Test local worker dispatch, cancellation, drain, and restart
bradleyshep Sep 10, 2026
9969753
Include model-free adapter entry points in the controller image
bradleyshep Sep 10, 2026
581083f
Normalize prompt fragment line endings across release platforms
bradleyshep Sep 10, 2026
f546749
Constrain PostgreSQL stock probes to the declared interface
bradleyshep Sep 10, 2026
a081817
Use measured repair expectations and correct empty-order diagnostic
bradleyshep Sep 10, 2026
48aa033
test(stack-bench): isolate concurrency and restart defects
bradleyshep Sep 10, 2026
bc8cf88
fix(stack-bench): await scheduled row removal before restart
bradleyshep Sep 10, 2026
f282165
test(stack-bench): reuse buyer in serial race prerequisite
bradleyshep Sep 10, 2026
e19636f
fix(stack-bench): give grading browsers a separate memory cap
bradleyshep Sep 10, 2026
e35b459
test(stack-bench): capture stale stock when editing restock form
bradleyshep Sep 10, 2026
d3f311a
docs(stack-bench): define defensible repair efficacy claims
bradleyshep Sep 10, 2026
2a354c8
Add planned depth pauses without resetting campaign state
bradleyshep Sep 10, 2026
01ee45b
Strengthen production probes and preserve conclusive grading evidence
bradleyshep Sep 10, 2026
62f88cd
fix(stack-bench): exclude live depth pauses from provider budgets
bradleyshep Sep 10, 2026
9972191
fix(stack-bench): own null-control browser and verify pause owner loss
bradleyshep Sep 10, 2026
bd123ae
docs(stack-bench): align guides with current execution and qualification
bradleyshep Sep 10, 2026
18ba395
Fix qualification isolation and bounded browser cancellation
bradleyshep Sep 10, 2026
e1a9547
Update suite counts for isolated qualification checks
bradleyshep Sep 10, 2026
6ea4c41
Preserve failed grade and container activation evidence
bradleyshep Sep 10, 2026
35e72b8
Retain sanitized multiline recovery diagnostics
bradleyshep Sep 10, 2026
abb86af
Use cumulative L3 qualification for earlier dependency depths
bradleyshep Sep 10, 2026
35ee14d
Simplify qualification maintenance and fix mutation reset ordering
bradleyshep Sep 10, 2026
12da392
Restore database schema when rolling back rejected repairs
bradleyshep Sep 10, 2026
f1395a6
Improve dashboard live cost, activity, and refresh handling
bradleyshep Sep 10, 2026
4ff20f3
Resolve active dashboard transcripts from the current owned lease
bradleyshep Sep 10, 2026
a5f7dd4
Cache validated dashboard campaign state across views
bradleyshep Sep 10, 2026
1185b87
Fix probe navigation and preserve observed repair evidence
bradleyshep Sep 10, 2026
a9cfae6
Remove long chart hover descriptions
bradleyshep Sep 10, 2026
94705db
Retain coding resource diagnostics and provide shared browser tooling
bradleyshep Sep 10, 2026
cb2dc51
Define scheduled restock input types for deterministic grading
bradleyshep Sep 10, 2026
92683d3
Harden grading controls and repair failure context
bradleyshep Sep 10, 2026
2caff21
Handle offscreen panels and status case in grading
bradleyshep Sep 10, 2026
9081821
Keep grading panels open across sequential checks
bradleyshep Sep 10, 2026
1606b34
fix(stack-bench): identify distribution runs on linked hover
bradleyshep Sep 11, 2026
a2937a5
feat(stack-bench): extend production checks and harden campaign execu…
bradleyshep Sep 12, 2026
3535e6a
fix(stack-bench): prevent browser thread exhaustion and misgraded nav…
bradleyshep Sep 12, 2026
49a895f
fix(stack-bench): show live Codex costs on dashboard
bradleyshep Sep 12, 2026
2c72793
fix(stack-bench): state empty database startup contract
bradleyshep Sep 12, 2026
f226ecc
fix(stack-bench): correct grading prerequisites and view navigation
bradleyshep Sep 12, 2026
2ba5ed1
fix(stack-bench): declare purchase prerequisites for grading actions
bradleyshep Sep 12, 2026
e02054e
fix(stack-bench): release dashboard streams in hidden tabs
bradleyshep Sep 12, 2026
e769180
Fix isolated database resets and order-history navigation
bradleyshep Sep 12, 2026
bb6d17b
Fix account navigation and isolate production probe prerequisites
bradleyshep Sep 12, 2026
570d2fd
Strengthen production probes and audit campaign impact
bradleyshep Sep 12, 2026
15098b1
Refresh draft calibration inputs for probe validation
bradleyshep Sep 12, 2026
25e5c42
Fix restock quantity type in SpacetimeDB reference client
bradleyshep Sep 12, 2026
7fd8b25
Keep optional navigation observation timeouts non-fatal
bradleyshep Sep 12, 2026
486b8aa
Preserve PostgreSQL reference data across application restarts
bradleyshep Sep 12, 2026
7a3304f
Fix missing-order responses in MongoDB reference actions
bradleyshep Sep 12, 2026
b44b4aa
Record validated probe controls and saved-app regrades
bradleyshep Sep 12, 2026
4eae953
Keep stock validation after live transfer observations
bradleyshep Sep 12, 2026
54db22a
Add the Stack Bench isometric system map
bradleyshep Sep 12, 2026
9cfc671
Rebuild the Stack Bench system map with one ground plate and uniform …
bradleyshep Sep 12, 2026
a95da62
Turn the Stack Bench system map into linked campuses with named tokens
bradleyshep Sep 12, 2026
26e166c
Preserve recorded spend for incomplete campaign reports
bradleyshep Sep 12, 2026
f975eca
Validate exported reference hashes during controller builds
bradleyshep Sep 12, 2026
61c8813
Add plan, result, and operations campuses to the Stack Bench system map
bradleyshep Sep 12, 2026
f9619f7
Correct shipping and staff-role defect controls
bradleyshep Sep 12, 2026
cf746b8
Fix scoped qualification timing and stock-alert controls
bradleyshep Sep 12, 2026
a67ca54
Handle restored sessions during authentication readiness
bradleyshep Sep 12, 2026
3a9ce37
Correct remaining MongoDB defect controls
bradleyshep Sep 12, 2026
41af662
Add the dependency graph and per-feature check views to the Stack Ben…
bradleyshep Sep 12, 2026
768c85e
Replace the escape hint with a Return control on the Stack Bench syst…
bradleyshep Sep 13, 2026
b385a9e
Fix navigation races and support logout grading
bradleyshep Sep 13, 2026
1e68f37
Route dependency wires per chapter and simplify the Return control on…
bradleyshep Sep 13, 2026
33a9313
Add reviewed run setup shared by dashboard and CLI
bradleyshep Sep 13, 2026
570818b
Use clear guidance names in run setup
bradleyshep Sep 13, 2026
a12cf55
Resolve configured accounts before reviewing a run
bradleyshep Sep 13, 2026
c4bb6ef
Show what each feature asks for and proves on the Stack Bench system map
bradleyshep Sep 13, 2026
239beba
Separate run guidance choices and correct support defect controls
bradleyshep Sep 13, 2026
1801011
Keep Mongo reference state reads from racing purchase payments
bradleyshep Sep 13, 2026
15de603
Fix grading navigation, restart isolation, and last-unit dispatch
bradleyshep Sep 13, 2026
294cf78
Default to progressive runs and admit work from host pressure
bradleyshep Sep 13, 2026
98d468c
Restore the signed-in recommendation list contract in the PostgreSQL …
bradleyshep Sep 13, 2026
c3cee24
Queue standalone work and increase grader browser headroom
bradleyshep Sep 13, 2026
f5effde
Load dashboard session without scanning campaign history
bradleyshep Sep 13, 2026
3f04454
Keep navigation timeouts unmeasured during grading
bradleyshep Sep 14, 2026
7b4a58e
Allow diagnostic replay of recovered dependency candidates
bradleyshep Sep 14, 2026
87ccb20
Preserve grading failures across observations and progression
bradleyshep Sep 14, 2026
6a81950
Simplify local dashboard controls without an operator password
bradleyshep Sep 14, 2026
f00db27
Read canonical artifact hashes when validating qualification evidence
bradleyshep Sep 14, 2026
4e1ecc0
Accept conclusive blocked setup in null qualification evidence
bradleyshep Sep 14, 2026
1632a60
Refresh dependency repair integration fixtures
bradleyshep Sep 14, 2026
001da23
Clarify storefront ordering and add conditional purchase-search coverage
bradleyshep Sep 14, 2026
574822d
Keep cross-depth repair evidence on its execution level
bradleyshep Sep 14, 2026
d825d1c
Preserve concurrent request evidence on cancellation
bradleyshep Sep 14, 2026
4e6c92d
Wait for complete concurrent HTTP responses
bradleyshep Sep 14, 2026
0f15cb9
Add draft stored checkout reconciliation diagnostic
bradleyshep Sep 14, 2026
9f9adc5
Preserve checkout snapshots across grader actions and refresh contrac…
bradleyshep Sep 14, 2026
1076d76
Match checkout SQL to SpacetimeDB reference column names
bradleyshep Sep 14, 2026
a95fd33
Read checkout tables from one SpacetimeDB subscription snapshot
bradleyshep Sep 14, 2026
3bd87a7
Use deployed names in SpacetimeDB checkout snapshots
bradleyshep Sep 14, 2026
f149c6d
Close the orders panel before inspecting checkout cart state
bradleyshep Sep 14, 2026
ebae9de
Document the verified Stack Bench repair-study baseline
bradleyshep Sep 14, 2026
2dbfce0
fix(stack-bench): enforce adapter process ownership and identity
bradleyshep Sep 14, 2026
a3836a5
Add draft address-book migration contract and preservation observers
bradleyshep Sep 15, 2026
8dd180f
Add native address-book migration reference diagnostics
bradleyshep Sep 15, 2026
8847ed6
Record address-book reference validation and limits
bradleyshep Sep 15, 2026
5c57068
Preserve populated code and database checkpoints for migration repairs
bradleyshep Sep 15, 2026
c8ad02a
Qualify populated migrations through shared agent and repair boundaries
bradleyshep Sep 15, 2026
98d12b1
fix(stack-bench): replay saved migration source on original data
bradleyshep Sep 15, 2026
af360fa
feat(stack-bench): bind populated grading to compiled starting state
bradleyshep Sep 15, 2026
f55d5a2
Connect populated upgrades to benchmark setup and repair lifecycle
bradleyshep Sep 15, 2026
8899eff
Fix grading retry archives and repair failure restoration
bradleyshep Sep 15, 2026
a4bdf9c
Add draft address-book migration observations to the main grader
bradleyshep Sep 15, 2026
f75624d
Bind migration grading to original purchase evidence
bradleyshep Sep 15, 2026
ab6d42c
Validate populated-run and grade-bundle provenance
bradleyshep Sep 15, 2026
7a752b9
Accept restored sessions during migration restart checks
bradleyshep Sep 15, 2026
dccd65a
Fix native restart and migration observation failures
bradleyshep Sep 15, 2026
50ad3a9
Keep migration optional and prioritize core benchmark checks
bradleyshep Sep 15, 2026
0a8e400
Remove experimental migration from core Stack Bench
bradleyshep Sep 15, 2026
4bcb4eb
dash
bradleyshep Sep 15, 2026
325bb48
Ignore repository-local working notes
bradleyshep Sep 15, 2026
ebc2171
Document core cancellation diagnostic scope
bradleyshep Sep 15, 2026
86ca3bb
Reconcile core purchase contention with stored business effects
bradleyshep Sep 15, 2026
7bb1844
Document purchase diagnostic scope and limits
bradleyshep Sep 15, 2026
ac6e124
Add draft checkout crash diagnostics with confirmed recovery evidence
bradleyshep Sep 15, 2026
c9ab4b3
Keep unsettled crash checkouts inconclusive across grading actions
bradleyshep Sep 15, 2026
d2267db
Keep app-crash checkout results inconclusive until database work settles
bradleyshep Sep 15, 2026
fc79b8a
Wait for surviving database work before app-crash grading
bradleyshep Sep 15, 2026
bc6d594
Keep crash drain deadline exhaustion inconclusive
bradleyshep Sep 15, 2026
0ea9bdc
Report confirmed crash recovery failures with unsettled requests
bradleyshep Sep 16, 2026
82b19fa
Clarify draft crash diagnostic scope after reference qualification
bradleyshep Sep 16, 2026
b69cc57
Run reference diagnostics in isolated parallel case groups
bradleyshep Sep 16, 2026
768cfbf
Support source-bound saved application crash diagnostics
bradleyshep Sep 16, 2026
a44fa1b
Extend saved application crash diagnostics across database stacks
bradleyshep Sep 16, 2026
9d0e12c
Complete reload steps in draft crash scenarios
bradleyshep Sep 16, 2026
510a26a
Repair qualification fingerprints for current runtime imports
bradleyshep Sep 16, 2026
8ebbacc
Isolate grading evidence and restore accepted repair dependencies
bradleyshep Sep 16, 2026
10289c5
Repair catalog mutation controls and include anchor validation in def…
bradleyshep Sep 16, 2026
cf3cc8a
Add default-on production-quality prompting to run setup
bradleyshep Sep 16, 2026
617309a
Resolve workflow guidance from the installed Stack Bench package
bradleyshep Sep 16, 2026
3f2da8a
Treat empty checkout stock reads as measurable evidence
bradleyshep Sep 16, 2026
b83b7e6
Handle concurrent network removal and reject over-budget qualification
bradleyshep Sep 16, 2026
43d01f6
Fix calibration timing identities and qualify measured pack budgets
bradleyshep Sep 16, 2026
816e2a0
Bind accepted dependency L3 qualification evidence
bradleyshep Sep 16, 2026
d3f1327
Keep queued crash checkouts unconfirmed
bradleyshep Sep 16, 2026
8605209
Confirm baseline purchases before crash diagnostics
bradleyshep Sep 16, 2026
fd319da
Mark doors and illustrate questline scoring on the Stack Bench system…
bradleyshep Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
**/ModuleBindings/** linguist-generated=true eol=lf
/docs/llms/** linguist-generated=true
/docs/llms/*-details.json linguist-generated=false
/tools/stack-bench/** text eol=lf
/tools/stack-bench/**/*.woff2 -text -diff
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,6 @@ nul

# Any local file
*.local

# Local working notes and temporary builds
/local-notes/
11 changes: 5 additions & 6 deletions codex-plugin/plugins/spacetimedb/skills/cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ spacetime build --debug # faster iteration, slower runtime

# Dev mode (auto-rebuild, auto-publish, generates bindings)
spacetime dev
spacetime dev --client-lang typescript --module-bindings-path ./client/src/module_bindings
spacetime dev my-database --server local --yes --delete-data=never --client-lang typescript --module-bindings-path ./client/src/module_bindings

# Generate client bindings
spacetime generate --lang typescript|csharp|rust --out-dir ./bindings --module-path ./server
spacetime generate --lang unrealcpp --uproject-dir ./MyGame --module-path ./server --unreal-module-name MyGame
```

`dev` stays running and watches module changes. `--run "npm run dev"` starts a client command; `--server-only` omits it. `--module-path` selects the module directory when no publish targets exist in `spacetime.json`. Once targets exist, use their configured paths and omit that flag. Separate build/publish/generate commands remain useful for one-shot deployment.

### Publishing & Deployment

```bash
Expand Down Expand Up @@ -112,7 +114,7 @@ spacetime server add myserver --url https://my-spacetime.example.com
# Set default server
spacetime server set-default local

# Test connectivity
# Check connectivity
spacetime server ping local

# Start local instance
Expand Down Expand Up @@ -169,10 +171,7 @@ spacetime server ping <server>
```

### "Schema conflict"
```bash
# Clear data and republish
spacetime publish my-db --delete-data=always --yes
```
`--delete-data=never` rejects incompatible schema updates without clearing data. A compatible migration preserves existing data; `--delete-data=always` destroys it and is only appropriate for an intentional reset.

### "Build failed"
```bash
Expand Down
4 changes: 2 additions & 2 deletions codex-plugin/plugins/spacetimedb/skills/concepts/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ Lifecycle: Write → Compile → Publish (`spacetime publish`) → Hot-swap (rep

## Identity

- **Identity**: A long-lived, globally unique identifier for a user.
- **ConnectionId**: Identifies a specific client connection.
- **Identity**: A long-lived, globally unique identifier for a user, derived from the token's issuer and subject claims. The same token yields the same identity on every connection.
- **ConnectionId**: Identifies one client connection. A new connection gets a new connection ID; a disconnect ends the connection, not the identity.
- Always use `ctx.sender` / `ctx.Sender` / `ctx.sender()` for authorization.

SpacetimeDB works with many OIDC providers, including SpacetimeAuth (built-in), Auth0, Clerk, Keycloak, Google, and GitHub.
2 changes: 2 additions & 0 deletions codex-plugin/plugins/spacetimedb/skills/cpp-server/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ SPACETIMEDB_CLIENT_DISCONNECTED(on_disconnect, ReducerContext ctx) {
}
```

Connection hooks run once per connection. The same authenticated principal keeps the same identity (`ctx.sender()`) across connections, while each connection has its own connection ID (`ctx.connection_id()`). A disconnect ends one connection; it does not end the identity, which returns unchanged on the next connection with the same token. Use connection IDs for presence and other connection-scoped state.

## Authentication & Timestamps

```cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ public static void OnConnect(ReducerContext ctx) { ... }
public static void OnDisconnect(ReducerContext ctx) { ... }
```

`ctx.ConnectionId` is `ConnectionId?`, including in connection lifecycle reducers. Check or unwrap it before storing it in a non-nullable column or passing it to an index accessor.
Connection hooks run once per connection. The same authenticated principal keeps the same identity (`ctx.Sender`) across connections, while each connection has its own connection ID (`ctx.ConnectionId`). A disconnect ends one connection; it does not end the identity, which returns unchanged on the next connection with the same token. Use connection IDs for presence and other connection-scoped state.

`ctx.ConnectionId` is typed `ConnectionId?`. It is present inside connection lifecycle reducers and reducers invoked over a connection, and null in `Init` and scheduled reducers. Check or unwrap it before storing it in a non-nullable column or passing it to an index accessor.

## Views

Expand Down
2 changes: 2 additions & 0 deletions codex-plugin/plugins/spacetimedb/skills/rust-server/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ pub fn on_connect(ctx: &ReducerContext) { ... }
pub fn on_disconnect(ctx: &ReducerContext) { ... }
```

Connection hooks run once per connection. The same authenticated principal keeps the same identity (`ctx.sender()`) across connections, while each connection has its own connection ID (`ctx.connection_id()`). A disconnect ends one connection; it does not end the identity, which returns unchanged on the next connection with the same token. Use connection IDs for presence and other connection-scoped state.

The current connection ID is available through `ctx.connection_id()` (not a public field) and may be absent outside connection-scoped calls.

## Views
Expand Down
32 changes: 13 additions & 19 deletions codex-plugin/plugins/spacetimedb/skills/typescript-client/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Generated bindings convert snake_case names to camelCase, including row fields:
## React: main.tsx

```typescript
import React, { useEffect, useMemo } from 'react';
import React, { useMemo } from 'react';
import ReactDOM from 'react-dom/client';
import { SpacetimeDBProvider } from 'spacetimedb/react';
import { DbConnection } from './module_bindings';
Expand All @@ -30,6 +30,7 @@ function Root() {
DbConnection.builder()
.withUri(SPACETIMEDB_URI)
.withDatabaseName(MODULE_NAME)
// Reuse the token issued on the previous connection.
.withToken(localStorage.getItem('auth_token') || undefined),
[]
);
Expand All @@ -46,27 +47,18 @@ ReactDOM.createRoot(document.getElementById('root')!).render(<Root />);
## React: App.tsx

```typescript
import { useEffect } from 'react';
import { useTable, useSpacetimeDB } from 'spacetimedb/react';
import { DbConnection, tables } from './module_bindings';

function App() {
const { isActive, identity: myIdentity, token, getConnection } = useSpacetimeDB();
const { identity: myIdentity, token, getConnection } = useSpacetimeDB();
const conn = getConnection() as DbConnection | null;

// Save auth token
// Persist the issued token for the next page load.
useEffect(() => { if (token) localStorage.setItem('auth_token', token); }, [token]);

// Subscribe when connected. Prefer typed query builders over raw SQL
useEffect(() => {
if (!conn || !isActive) return;
conn.subscriptionBuilder()
.onApplied(() => setSubscribed(true))
.subscribe([tables.entity, tables.record]);
// Or with filters: tables.entity.where(r => r.active.eq(true))
// Or raw SQL: 'SELECT * FROM entity'
}, [conn, isActive]);

// Reactive data. Returns [rows, isReady]
// useTable owns the subscription and cleanup. Returns [rows, isReady].
const [entities, entitiesReady] = useTable(tables.entity);
const [records, recordsReady] = useTable(tables.record);

Expand All @@ -80,8 +72,8 @@ function App() {
}
);

// Call reducers with object syntax
conn?.reducers.addRecord({ data }).catch(console.error);
// A callback for a UI event; defining it does not call the reducer during render.
const addRecord = (data: string) => conn?.reducers.addRecord({ data }).catch(console.error);

// Compare identities
const isMe = row.owner.toHexString() === myIdentity?.toHexString();
Expand Down Expand Up @@ -111,7 +103,9 @@ conn.db.user.onUpdate((ctx, oldUser, newUser) => console.log('Updated:', newUser

## Gotchas

- **`useTable` rows are `readonly`.** Copy before sorting/mutating, or it fails to type-check:
- **Subscription rows have no presentation order.** A server view's array order does not
define client cache iteration order. `useTable` rows are `readonly`; a sorted copy can
express the application's display order:
`const [rows] = useTable(tables.message); const sorted = [...rows].sort(...)`.
- **bigint in JSX.** ids/counts from `t.u64()`/`t.i64()` columns are `bigint`, which React
cannot render. Wrap it: `{Number(row.id)}` or `{String(count)}`.
- **64-bit display values.** `{String(row.id)}` preserves the full `bigint` value.
Conversion to `Number` can lose precision outside JavaScript's safe integer range.
33 changes: 30 additions & 3 deletions codex-plugin/plugins/spacetimedb/skills/typescript-server/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ Every column is a `t` builder value:

Modifiers: `.primaryKey()`, `.autoInc()`, `.unique()`, `.index('btree')`, `.default(value)`.

`.primaryKey()` and `.unique()` apply to one column. For uniqueness across
multiple columns, use a surrogate key, the multi-column index below, and a
reducer that rejects an existing index match before inserting. An index alone
does not enforce uniqueness.

Use `.default(value)` only for a newly appended migration-safe field. Do not put defaults on primary-key, unique, or auto-increment columns.

Optional columns: `nickname: t.option(t.string())`
Expand Down Expand Up @@ -130,7 +135,9 @@ export { default } from './schema'; // re-export the schema for the module ent

## Reducers

Reducers are created with `spacetimedb.reducer(...)`; the export name becomes the reducer name:
Reducers are created with `spacetimedb.reducer(...)`. An exported `signUp`
becomes `signUp` in generated clients and `sign_up` in `spacetime call` and
`describe`:

```typescript
export const createEntity = spacetimedb.reducer(
Expand Down Expand Up @@ -178,10 +185,17 @@ export const onConnect = spacetimedb.clientConnected((ctx) => { ... });
export const onDisconnect = spacetimedb.clientDisconnected((ctx) => { ... });
```

`ctx.connectionId` is `ConnectionId | null`, including in lifecycle contexts. Guard it before passing it to a helper or using it as a table key.
Connection hooks run once per connection. The same authenticated principal keeps the same identity (`ctx.sender`) across connections, while each connection has its own connection ID (`ctx.connectionId`). A disconnect ends one connection; it does not end the identity, which returns unchanged on the next connection with the same token. Use connection IDs for presence and other connection-scoped state. Reloads and temporary network loss also disconnect clients; application login expiry and explicit sign-out are separate from connection cleanup.

`ctx.connectionId` is typed `ConnectionId | null`. It is present inside connection lifecycle hooks and reducers invoked over a connection, and `null` in `init` and scheduled reducers. Guard it before passing it to a helper or using it as a table key.

## Reducer Context API

Each reducer call runs in one database transaction. An error that escapes the
reducer rolls back its database changes. `ctx.sender` identifies the caller;
application roles and permissions are not inferred from that identity. Table
visibility and view filters control reads, not authorization to call reducers.

`ctx` is the only source of sender identity, time, and randomness; stdlib clocks and RNG are unavailable in modules. Let exported callbacks infer their context type. In helpers, use `ReducerCtx<InferSchema<typeof spacetimedb>>`; do not annotate a context as `any`, because that erases table row types and can make `bigint` expressions infer as `number`.

```typescript
Expand Down Expand Up @@ -278,17 +292,30 @@ const Shape = t.enum('Shape', {
A client subscribing to a view receives only the rows it returns. Use a per-user view
(keyed on `ctx.sender`) for per-viewer access control: deleting a row it depends on
(e.g. a membership row) automatically drops the rows it was exposing from that client.
Use index accessors in views. Do not scan a whole table with `.iter()` when an
indexed lookup can select the required rows.

`t.row(...)` and `t.object(...)` return schema builders, not TypeScript runtime row types. Let a view callback infer its result, or annotate a separately declared structural type such as `Array<{ sku: bigint; label: string }>`. A named output type must not reuse the generated PascalCase name of its view accessor (for example, reserve `DiscountedProduct` for a `discounted_product` view).

A view context is `ViewCtx<S>` (and `AnonymousViewCtx<S>`), both exported from
`spacetimedb/server`. It carries `sender`, a read-only `db`, and `from`; it is
not a `ReducerCtx`, so a helper shared between a reducer and a view must accept
either:

```typescript
import type { ReducerCtx, ViewCtx, InferSchema } from 'spacetimedb/server';
type S = InferSchema<typeof spacetimedb>;
function stockOf(ctx: ReducerCtx<S> | ViewCtx<S>, itemId: bigint) { ... }
```

Both `spacetimedb.view(...)` and `spacetimedb.anonymousView(...)` take three arguments: view options, the declared return schema, and the callback.

```typescript
// Anonymous view (same for all clients):
export const activeUsers = spacetimedb.anonymousView(
{ name: 'active_users', public: true },
t.array(entity.rowType),
(ctx) => [...ctx.db.entity.iter()].filter(e => e.active)
(ctx) => [...ctx.db.entity.active.filter(true)] // active: t.bool().index('btree')
);

// Per-user view (varies by ctx.sender):
Expand Down
26 changes: 14 additions & 12 deletions crates/bindings-typescript/src/lib/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,19 +248,21 @@ export type NamespacedQueryBuilder<SchemaDef extends UntypedSchemaDef> =
* A runtime reference to a table. This materializes the RowExpr for us.
* TODO: Maybe add the full SchemaDef to the type signature depending on how joins will work.
*/
export type TableRef<TableDef extends TypedTableDef> = Readonly<{
type: 'table';
sourceName: TableDef['sourceName'];
accessorName: string;
cols: RowExpr<TableDef>;
indexedCols: IndexedRowExpr<TableDef>;
tableDef: TableDef;
// Keep this named so TypeScript diagnostics show `TableRef` instead of its
// expanded structure.
export interface TableRef<TableDef extends TypedTableDef> {
readonly type: 'table';
readonly sourceName: TableDef['sourceName'];
readonly accessorName: string;
readonly cols: RowExpr<TableDef>;
readonly indexedCols: IndexedRowExpr<TableDef>;
readonly tableDef: TableDef;
// Delegated UntypedTableDef properties for compatibility.
columns: TableDef['columns'];
indexes: TableDef['indexes'];
rowType: TableDef['rowType'];
constraints: any;
}>;
readonly columns: TableDef['columns'];
readonly indexes: TableDef['indexes'];
readonly rowType: TableDef['rowType'];
readonly constraints: any;
}

class TableRefImpl<TableDef extends TypedTableDef>
implements TableRef<TableDef>, From<TableDef>
Expand Down
79 changes: 79 additions & 0 deletions crates/bindings-typescript/tests/table_ref_error_message.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import * as ts from 'typescript';
import { describe, expect, it } from 'vitest';

const bindingsRoot = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'..'
);

function runTypecheck(source: string) {
const tmpDir = mkdtempSync(path.join(tmpdir(), 'stdb-tableref-diag-'));
const reproPath = path.join(tmpDir, 'repro.ts');
writeFileSync(reproPath, source);

try {
const options: ts.CompilerOptions = {
target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.ESNext,
strict: true,
noEmit: true,
skipLibCheck: true,
forceConsistentCasingInFileNames: true,
allowImportingTsExtensions: true,
noImplicitAny: true,
moduleResolution: ts.ModuleResolutionKind.Bundler,
useDefineForClassFields: true,
verbatimModuleSyntax: true,
isolatedModules: true,
};

const host = ts.createCompilerHost(options);
const program = ts.createProgram(
[reproPath, path.join(bindingsRoot, 'src/server/sys.d.ts')],
options,
host
);
const diagnostics = ts.getPreEmitDiagnostics(program);
return diagnostics.map(d =>
ts.flattenDiagnosticMessageText(d.messageText, '\n')
);
} finally {
rmSync(tmpDir, { recursive: true, force: true });
}
}

describe('TableRef diagnostics', () => {
const source = `
import { t } from ${JSON.stringify(path.join(bindingsRoot, 'src/server/index.ts'))};
import { table } from ${JSON.stringify(path.join(bindingsRoot, 'src/lib/table.ts'))};
import { createTableRefFromDef } from ${JSON.stringify(path.join(bindingsRoot, 'src/lib/query.ts'))};
import type { AllUnique } from ${JSON.stringify(path.join(bindingsRoot, 'src/lib/constraints.ts'))};

const cartItem = table(
{ name: 'cart_item' },
{ id: t.u64().primaryKey().autoInc(), accountId: t.u64(), quantity: t.u32() }
);

const ref = createTableRefFromDef(cartItem as any, 'cartItem');
type Boom = AllUnique<typeof ref, ['accountId']>;
declare const b: Boom;
`;

it('names the type instead of dumping its structure', () => {
const messages = runTypecheck(source);
const constraintError = messages.find(m =>
m.includes("does not satisfy the constraint 'UntypedTableDef'")
);

expect(constraintError).toBeDefined();
// The name, not the shape.
expect(constraintError).toContain('TableRef<');
expect(constraintError).not.toContain('type: "table"');
expect(constraintError).not.toContain('accessorName');
expect(constraintError.length).toBeLessThan(250);
}, 15000);
});
2 changes: 2 additions & 0 deletions crates/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::process::Command;
use toml::Value;

fn main() {
println!("cargo:rerun-if-env-changed=SPACETIMEDB_NIX_BUILD_GIT_COMMIT");
let git_hash = find_git_hash();
println!("cargo:rustc-env=GIT_HASH={git_hash}");

Expand Down Expand Up @@ -110,6 +111,7 @@ fn generate_template_files() {

// Embed skill files from skills/*/SKILL.md
let skills_dir = repo_root.join("skills");
println!("cargo:rerun-if-changed={}", skills_dir.display());
let skill_names = discover_skill_names(&skills_dir);

generated_code.push_str("pub fn get_skill(name: &str) -> Option<&'static str> {\n");
Expand Down
Loading
Loading