Skip to content

Architecture

A clean-room, local emulator of a Databricks workspace — the adb-*.azuredatabricks.net REST host — built as a peer of fabric-emulator. Fabric consumes Databricks; this process is the workspace. Folding the workspace API into fabric-emulator would blur the trust boundary the way inlining Key Vault would have. The founding constraint is Doctrine.

The binary terminates the public workspace REST. Unmapped /api/* is 501 NOT_IMPLEMENTED, never a silent 200. Identity is PAT + this process’s own OIDC; Entra is an optional federated issuer, not a required STS — make run needs no entra-emulator.

State lives under DATABRICKS_DATA_DIR (./data by default): hashed PATs, the OIDC signing key, workspace files, DBFS bytes, Databricks-backed secrets, git credentials, the MLflow tracking store, the persisted TLS pair.

SurfaceHonest attachIf missing
Jobs / SQL / cluster sessionHTTP statement agent at DATABRICKS_SPARK_CONNECT_URL (Sail behind the family’s spark-agent). Warehouse SQL also arrives as HiveServer2 Thrift on /sql/1.0/endpoints/{id}.Fail naming the engine — never SUCCESS / RUNNING
Databricks ConnectSpark Connect gRPC at DATABRICKS_SPARK_CONNECT_GRPC_URL (Sail :50051)501 naming the missing gRPC URL
Unity Catalog CRUDUC OSS at DATABRICKS_UC_URL501 naming the missing sidecar
AKV-backed secretsLive vault at DATABRICKS_AKV_VAULT_HOSTEmulator dns_name refused by name
Federated JWTIssuer list in DATABRICKS_OIDC_ISSUERSOnly PAT and emulator OIDC work
Delta filesSail CREATE/INSERT on a shared volume; delta-rs confirms the log. Three-part names: Sail’s unity provider dials UC OSS on the Compose networkNo write witness — a Sail COUNT(*) is not one
Git Credentials / Reposgit on PATH clones into {dataDir}/workspace501 naming the missing binary
Cluster policiesEnforced on clusters/create; unknown attributes 501
Command ExecutionSame HTTP statement agent as Jobs / SQLFail naming DATABRICKS_SPARK_CONNECT_URL
MLflow Experiments / Model RegistryFile-backed store under {dataDir}/mlflow

There is no invented metastore, no DuckDB answering as Photon, no cluster VM that sleeps to RUNNING. A lookalike is a bug.

/api/2.0/mlflow/experiments, /runs, /registered-models, and /model-versions persist under data/mlflow/. The unmodified SDK creates an experiment, logs params and metrics, registers a model version, and transitions its stage. Artifact list, log-model, traces, and logged-models are 501 — this is a tracking store, not a model binary host. Model Serving stays a different row.

DATABRICKS_SPARK_CONNECT_URL is the HTTP statement agent Jobs/SQL/cluster create drive. DATABRICKS_SPARK_CONNECT_GRPC_URL is the Spark Connect gRPC origin Databricks Connect is reverse-proxied to. An HTTP agent is not Spark Connect. See Jobs and the Spark attach and Clusters and Connect.

Every green row in parity.md names a witness in witnesses.json. The kinds are not equal evidence: ci: is an unmodified client in CI; go: is this repo’s own client. The checker fails the build on a missing or dangling name. Testing lists what each CI job actually drives.