mainsequence-metatable 0.1.20.dev32__tar.gz → 0.1.21.dev33__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mainsequence_metatable-0.1.20.dev32/src/mainsequence_metatable.egg-info → mainsequence_metatable-0.1.21.dev33}/PKG-INFO +1 -1
- mainsequence_metatable-0.1.21.dev33/docs/adr/api/0017-hosted-request-identity.md +99 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/index.md +1 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/authentication-and-errors.md +19 -6
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/installation-and-connection.md +3 -3
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/contributing/releasing.md +11 -5
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/contributing/testing.md +16 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/configuration.md +2 -1
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/hosted-runtime.md +12 -2
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/security/index.md +5 -3
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/mkdocs.yml +1 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/pyproject.toml +1 -1
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/check_boundaries.py +1 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33/src/mainsequence_metatable.egg-info}/PKG-INFO +1 -1
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/mainsequence_metatable.egg-info/SOURCES.txt +2 -2
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/auth/boundary.py +20 -19
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/main.py +49 -1
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/sdk_compat.py +6 -1
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_local_mode.py +46 -31
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_platform_fact_cache.py +19 -12
- mainsequence_metatable-0.1.21.dev33/tests/auth/test_request_identity.py +240 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_runtime_scaffold.py +6 -6
- mainsequence_metatable-0.1.21.dev33/tests/conftest.py +128 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_sqlite_runtime.py +18 -20
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/uv.lock +1 -1
- mainsequence_metatable-0.1.20.dev32/src/metatables/api/app/auth/caller_assertions.py +0 -39
- mainsequence_metatable-0.1.20.dev32/tests/auth/test_caller_assertions.py +0 -60
- mainsequence_metatable-0.1.20.dev32/tests/conftest.py +0 -40
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/.agents/skills/client/metatables-local-development/SKILL.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/.agents/skills/client/metatables-meta-tables/SKILL.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/.agents/skills/client/metatables-migrations/SKILL.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/.agents/skills/client/metatables-time-index-table-updates/SKILL.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/.agents/skills/client/metatables-upgrade-legacy-app/SKILL.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/.mainsequence/workflows/metatables-api.yaml +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/LICENSE +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/MANIFEST.in +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/alembic.ini +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/api/metatables/main.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/compose.database-tests.yml +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0001-unified-api-storage-and-local-sqlite.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0002-application-administration-and-table-ownership.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0004-approved-application-migrations.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0005-run-logs-and-local-file-capture.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0006-historical-run-graphs.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0007-database-enforced-table-access.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0007-database-roles-and-privileges.svg +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0007-query-enforcement-path.svg +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0008-mysql-mssql-table-workflows.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0009-shared-credential-store.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0010-import-external-tables-and-views.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0012-bounded-data-transfer-and-safe-retries.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0013-application-owned-migrations.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0014-main-sequence-release-jobs-and-production-migrations.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0015-timescale-compression-and-retention-policies.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/api/0016-impact-preflight.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/client/0003-api-endpoint-resolution.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/client/0011-cli-local-development-with-managed-admin.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/data-sources.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/openapi.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/overview.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/reference.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/tables-and-migrations.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/api/time-index-and-updates.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/assets/branding/metatables.svg +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/assets/diagrams/local-client-experience.svg +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/bounded-transfers.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/build-an-updater.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/define-and-migrate-tables.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/deploy-application-migrations.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/local-storage.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/query-and-mutate.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/quickstart.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/read-existing-time-index-tables.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/register-existing-tables.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/tutorial.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/client/upgrade-legacy-app.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/architecture.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/data-sources.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/identity-and-scope.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/permissions-namespaces-labels.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/runs-and-execution-graphs.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/table-contracts-and-lifecycle.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/concepts/time-index-tables-and-updates.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/contributing/architecture-and-boundaries.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/contributing/database-backends.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/contributing/documentation.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/bounded_reader.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/data_sources/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/data_sources/mssql.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/data_sources/mysql.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/data_sources/postgresql.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/data_sources/register.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/external_table.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/__main__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/migrations/versions/metatables_local_example/0001.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/local_app/tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/query.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/quickstart.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/reader.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/scripts/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/scripts/setup_metatables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/__main__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/data/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/data/yahoo_spy_qqq_iwm_2026-06-15_2026-07-17.csv +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/frames.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/registry.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/versions/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/versions/metatables_market_tutorial/0001_create_market_tutorial_tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/versions/metatables_market_tutorial/0002_create_rolling_volatility.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/migrations/versions/metatables_market_tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/tutorial/updaters.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/examples/updater.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/index.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/catalog-migrations.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/local-runtime.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/recovery-and-observability.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/run-history.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/operations/run-logs.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/reference/capabilities.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/reference/cli.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/reference/python.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/security/ownership-and-sharing.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/security/permissions.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/build_reference.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/check_client_api_coverage.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/check_distribution_sources.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/check_docs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/check_examples_debug.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/check_project.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/dev_release_version.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/test_databases.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/scripts/test_postgresql.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/setup.cfg +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/mainsequence_metatable.egg-info/dependency_links.txt +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/mainsequence_metatable.egg-info/entry_points.txt +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/mainsequence_metatable.egg-info/requires.txt +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/mainsequence_metatable.egg-info/top_level.txt +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/_admin_source.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/_build.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/_skill_bundle.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/auth/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/auth/local_actor.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/bootstrap.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/configuration.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/credential_admin.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/development.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/development_client.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/error_logging.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/platform_cache.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/column_search.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/contract_validation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/data_sources.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/managed_finalize.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/migration_connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/namespaces.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/run_logs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/runtime_context.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/schema_graph.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/security.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_cascade.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_crud.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_delete.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_filter.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_import.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_introspection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_patch.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_registration.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_response.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_search_document.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_sql.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/table_update_pipeline.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/time_index_delete.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/time_index_reads.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/time_index_stats.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/timescale_policies.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_batch.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_chunk_insert.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_constants.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_crud.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_details.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_graph.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_index_statistics.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_registration.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_runs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/routes/update_statistics.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/runtime.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/runtime_control.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/runtime_database.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/source_passwords.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/app/transfer.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/access.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/maintenance/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/maintenance/postgresql.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/maintenance/runtime.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/maintenance/temporal.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/maintenance/timescaledb.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/maintenance/validation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_cascade_delete.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_introspection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_table_delete.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_time_index.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_time_index_delete.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_time_index_queries.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_time_index_stats.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/postgresql_time_index_write.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/source_validation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/sqlite_connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/sqlite_introspection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/adapters/table_cursor.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/catalog.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/catalog_ddl.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/catalog_types.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/contracts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/hosted.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/hosted_access.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/migration_connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/native.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/pages.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/postgresql_access.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/registry.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/relation_tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/relational.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/restricted_sql.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/sqlite_access.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/streaming.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/backends/timescale.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/contracts/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/contracts/relation_import.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/contracts/storage_layouts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/contracts/table_contracts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/contracts/values.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/catalog_rules.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/data_source_rules.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/index_statistics.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/label_rules.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/permission_rules.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/domain/update_constants.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/catalog_data_sources.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/credential_keys.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/credential_store.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/data_source_provider.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/local_credentials.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/local_workspace.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/platform_principals.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/run_logs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/runtime_binding.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/runtime_data_sources.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/integrations/source_validation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0001_initial.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0002_security_model.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0003_run_log_capture.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0004_historical_run_graphs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0005_database_access.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0006_local_credentials.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0007_external_relation_names.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0008_upload_receipts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0009_timescale_policies.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/0010_cascade_targets.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/migrations/versions/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/bootstrap_migrations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/catalog_schema.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/create_table.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/finalize_managed.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/import_relations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/introspect_table.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/read_time_index.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/register_catalog.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/operations/search_documents.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/cascade.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/catalog.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/database.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/grants.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/impact.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/labels.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/locking.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/models.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/physical_operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/projections.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/run_graphs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/schema_graph.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/sqlite_types.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/table_body_filter.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/table_queries.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/table_response.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/update_graph.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/update_pipeline.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/updates.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/persistence/upload_receipts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/backend/presentation/data_source_summary.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/metatables/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/metatables/configuration.yaml +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/api/metatables/main.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/admin_install.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/app.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/filters.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/local.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/migrations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/project.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/cli/skills.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/compiled_sql/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/compiled_sql/mssql.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/compiled_sql/v1.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/dtype_codec.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/endpoint.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/bounded_reader.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/data_sources/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/data_sources/mssql.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/data_sources/mysql.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/data_sources/postgresql.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/data_sources/register.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/external_table.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/__main__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/migrations/versions/metatables_local_example/0001.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/local_app/tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/query.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/quickstart.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/reader.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/scripts/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/scripts/setup_metatables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/__main__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/data/README.md +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/data/yahoo_spy_qqq_iwm_2026-06-15_2026-07-17.csv +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/frames.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/registry.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/script.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/versions/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/versions/metatables_market_tutorial/0001_create_market_tutorial_tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/versions/metatables_market_tutorial/0002_create_rolling_volatility.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/migrations/versions/metatables_market_tutorial/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/tutorial/updaters.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/examples/updater.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/future_registry.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/hashing.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/instrumentation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/local_connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/local_files.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/local_run_logs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/log_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/alembic.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/provider.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/registry.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/runner.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/scaffold.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/sqlite.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/templates/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/templates/env.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/templates/script.py.mako +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/migrations/tls.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/models.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/pydantic_metadata.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/run_logging.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/runtime.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/runtime_context.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/runtime_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/schema_names.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/sqlalchemy_contracts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/storage_layout_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/time_index_table_refs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/transfer.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/transfer_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/transport.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/update_configuration_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/configuration.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/dependencies.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/managers.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/namespacing.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/runner.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/updaters.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/updaters/utils.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/src/metatables/upload.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_bootstrap_failure_cause.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_data_source_identity.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_development_client.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_hosted_environment_target.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_runtime_bootstrap.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_runtime_database.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_runtime_selection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_runtime_storage_binding.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/auth/test_source_passwords.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/catalog/test_catalog_foundation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/catalog/test_contract_projection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/catalog/test_database_config.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/catalog/test_index_statistics.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/catalog/test_migration.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/capabilities.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/client_signatures.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/database_operations.json +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/test_bounded_transfer.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/test_compiler_runtime_source.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/test_relation_batching.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/test_relation_import.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/test_storage_layouts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/contracts/test_table_contracts.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/Dockerfile +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/Dockerfile.dockerignore +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/conftest.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/provider/__init__.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/provider/env.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/provider/versions/0001_measurement.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_api_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_application_migration.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_bootstrap_recovery.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_catalog_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_credential_catalog.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_physical_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_relation_import.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_runtime_bootstrap.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_sql_security.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_backend/test_update_client.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_operations/test_physical_operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_operations/test_postgresql_operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/database_operations/test_runtime_and_temporal.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/documentation/test_project_checks.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_admin_installation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_api_endpoint.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_application_owned_migrations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_catalog_outage.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_api_contract.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_api_coverage.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_migration_scaffold.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_migration_tls.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_package.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_signatures.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_client_value_behaviors.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_data_source_registry.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_local_actor_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_local_cli_workflow.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_local_client_selection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_managed_finalize_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_namespaces_admin_http.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_public_imports.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_remaining_client_routes.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_run_graphs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_run_logs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_runtime_upgrade.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_sdk_local_startup.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_delete_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_filter_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_introspection_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_patch_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_search_document_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_stats_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_update_pipeline.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_table_updates_http.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_time_index_delete_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_time_index_reads_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_timescale_policies_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_update_batch_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_update_chunk_insert_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_update_dependency_priority_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_update_index_statistics_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/e2e/test_update_registration_client_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/examples/test_documented_examples.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/examples/test_postgresql_examples.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/examples/test_setup_launch.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/examples/test_tutorial.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_credential_store.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_data_source_rules.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_local_data_sources.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_local_run_logs.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_postgresql_connection.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_postgresql_sql.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_postgresql_tables.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_postgresql_time_index_queries.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_source_validation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/integrations/test_sqlite_operations.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/labels/test_labels.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/operations/test_create_table_operation.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/operations/test_create_table_postgres.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/operations/test_physical_operation_journal.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/operations/test_register_catalog.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/operations/test_search_documents.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/operations/test_timescale_policies.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/packaging/test_client_skills.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/packaging/test_dev_release_version.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/packaging/test_distribution_sources.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/packaging/test_editable_build.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/packaging/test_installed_distribution.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_governed_sql_scope.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_local_actor_membership.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_migration_boundary.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_namespace_grants.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_security_api.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_table_body_filter.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_table_grants.py +0 -0
- {mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/tests/permissions/test_table_queries.py +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# ADR 0017: Hosted caller identity through the SDK request identity
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-04
|
|
4
|
+
|
|
5
|
+
Status: Accepted.
|
|
6
|
+
|
|
7
|
+
Implementation status: implemented for 0.1.21. Tests cover the hosted entrypoint's
|
|
8
|
+
launcher declaration, genuine EdDSA caller assertions verified by the SDK, rejected
|
|
9
|
+
callers, Local isolation, and PodDeploymentOrchestrator's own launcher run against
|
|
10
|
+
the deployed entrypoint. A hosted rollout has not yet been verified.
|
|
11
|
+
|
|
12
|
+
Owner: MetaTables API. The SDK owns caller verification
|
|
13
|
+
([SDK 9.0.6 ADR 0036: Request-scoped logged user](https://github.com/mainsequence-sdk/mainsequence-sdk/blob/v9.0.6/docs/adr/0036-request-scoped-logged-user.md));
|
|
14
|
+
the platform's FastAPI launcher owns the startup check.
|
|
15
|
+
|
|
16
|
+
Related decisions: [ADR 0001](0001-unified-api-storage-and-local-sqlite.md) (one API
|
|
17
|
+
execution path, with Local for development), [ADR 0002](0002-application-administration-and-table-ownership.md)
|
|
18
|
+
(admission and platform facts) and [ADR 0007](0007-database-enforced-table-access.md)
|
|
19
|
+
(the API authenticates the caller; the database enforces grants).
|
|
20
|
+
|
|
21
|
+
## Context
|
|
22
|
+
|
|
23
|
+
Since 2026-09-28 the platform's FastAPI launcher serves an application only when
|
|
24
|
+
`app.state.mainsequence_request_identity` declares the installed SDK integration,
|
|
25
|
+
the deployment's caller mode (`assertion` when hosted) and its public ingress
|
|
26
|
+
(`FASTAPI_PUBLIC_INGRESS`). The SDK's `install_request_identity(app)` sets that
|
|
27
|
+
declaration. MetaTables verified caller assertions itself, in its admission
|
|
28
|
+
dependency, and never installed the integration. Every hosted revision after
|
|
29
|
+
0.1.13 therefore stopped at startup with "Application request identity is not
|
|
30
|
+
installed" while traffic stayed on the 0.1.13 revision
|
|
31
|
+
([#34](https://github.com/mainsequence-projects/MetaTables/issues/34)).
|
|
32
|
+
|
|
33
|
+
## Decision
|
|
34
|
+
|
|
35
|
+
- The application factory installs the SDK request identity once, after mounting
|
|
36
|
+
every route, for the hosted runtime only. Its middleware is the outermost
|
|
37
|
+
application middleware, so callers are verified before local admission,
|
|
38
|
+
transfer limits or any route.
|
|
39
|
+
- It installs it when the process carries the platform's caller-authentication
|
|
40
|
+
configuration: any of `MAINSEQUENCE_CALLER_AUTH_MODE`, `APP_NAME`,
|
|
41
|
+
`FASTAPI_PUBLIC_BASE_URL`, `MAINSEQUENCE_CALLER_ASSERTION_ISSUER` or
|
|
42
|
+
`MAINSEQUENCE_CALLER_ASSERTION_JWKS_URL`. The SDK and the launcher select their
|
|
43
|
+
mode from the same variables, and every hosted deployment carries them.
|
|
44
|
+
- The hosted API accepts only platform caller assertions. If the SDK would select
|
|
45
|
+
another mode, creating the app fails; incomplete trust configuration also fails
|
|
46
|
+
at startup. Without any of these variables nothing is installed, no caller is
|
|
47
|
+
ever bound, and admission rejects every caller with 401.
|
|
48
|
+
- The SDK verifies each assertion once, before the route: missing or invalid proof
|
|
49
|
+
is 401 and unavailable key discovery is 503. Admission takes the caller's User UID
|
|
50
|
+
from `User.get_logged_user()` and the verified target Environment from the request
|
|
51
|
+
state the SDK records. It no longer reads the assertion header or calls the
|
|
52
|
+
verifier. The SDK verifier keeps no replay record, so assertions are not
|
|
53
|
+
single-use; a second verification would only repeat key discovery and could
|
|
54
|
+
disagree at the expiry boundary.
|
|
55
|
+
- Local and developer runtimes never install it. The SDK's local mode requires a
|
|
56
|
+
Bearer token on every request and validates it against the platform, while Local
|
|
57
|
+
admits requests through its loopback listener and the launcher's private token
|
|
58
|
+
with the developer's SDK user resolved at startup. Local clients send no Bearer
|
|
59
|
+
token, so the SDK would reject every Local request. `metatables serve --local`
|
|
60
|
+
runs its own uvicorn worker, which the platform launcher never checks.
|
|
61
|
+
- `metatables.api.app.main:app` is created on first access. Importing the factory,
|
|
62
|
+
as the Local worker and the hosted entrypoint do, builds no extra app and cannot
|
|
63
|
+
fail because a shell carries a platform variable.
|
|
64
|
+
- MetaTables declares no anonymous route. The SDK copies the deployment's
|
|
65
|
+
`FASTAPI_PUBLIC_INGRESS` into the declaration unchanged; every other route,
|
|
66
|
+
including `/`, `/docs` and `/openapi.json`, requires a caller.
|
|
67
|
+
- The direct verifier dependency, `metatables.api.app.auth.caller_assertions`, is
|
|
68
|
+
removed so that no route can verify an assertion a second time.
|
|
69
|
+
|
|
70
|
+
## Consequences
|
|
71
|
+
|
|
72
|
+
- Who may call what is unchanged. The caller is still the User in a platform-signed
|
|
73
|
+
assertion for this release and Environment. Admin and Team facts, the one-hour
|
|
74
|
+
fact cache, table and namespace grants and database enforcement are unchanged.
|
|
75
|
+
Unsigned User headers, the runtime's own SDK account and Bearer tokens never
|
|
76
|
+
identify a hosted caller.
|
|
77
|
+
- New hosted revisions pass the launcher's check and can roll out. The SDK
|
|
78
|
+
requirement stays `mainsequence>=9.0.6,<10`, which provides the integration.
|
|
79
|
+
- Hosted routes without an admission dependency (`/` and the OpenAPI pages) now also
|
|
80
|
+
require a verified caller; the platform ingress already authenticated those
|
|
81
|
+
requests. A numeric `X-User-Id` header is rejected with 401.
|
|
82
|
+
- The SDK answers rejected callers itself with `{"detail": ...}`, so MetaTables'
|
|
83
|
+
error handler no longer logs them. The launcher's request log records each
|
|
84
|
+
request's authentication outcome.
|
|
85
|
+
- The SDK and the launcher look for public ingress routes among the app's top-level
|
|
86
|
+
routes. FastAPI 0.142 keeps included routers unflattened, so a route mounted
|
|
87
|
+
through a router cannot be declared public; startup would refuse it. MetaTables
|
|
88
|
+
declares none.
|
|
89
|
+
|
|
90
|
+
## Verification
|
|
91
|
+
|
|
92
|
+
`tests/auth/test_request_identity.py` imports the deployed entrypoint under a
|
|
93
|
+
simulated hosted environment and checks its declaration, verifies genuine EdDSA
|
|
94
|
+
assertions signed with a test key served as the platform's key document, and checks
|
|
95
|
+
rejected callers, a key outage, the other runtimes and the refused modes. With
|
|
96
|
+
`PYTHONPATH` naming PodDeploymentOrchestrator's `src` directory, it also runs that
|
|
97
|
+
launcher's `require_request_identity` and `serve_fastapi` against the entrypoint.
|
|
98
|
+
`tests/auth/test_local_mode.py` shows Local admission is unchanged when a shell
|
|
99
|
+
carries hosted variables, and that the SDK's local mode would reject Local clients.
|
{mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/adr/index.md
RENAMED
|
@@ -37,3 +37,4 @@ decisions belong in the SDK repository and are linked as dependencies.
|
|
|
37
37
|
| [0014: System migrations in the deployment workflow](api/0014-main-sequence-release-jobs-and-production-migrations.md) | Accepted; implemented on development; hosted verification pending | A Main Sequence Job verifies, migrates and registers the declared runtime database from the candidate image before each API rollout, including the first. |
|
|
38
38
|
| [0015: TimescaleDB compression and retention policies](api/0015-timescale-compression-and-retention-policies.md) | Accepted; implemented on branch; TimescaleDB verification pending | Time-index tables on TimescaleDB become hypertables; Writers set compression and retention through the API/Admin; Timescale keeps the jobs, and the Admin shows their status. |
|
|
39
39
|
| [0016: Impact pre-flight for cascades and deletes](api/0016-impact-preflight.md) | Accepted; implemented; container engine verification pending | `get_impact` returns what a row delete, key update or table drop reaches, every blocker and whether the caller may write each table, from the planner the confirmed delete runs; cascade effects never block. Projects render it in their own UIs. |
|
|
40
|
+
| [0017: Hosted caller identity through the SDK request identity](api/0017-hosted-request-identity.md) | Accepted; implemented for 0.1.21; hosted rollout verification pending | The hosted API installs the SDK request identity that the platform launcher requires; the SDK verifies each caller assertion once and admission reads `User.get_logged_user()`. Local keeps its loopback token admission. |
|
|
@@ -5,11 +5,22 @@ Reader/Writer ownership, live namespace inheritance, and sharing endpoints.
|
|
|
5
5
|
|
|
6
6
|
## Hosted requests
|
|
7
7
|
|
|
8
|
-
The API
|
|
9
|
-
platform
|
|
10
|
-
request-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
The hosted API installs the `mainsequence` SDK's request identity once, when it is
|
|
9
|
+
created; the platform's FastAPI launcher requires it before serving a deployment
|
|
10
|
+
([ADR 0017](../adr/api/0017-hosted-request-identity.md)). The SDK verifies the
|
|
11
|
+
platform-signed caller assertion before any route runs and owns issuer, key
|
|
12
|
+
discovery, claim, request-target, signature, and expiry verification. It answers a
|
|
13
|
+
missing or invalid assertion with 401 and unavailable key discovery with 503.
|
|
14
|
+
Admission then reads the caller from `User.get_logged_user()` and never verifies the
|
|
15
|
+
assertion again. Unsigned user headers, Bearer tokens and the runtime's own SDK
|
|
16
|
+
account are not identity evidence.
|
|
17
|
+
|
|
18
|
+
The API installs the integration when the process carries the platform's
|
|
19
|
+
caller-assertion configuration, as every hosted deployment does, and accepts no
|
|
20
|
+
other SDK mode. Once it is installed, every route not declared in the deployment's
|
|
21
|
+
`FASTAPI_PUBLIC_INGRESS` requires a caller, including `/` and the OpenAPI pages;
|
|
22
|
+
MetaTables declares no anonymous route. A hosted API started without that
|
|
23
|
+
configuration installs nothing, and admission rejects every caller.
|
|
13
24
|
|
|
14
25
|
After verification, the API reads the admitted User through the SDK to obtain
|
|
15
26
|
current admin status and active Team UIDs. It evaluates table/namespace grants
|
|
@@ -26,7 +37,9 @@ A local server binds only a loopback listener supplied by `metatables serve
|
|
|
26
37
|
one-hour fact cache used by subsequent requests. Each request checks
|
|
27
38
|
loopback peer, exact Host, the private local process token, and browser-origin
|
|
28
39
|
policy. Hosted caller assertions are rejected in local mode; request headers
|
|
29
|
-
cannot choose an authentication mode or supply another user.
|
|
40
|
+
cannot choose an authentication mode or supply another user. Local does not install
|
|
41
|
+
the SDK request identity, whose local mode would require a platform Bearer token on
|
|
42
|
+
every request.
|
|
30
43
|
|
|
31
44
|
`METATABLES_LOCAL_ALLOWED_ORIGINS` lists exact loopback browser origins with ports.
|
|
32
45
|
The default permits no browser-origin write requests. Native requests without
|
|
@@ -11,7 +11,7 @@ require running another service locally.
|
|
|
11
11
|
Install in your application's Python environment on macOS or Linux:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
python -m pip install "mainsequence-metatable==0.1.
|
|
14
|
+
python -m pip install "mainsequence-metatable==0.1.21" "mainsequence==9.0.6"
|
|
15
15
|
mainsequence login
|
|
16
16
|
metatables init --local
|
|
17
17
|
metatables serve --local --admin
|
|
@@ -20,9 +20,9 @@ metatables serve --local --admin
|
|
|
20
20
|
Run from an application Git checkout with a commit and an `origin` remote. Python
|
|
21
21
|
3.13+ is required. Admin also needs Node.js 22.12+ (or 20.19+) and npm. The package
|
|
22
22
|
requires published `mainsequence>=9.0.6,<10`; no SDK checkout is needed.
|
|
23
|
-
The next stable release is MetaTables 0.1.
|
|
23
|
+
The next stable release is MetaTables 0.1.21, paired with published SDK 9.0.6.
|
|
24
24
|
The pinned command above applies after that stable release is published; before
|
|
25
|
-
then, install the exact `0.1.
|
|
25
|
+
then, install the exact `0.1.21.devN` artifact produced by the development publishing
|
|
26
26
|
workflow alongside `mainsequence==9.0.6`. SDK 8 is outside this release's
|
|
27
27
|
dependency range.
|
|
28
28
|
`python -m metatables.sdk_compat` checks the required SDK interfaces without network
|
|
@@ -39,11 +39,17 @@ distribution.
|
|
|
39
39
|
|
|
40
40
|
CI installs dependencies from `uv.lock` and PyPI. An editable SDK checkout cannot
|
|
41
41
|
substitute for the published SDK in a release. The selected SDK artifact must
|
|
42
|
-
provide ordinary `Secret.get_by_uid`, independent Git source context,
|
|
43
|
-
`CallerAssertionVerifier.from_environment
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
provide ordinary `Secret.get_by_uid`, independent Git source context,
|
|
43
|
+
`CallerAssertionVerifier.from_environment`, and the FastAPI request identity:
|
|
44
|
+
`mainsequence.server.fastapi.install_request_identity` and `User.get_logged_user`.
|
|
45
|
+
|
|
46
|
+
The next MetaTables stable release is `0.1.21`; its supported SDK range is
|
|
47
|
+
`mainsequence>=9.0.6,<10`. Development builds use `0.1.21.devN`.
|
|
48
|
+
0.1.21 is the first release whose hosted API installs the SDK request identity.
|
|
49
|
+
Since 2026-09-28 the platform's FastAPI launcher refuses an app without it, so a new
|
|
50
|
+
hosted API revision needs 0.1.21
|
|
51
|
+
([#34](https://github.com/mainsequence-projects/MetaTables/issues/34),
|
|
52
|
+
[ADR 0017](../adr/api/0017-hosted-request-identity.md)).
|
|
47
53
|
The minimum and lockfile now select published SDK `9.0.6`. SDK 9.0.4 is the first
|
|
48
54
|
whose caller-assertion verifier accepts the platform's EdDSA (Ed25519) caller
|
|
49
55
|
assertions; earlier SDKs verify only RS256, so a hosted API built with them cannot
|
|
@@ -30,6 +30,22 @@ scaffold/TLS tests, and executable example tests. Loopback tests need permission
|
|
|
30
30
|
to bind local sockets. Tests inject identity and SDK responses where appropriate;
|
|
31
31
|
they do not claim a hosted SDK deployment has been verified.
|
|
32
32
|
|
|
33
|
+
## Hosted request identity
|
|
34
|
+
|
|
35
|
+
The `platform_caller_assertions` fixture simulates a hosted deployment's trust
|
|
36
|
+
configuration and signs genuine EdDSA caller assertions that the SDK verifies.
|
|
37
|
+
`tests/auth/test_request_identity.py` also runs PodDeploymentOrchestrator's
|
|
38
|
+
`require_request_identity` and `serve_fastapi` against the deployed entrypoint when
|
|
39
|
+
that launcher is importable; otherwise those two tests are skipped:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
PYTHONPATH=/path/to/PodDeploymentOrchestrator/src python -m pytest -q tests/auth/test_request_identity.py
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The suite removes platform caller-authentication variables inherited from the
|
|
46
|
+
shell. These checks do not establish a hosted rollout
|
|
47
|
+
([ADR 0017](../adr/api/0017-hosted-request-identity.md)).
|
|
48
|
+
|
|
33
49
|
## Local CLI workflow
|
|
34
50
|
|
|
35
51
|
Focused manual checks for ADR 0011:
|
|
@@ -31,7 +31,8 @@ Shared deployments use `local_mode_available: false`; the developer checkout use
|
|
|
31
31
|
`true`. The launcher always runs Local; see [Local only](local-runtime.md#local-only).
|
|
32
32
|
|
|
33
33
|
Configure the API’s SDK session for ordinary platform Secret access and supply
|
|
34
|
-
|
|
34
|
+
the platform's caller-assertion trust configuration, which the SDK request identity
|
|
35
|
+
reads ([ADR 0017](../adr/api/0017-hosted-request-identity.md)). Use the SDK's own configuration contract;
|
|
35
36
|
MetaTables passes no user-supplied issuer, key URL, or target scope to verification.
|
|
36
37
|
The [SDK capability check](../client/installation-and-connection.md) establishes
|
|
37
38
|
interface availability, not deployment credentials or network readiness.
|
|
@@ -31,8 +31,11 @@ deployment; resolve duplicates within it. Hosted clients leave
|
|
|
31
31
|
`METATABLES_API_URL` unset; that variable accepts only loopback development URLs.
|
|
32
32
|
|
|
33
33
|
Serve `metatables.api.app.main:app` with hosted execution and one runtime DataSource. Start one
|
|
34
|
-
worker per runtime instance, configure the ordinary SDK session and
|
|
35
|
-
|
|
34
|
+
worker per runtime instance, configure the ordinary SDK session and the platform's
|
|
35
|
+
caller-assertion trust configuration (`MAINSEQUENCE_CALLER_AUTH_MODE=assertion`,
|
|
36
|
+
`MAINSEQUENCE_CALLER_ASSERTION_ISSUER`, `MAINSEQUENCE_CALLER_ASSERTION_JWKS_URL`,
|
|
37
|
+
`APP_NAME` and `MAINSEQUENCE_ORGANIZATION_ENVIRONMENT_UID`), and set
|
|
38
|
+
`local_mode_available: false` in `configuration.yaml` on shared deployments.
|
|
36
39
|
|
|
37
40
|
```bash
|
|
38
41
|
uvicorn metatables.api.app.main:app --host 0.0.0.0 --port 18473
|
|
@@ -42,6 +45,13 @@ The ingress must provide signed caller assertions. Unsigned User UIDs and the
|
|
|
42
45
|
runtime's own workload token cannot identify the human requesting a table
|
|
43
46
|
operation. The SDK verifies caller proof; MetaTables applies local resource policy.
|
|
44
47
|
|
|
48
|
+
The app installs the SDK request identity when it is created, and the platform's
|
|
49
|
+
FastAPI launcher checks that declaration before it serves a revision
|
|
50
|
+
([ADR 0017](../adr/api/0017-hosted-request-identity.md)). Releases before 0.1.21 do
|
|
51
|
+
not install it, so the launcher refuses their new hosted revisions. Without the
|
|
52
|
+
trust configuration the app installs nothing and admits no caller; an incomplete
|
|
53
|
+
configuration stops startup.
|
|
54
|
+
|
|
45
55
|
## Declare the runtime database
|
|
46
56
|
|
|
47
57
|
The deployment configuration is `src/metatables/api/metatables/configuration.yaml`,
|
{mainsequence_metatable-0.1.20.dev32 → mainsequence_metatable-0.1.21.dev33}/docs/security/index.md
RENAMED
|
@@ -97,9 +97,11 @@ choice, not an authorization mechanism.
|
|
|
97
97
|
|
|
98
98
|
The platform User response must supply `is_organization_admin` and
|
|
99
99
|
`active_team_uids`; use the compatible published SDK prerequisite described in
|
|
100
|
-
[installation](../client/installation-and-connection.md).
|
|
101
|
-
the existing signed caller assertion
|
|
102
|
-
|
|
100
|
+
[installation](../client/installation-and-connection.md). In hosted mode the SDK
|
|
101
|
+
request identity verifies the existing signed caller assertion; admission takes that
|
|
102
|
+
User from `User.get_logged_user()` and obtains the User's facts through the SDK User
|
|
103
|
+
detail operation ([ADR 0017](../adr/api/0017-hosted-request-identity.md)). Local
|
|
104
|
+
admission resolves facts for the running SDK user.
|
|
103
105
|
The deployment's existing User-directory access must permit that lookup.
|
|
104
106
|
|
|
105
107
|
The API caches successful User facts for one hour per caller and runtime. Startup
|
|
@@ -83,3 +83,4 @@ nav:
|
|
|
83
83
|
- "0014: System migrations in the deployment workflow": adr/api/0014-main-sequence-release-jobs-and-production-migrations.md
|
|
84
84
|
- "0015: TimescaleDB compression and retention policies": adr/api/0015-timescale-compression-and-retention-policies.md
|
|
85
85
|
- "0016: Impact pre-flight": adr/api/0016-impact-preflight.md
|
|
86
|
+
- "0017: Hosted request identity": adr/api/0017-hosted-request-identity.md
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mainsequence-metatable"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.21.dev33"
|
|
8
8
|
description = "Main Sequence MetaTables Python client and standalone API"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -20,6 +20,7 @@ SDK_MODULES = frozenset({
|
|
|
20
20
|
'mainsequence.client.models_user', 'mainsequence.client.utils', 'mainsequence.client.value_sets',
|
|
21
21
|
'mainsequence.cli.config', 'mainsequence.code_repository_context',
|
|
22
22
|
'mainsequence.instrumentation', 'mainsequence.logconf', 'mainsequence.server.caller_assertions',
|
|
23
|
+
'mainsequence.server.fastapi',
|
|
23
24
|
})
|
|
24
25
|
SHARED_MODULES = frozenset({'metatables.local_connection', 'metatables.local_files', 'metatables.sdk_compat', 'metatables.update_configuration_contract',
|
|
25
26
|
'metatables.transfer_contract', 'metatables.runtime_contract', 'metatables.log_contract', 'metatables.local_run_logs',
|
|
@@ -31,6 +31,7 @@ docs/adr/api/0013-application-owned-migrations.md
|
|
|
31
31
|
docs/adr/api/0014-main-sequence-release-jobs-and-production-migrations.md
|
|
32
32
|
docs/adr/api/0015-timescale-compression-and-retention-policies.md
|
|
33
33
|
docs/adr/api/0016-impact-preflight.md
|
|
34
|
+
docs/adr/api/0017-hosted-request-identity.md
|
|
34
35
|
docs/adr/client/0003-api-endpoint-resolution.md
|
|
35
36
|
docs/adr/client/0011-cli-local-development-with-managed-admin.md
|
|
36
37
|
docs/api/authentication-and-errors.md
|
|
@@ -183,7 +184,6 @@ src/metatables/api/app/source_passwords.py
|
|
|
183
184
|
src/metatables/api/app/transfer.py
|
|
184
185
|
src/metatables/api/app/auth/__init__.py
|
|
185
186
|
src/metatables/api/app/auth/boundary.py
|
|
186
|
-
src/metatables/api/app/auth/caller_assertions.py
|
|
187
187
|
src/metatables/api/app/auth/local_actor.py
|
|
188
188
|
src/metatables/api/app/routes/__init__.py
|
|
189
189
|
src/metatables/api/app/routes/column_search.py
|
|
@@ -412,12 +412,12 @@ src/metatables/updaters/updaters.py
|
|
|
412
412
|
src/metatables/updaters/utils.py
|
|
413
413
|
tests/conftest.py
|
|
414
414
|
tests/auth/test_bootstrap_failure_cause.py
|
|
415
|
-
tests/auth/test_caller_assertions.py
|
|
416
415
|
tests/auth/test_data_source_identity.py
|
|
417
416
|
tests/auth/test_development_client.py
|
|
418
417
|
tests/auth/test_hosted_environment_target.py
|
|
419
418
|
tests/auth/test_local_mode.py
|
|
420
419
|
tests/auth/test_platform_fact_cache.py
|
|
420
|
+
tests/auth/test_request_identity.py
|
|
421
421
|
tests/auth/test_runtime_bootstrap.py
|
|
422
422
|
tests/auth/test_runtime_database.py
|
|
423
423
|
tests/auth/test_runtime_scaffold.py
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Shared request admission for hosted
|
|
1
|
+
"""Shared request admission for hosted callers and local SDK identity."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -7,12 +7,6 @@ from uuid import UUID
|
|
|
7
7
|
|
|
8
8
|
from fastapi import Depends, HTTPException, Request
|
|
9
9
|
|
|
10
|
-
from metatables.api.app.auth.caller_assertions import (
|
|
11
|
-
ASSERTION_HEADER,
|
|
12
|
-
CallerAssertionUnavailable,
|
|
13
|
-
InvalidCallerAssertion,
|
|
14
|
-
configured_verifier,
|
|
15
|
-
)
|
|
16
10
|
from metatables.api.app.runtime import RuntimeState
|
|
17
11
|
from metatables.api.backend.domain.permission_rules import TrustedActorFacts
|
|
18
12
|
|
|
@@ -43,25 +37,32 @@ def admit_request(request: Request) -> AdmittedCaller:
|
|
|
43
37
|
user_uid=state.identity.user_uid, active_team_uids=teams, is_admin=admin,
|
|
44
38
|
environment_uid=UUID(environment_uid) if environment_uid else None,
|
|
45
39
|
)
|
|
46
|
-
|
|
47
|
-
if assertion is None:
|
|
48
|
-
raise HTTPException(status_code=401, detail="Caller assertion is required.")
|
|
49
|
-
try:
|
|
50
|
-
caller = configured_verifier().verify(assertion)
|
|
51
|
-
except InvalidCallerAssertion as exc:
|
|
52
|
-
raise HTTPException(status_code=401, detail="Invalid caller assertion.") from exc
|
|
53
|
-
except CallerAssertionUnavailable as exc:
|
|
54
|
-
raise HTTPException(status_code=503, detail="Caller authentication is unavailable.") from exc
|
|
55
|
-
user_uid = UUID(caller.user_uid)
|
|
40
|
+
user_uid = logged_user_uid()
|
|
56
41
|
teams, admin = state.actor_facts_cache.get(
|
|
57
42
|
(False, user_uid), lambda: sdk_actor_facts(user_uid, local=False),
|
|
58
43
|
)
|
|
44
|
+
# The verified assertion's target, recorded by the SDK request identity.
|
|
45
|
+
environment_uid = getattr(request.state, "organization_environment_uid", None)
|
|
59
46
|
return AdmittedCaller(
|
|
60
|
-
user_uid=
|
|
61
|
-
environment_uid=UUID(
|
|
47
|
+
user_uid=user_uid, active_team_uids=teams, is_admin=admin,
|
|
48
|
+
environment_uid=UUID(environment_uid) if environment_uid else None,
|
|
62
49
|
)
|
|
63
50
|
|
|
64
51
|
|
|
52
|
+
def logged_user_uid() -> UUID:
|
|
53
|
+
"""Return the caller that the SDK request identity verified for this request.
|
|
54
|
+
|
|
55
|
+
The SDK verifies the platform-signed caller assertion once, before any route
|
|
56
|
+
runs, and answers missing or invalid proof itself. When no caller is bound, for
|
|
57
|
+
example on a hosted API started without the platform's trust configuration,
|
|
58
|
+
admission fails; there is no header or process-account fallback.
|
|
59
|
+
"""
|
|
60
|
+
from mainsequence.client import RequestIdentityError, User
|
|
61
|
+
try:
|
|
62
|
+
return UUID(User.get_logged_user().uid)
|
|
63
|
+
except RequestIdentityError:
|
|
64
|
+
raise HTTPException(status_code=401, detail="Caller assertion is required.") from None
|
|
65
|
+
|
|
65
66
|
|
|
66
67
|
def platform_facts(identity):
|
|
67
68
|
"""Consume facts supplied by SDK User responses for the already verified caller."""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""MetaTables API application and route composition."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
from contextlib import asynccontextmanager
|
|
4
5
|
from uuid import UUID
|
|
5
6
|
|
|
@@ -7,6 +8,7 @@ from fastapi import Depends, FastAPI, HTTPException, Request
|
|
|
7
8
|
from fastapi.exception_handlers import http_exception_handler
|
|
8
9
|
from fastapi.responses import JSONResponse
|
|
9
10
|
from fastapi.routing import APIRoute
|
|
11
|
+
from mainsequence.server.fastapi import install_request_identity
|
|
10
12
|
from sqlalchemy.orm import Session
|
|
11
13
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
|
12
14
|
|
|
@@ -100,6 +102,38 @@ def time_index_aliases(router):
|
|
|
100
102
|
|
|
101
103
|
from metatables.api.app.routes.update_crud import router as update_crud_router
|
|
102
104
|
|
|
105
|
+
# The platform projects caller-assertion trust configuration into every hosted
|
|
106
|
+
# FastAPI deployment. The SDK request identity and the platform launcher select
|
|
107
|
+
# their caller-authentication mode from these variables (ADR 0017).
|
|
108
|
+
PLATFORM_CALLER_AUTHENTICATION = (
|
|
109
|
+
"MAINSEQUENCE_CALLER_AUTH_MODE",
|
|
110
|
+
"APP_NAME",
|
|
111
|
+
"FASTAPI_PUBLIC_BASE_URL",
|
|
112
|
+
"MAINSEQUENCE_CALLER_ASSERTION_ISSUER",
|
|
113
|
+
"MAINSEQUENCE_CALLER_ASSERTION_JWKS_URL",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def install_hosted_request_identity(service: FastAPI, config: RuntimeConfig) -> None:
|
|
118
|
+
"""Install the SDK request identity once on the platform-served hosted API.
|
|
119
|
+
|
|
120
|
+
Local and developer runtimes admit requests through their loopback listener and
|
|
121
|
+
private launcher token, with the SDK user resolved at startup; they never install
|
|
122
|
+
it. The hosted API installs it when the platform's caller-authentication
|
|
123
|
+
configuration is present and accepts only signed caller assertions. Without that
|
|
124
|
+
configuration no caller is ever bound, so admission rejects every caller.
|
|
125
|
+
"""
|
|
126
|
+
if config.local_mode or config.developer_mode:
|
|
127
|
+
return
|
|
128
|
+
if not any(os.environ.get(name) for name in PLATFORM_CALLER_AUTHENTICATION):
|
|
129
|
+
return
|
|
130
|
+
install_request_identity(service)
|
|
131
|
+
if service.state.mainsequence_request_identity["mode"] != "assertion":
|
|
132
|
+
raise RuntimeError(
|
|
133
|
+
"The hosted MetaTables API accepts only platform caller assertions. "
|
|
134
|
+
"Use 'metatables serve --local' for local development."
|
|
135
|
+
)
|
|
136
|
+
|
|
103
137
|
|
|
104
138
|
def create_app(config: RuntimeConfig | None = None) -> FastAPI:
|
|
105
139
|
configure_logging()
|
|
@@ -223,7 +257,21 @@ def create_app(config: RuntimeConfig | None = None) -> FastAPI:
|
|
|
223
257
|
async def hello() -> dict[str, str]:
|
|
224
258
|
return {"message": "Hello, world!"}
|
|
225
259
|
|
|
260
|
+
# Installed last, its middleware is the outermost application middleware:
|
|
261
|
+
# callers are verified before local admission, transfer limits or any route.
|
|
262
|
+
install_hosted_request_identity(service, selected)
|
|
226
263
|
return service
|
|
227
264
|
|
|
228
265
|
|
|
229
|
-
|
|
266
|
+
def __getattr__(name: str) -> FastAPI:
|
|
267
|
+
"""Create the default app served as ``metatables.api.app.main:app`` on first use.
|
|
268
|
+
|
|
269
|
+
Importing the factory, as the local worker, the hosted entrypoint and the
|
|
270
|
+
reference scripts do, therefore builds no unused app and installs no request
|
|
271
|
+
identity in processes that never serve it.
|
|
272
|
+
"""
|
|
273
|
+
if name != "app":
|
|
274
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
275
|
+
service = create_app()
|
|
276
|
+
globals()["app"] = service
|
|
277
|
+
return service
|
|
@@ -21,10 +21,15 @@ def require_sdk_capabilities(*, server: bool = False) -> None:
|
|
|
21
21
|
from mainsequence.server.caller_assertions import CallerAssertionVerifier
|
|
22
22
|
if not callable(getattr(CallerAssertionVerifier, "from_environment", None)):
|
|
23
23
|
raise ImportError("CallerAssertionVerifier.from_environment is unavailable")
|
|
24
|
+
from mainsequence.client import RequestIdentityError
|
|
25
|
+
from mainsequence.server.fastapi import install_request_identity
|
|
26
|
+
if not (callable(install_request_identity) and issubclass(RequestIdentityError, Exception)
|
|
27
|
+
and callable(getattr(User, "get_logged_user", None))):
|
|
28
|
+
raise ImportError("SDK FastAPI request identity is unavailable")
|
|
24
29
|
except ImportError as exc:
|
|
25
30
|
raise ImportError(
|
|
26
31
|
"MetaTables requires a compatible mainsequence SDK with platform Secrets "
|
|
27
|
-
"and
|
|
32
|
+
"and FastAPI request identity. Install a compatible SDK artifact or the documented local checkout; "
|
|
28
33
|
"see docs/client/installation-and-connection.md."
|
|
29
34
|
) from exc
|
|
30
35
|
|
|
@@ -15,8 +15,7 @@ from sqlalchemy import create_engine
|
|
|
15
15
|
from sqlalchemy.orm import Session, sessionmaker
|
|
16
16
|
|
|
17
17
|
from metatables.api.app import runtime
|
|
18
|
-
from metatables.api.app.auth import
|
|
19
|
-
from metatables.api.app.auth.caller_assertions import AuthenticatedCaller, InvalidCallerAssertion
|
|
18
|
+
from metatables.api.app.auth import local_actor
|
|
20
19
|
from metatables.api.app.main import create_app
|
|
21
20
|
from metatables.api.app.runtime import LocalIdentity, RuntimeConfig
|
|
22
21
|
from metatables.api.backend.domain.catalog_rules import TableRegistration
|
|
@@ -296,19 +295,9 @@ def test_local_protected_route_needs_no_seed_and_keeps_current_grant_checks(monk
|
|
|
296
295
|
engine.dispose()
|
|
297
296
|
|
|
298
297
|
|
|
299
|
-
def test_hosted_verified_caller_needs_no_membership_or_protection_row(monkeypatch, tmp_path
|
|
298
|
+
def test_hosted_verified_caller_needs_no_membership_or_protection_row(monkeypatch, tmp_path,
|
|
299
|
+
platform_caller_assertions):
|
|
300
300
|
user_uid = uuid4()
|
|
301
|
-
|
|
302
|
-
class Verifier:
|
|
303
|
-
def verify(self, assertion):
|
|
304
|
-
return SimpleNamespace(
|
|
305
|
-
user_uid=str(user_uid),
|
|
306
|
-
release_uid=str(uuid4()),
|
|
307
|
-
issued_at=1,
|
|
308
|
-
expires_at=2,
|
|
309
|
-
)
|
|
310
|
-
|
|
311
|
-
monkeypatch.setattr(boundary, "configured_verifier", lambda: Verifier())
|
|
312
301
|
monkeypatch.setattr(runtime, "resolve_sdk_identity", lambda: pytest.fail("SDK called"))
|
|
313
302
|
engine = create_engine(f"sqlite+pysqlite:///{tmp_path / 'hosted.sqlite'}")
|
|
314
303
|
Base.metadata.create_all(engine)
|
|
@@ -319,7 +308,7 @@ def test_hosted_verified_caller_needs_no_membership_or_protection_row(monkeypatc
|
|
|
319
308
|
|
|
320
309
|
from metatables.api.backend.integrations.runtime_binding import RuntimeStorageBinding
|
|
321
310
|
client.app.state.runtime = replace(client.app.state.runtime, bootstrap=None, binding=RuntimeStorageBinding("postgresql://fixture/catalog"))
|
|
322
|
-
headers =
|
|
311
|
+
headers = platform_caller_assertions.headers(user_uid)
|
|
323
312
|
filters = { "limit": 10}
|
|
324
313
|
assert client.post("/meta-tables/filter/", json=filters, headers=headers).status_code == 200
|
|
325
314
|
with Session(engine) as session, session.begin():
|
|
@@ -374,36 +363,62 @@ def test_local_rejects_non_loopback_peer_even_with_token(monkeypatch, make_local
|
|
|
374
363
|
def test_hosted_does_not_use_local_sdk_or_accept_unsigned_uid(monkeypatch):
|
|
375
364
|
monkeypatch.setattr(runtime, "resolve_sdk_identity", lambda: pytest.fail("SDK called"))
|
|
376
365
|
with TestClient(create_app(RuntimeConfig.from_environment({}))) as client:
|
|
366
|
+
# Without the platform's trust configuration no caller is ever bound.
|
|
367
|
+
assert getattr(client.app.state, "mainsequence_request_identity", None) is None
|
|
377
368
|
assert client.get("/time-index-table-update-constants", headers={"X-User-UID": str(uuid4())}).status_code == 401
|
|
378
369
|
|
|
379
370
|
|
|
380
|
-
def
|
|
371
|
+
def test_hosted_route_uses_sdk_identity_without_local_fallback(monkeypatch, platform_caller_assertions):
|
|
381
372
|
user_uid = uuid4()
|
|
382
|
-
|
|
383
|
-
class Verifier:
|
|
384
|
-
def verify(self, assertion):
|
|
385
|
-
if assertion != "verified":
|
|
386
|
-
raise InvalidCallerAssertion("invalid")
|
|
387
|
-
return SimpleNamespace(
|
|
388
|
-
user_uid=str(user_uid),
|
|
389
|
-
release_uid=str(uuid4()),
|
|
390
|
-
issued_at=1,
|
|
391
|
-
expires_at=2,
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
monkeypatch.setattr(boundary, "configured_verifier", lambda: Verifier())
|
|
395
373
|
monkeypatch.setattr(runtime, "resolve_sdk_identity", lambda: pytest.fail("SDK called"))
|
|
396
374
|
with TestClient(create_app(RuntimeConfig.from_environment({}))) as client:
|
|
397
375
|
assert client.get(
|
|
398
376
|
"/time-index-table-update-constants",
|
|
399
|
-
headers={
|
|
377
|
+
headers={platform_caller_assertions.header: "invalid"},
|
|
400
378
|
).status_code == 401
|
|
401
379
|
assert client.get(
|
|
402
380
|
"/time-index-table-update-constants",
|
|
403
|
-
headers={"X-
|
|
381
|
+
headers={"X-User-UID": str(user_uid), "X-MetaTables-Local-Token": TOKEN},
|
|
382
|
+
).status_code == 401
|
|
383
|
+
assert client.get(
|
|
384
|
+
"/time-index-table-update-constants",
|
|
385
|
+
headers=platform_caller_assertions.headers(user_uid),
|
|
404
386
|
).status_code == 200
|
|
405
387
|
|
|
406
388
|
|
|
389
|
+
def test_local_runtime_never_installs_request_identity(monkeypatch, make_local_identity,
|
|
390
|
+
platform_caller_assertions):
|
|
391
|
+
# Even a shell that carries a hosted deployment's variables keeps local admission.
|
|
392
|
+
monkeypatch.setattr(runtime, "resolve_sdk_identity", lambda: make_local_identity(uuid4(), uuid4()))
|
|
393
|
+
with local_client(local_config()) as client:
|
|
394
|
+
assert getattr(client.app.state, "mainsequence_request_identity", None) is None
|
|
395
|
+
assert not [entry for entry in client.app.user_middleware
|
|
396
|
+
if entry.cls.__module__.startswith("mainsequence")]
|
|
397
|
+
assert client.get("/time-index-table-update-constants").status_code == 200
|
|
398
|
+
assert client.get(
|
|
399
|
+
"/time-index-table-update-constants",
|
|
400
|
+
headers=platform_caller_assertions.headers(uuid4()),
|
|
401
|
+
).status_code == 401 # Caller assertions are still rejected locally.
|
|
402
|
+
assert client.get(
|
|
403
|
+
"/time-index-table-update-constants", headers={"X-MetaTables-Local-Token": "bad"}
|
|
404
|
+
).status_code == 401
|
|
405
|
+
assert platform_caller_assertions.verified == []
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def test_sdk_bearer_mode_would_reject_every_local_launcher_request(monkeypatch, make_local_identity):
|
|
409
|
+
"""Why Local keeps its own admission: the SDK's local mode needs a Bearer token
|
|
410
|
+
on every request, and local clients send only the launcher's private token."""
|
|
411
|
+
from mainsequence.server.fastapi import install_request_identity
|
|
412
|
+
|
|
413
|
+
monkeypatch.setattr(runtime, "resolve_sdk_identity", lambda: make_local_identity(uuid4(), uuid4()))
|
|
414
|
+
app = create_app(local_config())
|
|
415
|
+
install_request_identity(app)
|
|
416
|
+
assert app.state.mainsequence_request_identity["mode"] == "local"
|
|
417
|
+
with TestClient(app, base_url=BASE_URL, client=("127.0.0.1", 52000),
|
|
418
|
+
headers={"X-MetaTables-Local-Token": TOKEN}) as client:
|
|
419
|
+
assert client.get("/time-index-table-update-constants").status_code == 401
|
|
420
|
+
|
|
421
|
+
|
|
407
422
|
def test_sdk_identity_comes_from_authenticated_user_and_git_source(monkeypatch):
|
|
408
423
|
from mainsequence import code_repository_context
|
|
409
424
|
from mainsequence.client.models_user import User
|