TableTheory v2 migration guide
TableTheory v2.0.0 is the planned major release that completes the deprecation cycle from the 2026-07 Product Strengthening Program. It removes duplicate or misleading public surfaces while preserving the DynamoDB-first contract, the P0/P1/P2 scenario corpus, and the single GitHub Releases distribution path.
This page is an implementation-readiness guide. It does not assert that a v2.0.0 release has been cut. Before any stable v2 release, the maintainer must confirm that the 1.x release candidates and stable releases carrying the deprecation notices were published through the normal immutable release lane.
Who is affected
| Consumer class | What to audit | Coordination path |
|---|---|---|
| AppTheory | Go transaction helpers, typed table/migration options, Python import paths in examples or tests | Validate against the v2 RC before promotion; update examples and scaffolds in the same downstream PR. |
| FaceTheory | TypeScript imports for ISR cache helpers and lease helpers; Go transaction recipes | Move TypeScript domain helpers to subpath imports and run ISR lease/publish transaction tests against the v2 RC. |
| KnowledgeTheory | Python package imports, Go transaction writes, TypeScript number reads for ledger/telemetry-like values | Run data-access integration tests with exact number assertions and canonical tabletheory_py imports. |
| Autheory | Go transactions around identity/session state, encrypted-field read paths, TypeScript/Python imports | Validate optimistic-lock and transaction conflict paths; confirm no encrypted field path logs plaintext. |
| theory-mcp-server | Go transaction APIs, Python tabletheory_py package, TypeScript release-state helpers |
Validate agent memory, idempotency, release-state, and mailbox state flows against DynamoDB Local and the v2 RC. |
| Pay Theory | Payment, settlement, idempotency, and ledger code using transactions or large numbers | Maintainer-mediated validation window on the v2 RC; no direct agent outreach. |
| External open-source consumers | All public APIs listed below | Changelog, GitHub Release notes, and this guide are the only guaranteed channels. |
Release gate checklist
Do not promote a v2 stable release until all of these are true:
- A 1.x release containing the deprecation notices has been published as an immutable GitHub Release.
- Every Theory Cloud product above has either completed an RC validation pass or has an explicit maintainer waiver.
- Pay Theory validation has been coordinated by the maintainer.
- The v2 release PR body contains every
BREAKING CHANGE:footer from this milestone. - The v2 release notes link this guide and list the exact validation commands used for the release candidate.
- The contract suite passes across Go, TypeScript, and Python, including
p2.transact_write_atomicity.
Deprecation audit
The v2 removals below are allowed only because each one had a 1.x additive/deprecation predecessor. Repo-local evidence:
| v2 change | 1.x predecessor evidence | v2 issue |
|---|---|---|
Remove Go DB.Transaction, TransactionFunc, and core.Tx |
docs/development/planning/tabletheory-improvement-program-enumerated-changes-2026-07.md item 1; docs/features/transactions.md warned that db.Transaction(...) and db.TransactionFunc(...) were deprecated in favor of Transact(); docs/development/planning/tabletheory-improvement-program-roadmap-2026-07.md maps item 1 to v2 removal. |
THE-2453 / TTIP-115 |
| Flip TypeScript number unmarshaling default to precision-safe strings | Enumerated item 14 added the opt-in precision-safe mode; ts/docs/core-patterns.md documented the historical lossy default and the numberUnmarshalMode: 'string' migration path; contract-tests/scenarios/p0/10-number-precision.yml pins exact decimal behavior. |
THE-2454 / TTIP-116 |
Make tabletheory_py the only Python import package |
Enumerated item 19 added the tabletheory_py import alias; py/README.md, py/docs/getting-started.md, and docs/runtimes/python/getting-started.md identify tabletheory_py as canonical after the 1.x transition. The legacy theorydb_py package is removed in v2. |
THE-2455 / TTIP-117 |
| Remove TypeScript root re-exports for domain modules | Enumerated item 106 added /facetheory, /release-state, and /lease subpath exports; ts/docs/getting-started.md and docs/runtimes/typescript/getting-started.md marked root imports for those modules deprecated. |
THE-2456 / TTIP-118 |
Remove Go opts ...any option variants |
Enumerated item 69 added concretely typed option APIs and deprecation markers; pkg/core/interfaces.go and internal/theorydb/theorydb.go carried 1.x deprecation notices for the any-typed compatibility surfaces before v2 removal. |
THE-2457 / TTIP-119 |
Remove pkg/query.MainExecutor, pkg/query.NewExecutor, and legacy pkg/query.DynamoDBAPI |
Enumerated item 99 and docs/migration-guide.md documented MainExecutor as a 1.x compatibility/test seam scheduled for next-major removal; production paths already use DB.Model(...), NewWithClient(...), and the runtime executor. |
THE-2458 / TTIP-120 |
1. Go transactions: replace Transaction / TransactionFunc with Transact
Breaking change
DB.Transaction(func(*core.Tx) error), ExtendedDB.TransactionFunc(func(any) error), and the legacy core.Tx wrapper are removed. The removed helpers were non-atomic or duplicate transaction surfaces. The only high-level Go write transaction path is now the DynamoDB-backed Transact() builder / TransactWrite(...) helper.
Exact rewrite
Before:
err := db.Transaction(func(tx *core.Tx) error {
if err := tx.Create(order); err != nil {
return err
}
return tx.Update(account, "balance")
})
After:
err := db.Transact().
Create(order).
Update(account, []string{"balance"}).
Execute()
For callback-style code:
err := db.TransactWrite(ctx, func(tx core.TransactionBuilder) error {
tx.Create(order)
tx.Update(account, []string{"balance"})
return nil
})
Verification steps
grep -R "\.Transaction(" .andgrep -R "TransactionFunc" .in the consumer repo; only migration/provenance prose should remain.- Run the consumer’s DynamoDB Local transaction tests.
- Run TableTheory
make contract-testsand confirmp2.transact_write_atomicitypasses for Go, TypeScript, and Python. - For versioned writes, force a version conflict and confirm the whole transaction aborts.
Downstream coordination
- AppTheory, Autheory, KnowledgeTheory, theory-mcp-server, and Pay Theory must audit Go services for legacy transaction callbacks.
- FaceTheory must verify ISR transaction recipes use
Transact()or direct DynamoDB transaction calls, not the removed wrapper.
2. TypeScript numbers: precision-safe strings are the default
Breaking change
TypeScript now unmarshals DynamoDB N and NS values to canonical decimal strings by default. This prevents JavaScript Number rounding for values such as 9007199254740993 or 0.12345678901234567. Consumers that intentionally want historical lossy JavaScript numbers must opt in.
Exact rewrite
Before v2, exact reads required an option:
const db = new TheorydbClient(ddb, { numberUnmarshalMode: 'string' }).register(LedgerEntry);
In v2, use the default for exact reads:
const db = new TheorydbClient(ddb).register(LedgerEntry);
If a bounded legacy path intentionally wants JavaScript Number coercion:
const lossyDb = new TheorydbClient(ddb, { numberUnmarshalMode: 'number' }).register(LedgerEntry);
Verification steps
- Search for arithmetic performed directly on fields read from DynamoDB
N/NSattributes. - Convert explicit arithmetic to parse with the consumer’s chosen decimal library or
BigIntwhere appropriate. - Add a fixture for
9007199254740993and a high-precision decimal; assert the read value is the original string. - Run
cd ts && npm run checkand TableTheorymake contract-tests.
Downstream coordination
- KnowledgeTheory, Pay Theory, and any ledger/telemetry consumer must validate large-number reads first.
- FaceTheory/AppTheory helpers that use epoch milliseconds or counters can opt into
numberonly after confirming values remain within JavaScript’s safe range.
3. Python package: use tabletheory_py
Breaking change
tabletheory_py is the only Python import package. The legacy theorydb_py package was deprecated during the 1.x transition and is removed in v2; there is no warning shim in the v2 package.
Exact rewrite
Before:
from theorydb_py import ModelDefinition, Table, theorydb_field
from theorydb_py.schema_migration import auto_migrate
After:
from tabletheory_py import ModelDefinition, Table, theorydb_field
from tabletheory_py.schema_migration import auto_migrate
Verification steps
grep -R "theorydb_py" .in the consumer repo; update imports except historical migration notes.- Install the v2 wheel from GitHub Releases and run
python - <<'PY'\nimport tabletheory_py; print(tabletheory_py.__version__)\nPY. - Confirm
python - <<'PY'\nimport theorydb_py\nPYfails withModuleNotFoundErrorafter the consumer no longer depends on the legacy path. - Run Python unit/integration tests against DynamoDB Local.
- Confirm packaged code, generated DMS models, Lambda handlers, and examples import only
tabletheory_py.
Downstream coordination
- KnowledgeTheory, Autheory, theory-mcp-server, and Pay Theory Python services must update imports before the v2 stable release.
- External consumers should be directed to the GitHub Release wheel and this guide; do not suggest PyPI.
4. TypeScript domain modules: use package subpaths
Breaking change
The root TypeScript barrel is now generic ORM only. FaceTheory ISR helpers, release-state helpers, and lease helpers are exported exclusively from subpaths.
Exact rewrite
Before:
import { FaceTheoryIsrMetaStore, transitionReleaseState, LeaseManager } from '@theory-cloud/tabletheory-ts';
After:
import { FaceTheoryIsrMetaStore } from '@theory-cloud/tabletheory-ts/facetheory';
import { transitionReleaseState } from '@theory-cloud/tabletheory-ts/release-state';
import { LeaseManager } from '@theory-cloud/tabletheory-ts/lease';
Verification steps
grep -R "@theory-cloud/tabletheory-ts'" .and inspect any imports of FaceTheory, release-state, or lease symbols.- Run
npm run typecheck(or the consumer equivalent) to catch removed root exports. - Run affected ISR, release-state, and lease tests.
- Run TableTheory
cd ts && npm run check.
Downstream coordination
- FaceTheory is the primary consumer of
/facetheoryand/lease; validate ISR regeneration and lease release flows. - Release automation and theory-mcp-server should validate
/release-stateimports.
5. Go typed options: remove opts ...any
Breaking change
Go table/migration option APIs no longer accept arbitrary opts ...any. Call sites must pass the concrete schema.AutoMigrateOption or schema.TableOption values that the typed methods expect.
Exact rewrite
Before (boxed options compiled because the API accepted opts ...any):
migrationOpts := []any{schema.WithTargetModel(&UserV2{})}
err := db.AutoMigrateWithOptions(&UserV1{}, migrationOpts...)
tableOpts := []any{schema.WithBillingMode(types.BillingModePayPerRequest)}
err = db.CreateTable(&User{}, tableOpts...)
After (make the option slices concrete):
migrationOpts := []schema.AutoMigrateOption{schema.WithTargetModel(&UserV2{})}
err := db.AutoMigrateWithOptions(&UserV1{}, migrationOpts...)
tableOpts := []schema.TableOption{schema.WithBillingMode(types.BillingModePayPerRequest)}
err = db.CreateTable(&User{}, tableOpts...)
Direct calls with typed option values keep the same call shape:
err := db.AutoMigrateWithOptions(&UserV1{}, schema.WithTargetModel(&UserV2{}))
err = db.CreateTable(&User{}, schema.WithBillingMode(types.BillingModePayPerRequest))
Verification steps
- Search for
[]anyorinterface{}values passed toAutoMigrateWithOptionsorCreateTable. - Let
go test ./...catch any remaining non-concrete options at compile time. - Run schema migration/table creation smoke tests against DynamoDB Local.
Downstream coordination
- AppTheory and KnowledgeTheory scaffolds should update any helper that stores schema options in
[]any. - Pay Theory should validate any custom table-provisioning tooling before v2 stable.
6. Go query executor: MainExecutor is removed
Breaking change
pkg/query.MainExecutor, pkg/query.NewExecutor, and the legacy pkg/query.DynamoDBAPI executor seam are removed. The
production execution stack is the runtime executor reached through tabletheory.New(...), tabletheory.LambdaInit(...),
DB.Model(...), and tabletheory.Model(...). Tests that need client injection should use the public
tabletheory.NewWithClient(...) constructor with tabletheory.DynamoDBAPI / session.DynamoDBAPI instead of importing a
seam from pkg/query.
Exact rewrite
Before:
exec := query.NewExecutor(ddb, ctx)
compiled := &core.CompiledQuery{TableName: "users", Operation: "query"}
var out []User
err := exec.ExecuteQuery(compiled, &out)
After:
db, err := tabletheory.NewWithClient(session.Config{Region: "us-east-1"}, ddb)
if err != nil {
return err
}
var out []User
err = db.WithContext(ctx).
Model(&User{}).
Where("PK", "=", "USER#1").
All(&out)
For test code that used MainExecutor only to exercise unmarshaling, call query.UnmarshalItem(...) or
query.UnmarshalItems(...) directly, or use the state-backed fake where the test needs behavior rather than a low-level
executor seam.
Verification steps
grep -R "MainExecutor\|NewExecutor\|query.DynamoDBAPI" .in the consumer repo; only migration prose should remain.- Replace low-level compiled-query tests with
DB.Model(...)tests over DynamoDB Local or the TableTheory fake. - Run
make test-unitand any package-level coverage gates.
Downstream coordination
- Internal Theory Cloud packages should remove direct executor tests before adopting v2.
- External consumers should not construct execution stacks manually; if a use case cannot be expressed through
DB.Model(...), open a TableTheory issue instead of reaching around the runtime.