New Platform Acceptance Checklist
Use this checklist before opening a platform-support PR. It is deliberately concrete: platform breadth is only useful when the registry, docs, optional dependencies, compatibility rules, and tests move together.
First Decision
| Question | Required answer |
|---|---|
| Is this SQL, DataFrame, or dual-mode? | Pick one primary path; dual-mode still needs separate SQL and DataFrame checks. |
What is the support_status? | Use exactly one of stable, beta, experimental, repo_only, deprecated, document_only. |
| Is it runnable from a wheel? | If no, do not add it as a normal runtime platform. Use repo_only or document_only. |
| What dependency group enables it? | Add or reuse an optional extra; do not make base import require a platform SDK. |
| What is the blast radius? | List adapter files, registry metadata, docs, tests, SQL compatibility, and UAT/live scope. |
SQL Platform Checklist
- Add the adapter under
benchbox/platforms/or an existing platform family package. - Keep platform SDK imports lazy or guarded so
import benchboxremains cheap. - Add the platform’s canonical entry to
benchbox/core/platform_manifest.py, including one explicitsupport_status. The registry’s_OPTIONAL_ADAPTERSand_build_platform_metadata()paths are live pass-throughs and should not be treated as independent registration authorities. - Fill
capabilities:supports_sql,supports_dataframe,default_mode,platform_family,inherits_from,cost_class, and deployment modes when relevant. - Declare every deployment mode in the manifest with its class (
local,self-hosted, ormanaged) and exactly one platform default; the--platform name:modeselector is the only canonical spelling. - Name no canonical option
engine,mode,backend,runtime,executor, orwarehouse; list any reserved-word alias in the core deprecated-alias table with its removal release. - Record the factory-resolved deployment in result metadata as
platform.deployment.selectedwithselected_class, and cover each mode with an adapter test. - Declare compute when the platform bills a named compute object: add a manifest
capabilities.computeblock withresource_kind(warehouse,engine,workgroup,cluster,pool,applicationorservice),native_resource_keysandnative_size_keys. The core registerscompute_resourceandcompute_sizewith the native keys as deprecated aliases automatically; never register a canonical key namedengine,mode,backend,runtime,executororwarehouse. The adapter reads the canonical names first with native fallback, and results carry the canonical kind and size alongside legacy fields. - Declare gateways when the platform supports query routing through an intermediary: add a manifest
capabilities.gatewaysblock with{name: {routes_to: {engine_name: {class}}, requires_host: bool}}. The core registers the--gatewayCLI flag and typed connection options (gateway_host,gateway_portas an integer port,gateway_protocol,gateway_ca_bundle, and the booleansgateway_ocsp_fail_openandallow_insecure_gateway) with the other platform options. Every non-native gateway must require a host;nativeis accepted and recorded as no gateway. Until the adapter routes queries through the gateway, any other--gatewayvalue fails before work starts with “gateway routing is not implemented for <platform> yet”. A routed result recordsplatform.gatewaywithnameandrouted: true, sets the top-leveltpc_compliant: false, restricts per-queryexecution_enginetoroutes_totargets plusunknown, and observesmixedwhen queries differ.benchbox compareand MCPcompare_resultsrefuse runs that differ in deployment, requested engine or gateway (the CLI accepts--allow-heterogeneous-comparison), and regression baselines use only runs of the same variant. - Declare execution engines when the platform offers more than one way to execute a query: add a manifest
capabilities.execution_enginesblock with{name: {class, display_name, description, dependencies, selectable}}. The class comes from the closed core list (adaptive,in-memory,streaming,gpu,native-vectorized,standard,distributed,jit,delegated). Name each value with the platform’s own documented term when one exists, otherwise the class name; the same name must map to the same class on every platform (the vocabulary parity test enforces this).defaultis a reserved sentinel meaning “pass nothing” and is never declared. Platforms without engines omit the block and accept onlydefaultthrough the inheritedresolve_execution_enginehook; override the hook only to map native settings into a receipt, and fail closed on unsupported values. Never name a canonical optionengine,mode,backend,runtime,executororwarehouse; a reserved-word spelling survives only as a deprecated alias registered in the coreDEPRECATED_OPTION_ALIASEStable with its removal release. - Add
driver_packageandinstallation_command; dependency extras belong inpyproject.toml. - Add DDL/query compatibility rules or an explicit exemption in the SQL compatibility inventory when the adapter rewrites SQL or DDL.
- Add unit tests for adapter construction, SQL rendering/loading behavior, registry metadata, optional import failure behavior, and any deployment-mode routing.
- Add a platform guide under
docs/platforms/and update the comparison matrix only through registry-derived counts. - Define smoke/UAT scope: local Docker, cloud live, or explicit no-live justification.
DataFrame Platform Checklist
- Decide whether the platform belongs to the expression family, pandas family, Spark family, or a new family.
- Add adapter/context code under
benchbox/platforms/dataframe/unless an existing family file already owns the behavior. - Add the platform’s canonical entry to
benchbox/core/platform_manifest.py, including one explicitsupport_status. DataFrame-only platforms must havesupports_sql=False. The registry’s_OPTIONAL_ADAPTERSand_build_platform_metadata()paths are live pass-throughs and should not be treated as independent registration authorities. - Add the
-dfCLI path or confirm the existingadapter_factorymapping routes to the new adapter. - Declare execution engines when the platform offers more than one way to execute a query, following the same
manifest
capabilities.execution_enginesblock, closed class list, value-naming rule and reserved-word ban as SQL platforms above. The worked example ispolars-df, which declaresauto(adaptive),in-memoryandstreamingunder the platform’s own documented names. DataFrame adapters inheritresolve_execution_enginefrom the adapter base and map the resolved engine into their collect or compute call; unsupported values fail closed. - Add native DataFrame query implementations or document unsupported benchmarks with benchmark-gate rules.
- Add lazy availability checks and dependency extras; GPU or native-stack dependencies must not load during base import.
- Add unit tests for family behavior, adapter lifecycle, query execution primitives, and registry capability alignment.
- Add docs under
docs/platforms/using the-dfCLI name and compatibility caveats. - Validate against DuckDB SQL at SF=0.01 where the benchmark has parity expectations.
Documentation and Drift Checks
- README and platform matrix exact counts must match
PlatformRegistry.get_platform_count_summary(). - The public docs should describe support status separately from local dependency availability.
- New docs should link to setup, credentials, deployment modes, and benchmark limitations.
- If a platform is experimental or deprecated, the docs must say so on the first screen.
Expected Extension Cost
The minimum durable file count for a new platform is more than one adapter file.
Target for a straightforward SQL platform is 7-10 files:
- adapter or family module,
- registry metadata and optional adapter entry,
- optional dependency extra,
- SQL compatibility rule or explicit exemption,
- unit tests,
- platform docs,
- count/drift or acceptance checklist update when a claim changes.
Target for a straightforward DataFrame platform is 8-12 files because native query implementations and family tests usually add another surface.
Scaffold Helper
Print the expected file plan with manifest and adapter stubs before implementation:
uv run -- python scripts/new_platform_scaffold.py --name myengine --kind sqluv run -- python scripts/new_platform_scaffold.py --name myengine --kind dataframeA maintainer scaffold script prints the expected file plan for a new SQL or
DataFrame platform, a manifest entry for _PLATFORM_MANIFEST_JSON, and an
adapter stub. The manifest entry declares no execution engines and passes the
same manifest validator the package uses at import; the script exits with an
error if the key or an alias collides with an existing entry. The
adapter stub includes a resolve_execution_engine hook that returns the
platform-default receipt. --output-dir DIR also writes the entry as
manifest-entry.json and the stub under the file name the plan uses. The
helper is an architecture health aid, not a framework that owns platform
implementation.