Silver Layer Setup - Orchestrator Skill
End-to-end workflow for creating production-grade Silver layer pipelines using Spark Declarative Pipelines (SDP, formerly Delta Live Tables/DLT) with Delta table-based data quality rules, quarantine patterns, streaming ingestion, and monitoring views.
Naming: Databricks rebranded DLT to Spark Declarative Pipelines (SDP) / Lakeflow Declarative Pipelines (LDP). The modern Python API is
from pyspark import pipelines as dp, and Databricks now recommendsdpoverimport dlt. Expectations are available indp(e.g.dp.expect_all_or_drop(...),dp.expect_all(...)) — the Lakeflow pipelines Python reference maps each@dlt.expect*decorator to adpequivalent. This skill still standardizes onimport dltfor the existing DQ-rules framework (dlt-expectations-patterns) because that framework's decorators are written againstdlt; the two APIs are behaviorally equivalent, so adpmigration is straightforward (swap the import and decorator prefix). New projects may usedatabricks pipelines initto scaffold an SDP Asset Bundle project.
Time Estimate: 3-4 hours for initial setup, 1 hour per additional table
What You'll Create:
dq_rulesDelta table - Centralized rules repository in Unity Catalogdq_rules_loader.py- Pure Python module to load rules at runtimesilver_*.py- SDP/DLT notebooks with expectations loaded from Delta tablesilver_pipeline.yml- Serverless SDP pipeline configuration- DQ monitoring views - Per-table metrics and referential integrity checks
Decision Tree
| Question | Action |
|---|---|
| Creating a Silver layer from scratch? | Use this skill - it orchestrates everything |
| Only need DLT expectations patterns? | Read silver/01-dlt-expectations-patterns/SKILL.md directly |
| Need advanced DQX validation? | Read silver/02-dqx-patterns/SKILL.md directly |
| Need Asset Bundle configuration? | Read skills/databricks-asset-bundles/SKILL.md directly |
| Need table properties reference? | Read common/databricks-table-properties/SKILL.md directly |
| Need pure Python import patterns? | Read common/databricks-python-imports/SKILL.md directly |
Mandatory Skill Dependencies
CRITICAL: Before generating ANY code for the Silver layer, you MUST read and follow the patterns in these common skills. Do NOT generate these patterns from memory.
| Phase | MUST Read Skill (use Read tool on SKILL.md) | What It Provides |
|---|---|---|
| All phases | skills/databricks-expert-agent |
Core extraction principle: extract names from source, never hardcode |
| Schema setup | common/schema-management-patterns |
CREATE SCHEMA DDL with governance metadata |
| DQ rules table | common/databricks-table-properties |
TBLPROPERTIES for the dq_rules metadata table |
| DQ rules table | common/unity-catalog-constraints |
PRIMARY KEY constraint syntax |
| Rules loader | common/databricks-python-imports |
Pure Python module patterns (NO notebook header) |
| DLT notebooks | common/databricks-table-properties |
Silver-layer TBLPROPERTIES (CDF, row tracking, auto-optimize) |
| Pipeline config | skills/databricks-asset-bundles |
DLT pipeline YAML, job YAML, serverless config, multi-user user_prefix pattern |
| Pipeline config | common/naming-tagging-standards |
Enterprise naming, COMMENTs, tags, PII classifications for every DDL and resource |
| Deployment (if user-triggered) | common/databricks-autonomous-operations |
Deploy → Poll → Diagnose → Fix → Redeploy loop when jobs/pipelines fail |
NEVER do these without FIRST reading the corresponding skill:
- NEVER write
table_properties={...}without readingdatabricks-table-properties - NEVER write Python import patterns without reading
databricks-python-imports - NEVER write Asset Bundle YAML without reading
databricks-asset-bundles - NEVER write
CREATE SCHEMAwithout readingschema-management-patterns - NEVER define PK/FK constraints without reading
unity-catalog-constraints - NEVER skip a
references/*.mdfile when the SKILL.md links to it withSee: references/... - NEVER skip the requirements template in Phase 1 — it forces structured design decisions
🔴 CRITICAL — Follow
See: references/...links. When a SKILL.md (or this orchestrator) saysSee: references/xxx.md for complete pattern, you MUST Read that reference file. The SKILL.md is a summary; thereferences/*.mdfile contains the complete, production-ready pattern. Skipping references means generating from memory rather than from the specification.For Silver specifically, these are the references most often skipped — read ALL of them during their relevant phase:
Reference Phase Why silver/00-silver-layer-setup/assets/templates/requirements-template.mdPhase 1 Forces Bronze→Silver mapping, DQ strategy, quarantine decisions before any code silver/01-dlt-expectations-patterns/references/expectation-patterns.mdPhase 2/4 Complete DQ rules table DDL, loader implementation, population examples silver/01-dlt-expectations-patterns/references/quarantine-patterns.mdPhase 4 Complete quarantine table implementation with diagnostic columns silver/00-silver-layer-setup/references/silver-table-patterns.mdPhase 4 DLT table templates, get_bronze_table()helper, derived-field patternssilver/00-silver-layer-setup/references/monitoring-patterns.mdPhase 5 DQ monitoring views, referential integrity, data freshness silver/00-silver-layer-setup/references/pipeline-configuration.mdPhase 6 Silver-specific DLT pipeline YAML + DQ setup job YAML
🔴 Non-Negotiable Defaults (Applied to EVERY Silver Table and Pipeline)
These defaults are ALWAYS applied. There are NO exceptions, NO overrides, NO alternative options.
| Default | Value | Applied Where | NEVER Do This Instead |
|---|---|---|---|
| Serverless | serverless: true |
Pipeline YAML | ❌ NEVER set serverless: false or define clusters: |
| Auto Liquid Clustering | cluster_by_auto=True |
Every @dlt.table() |
❌ NEVER use cluster_by=["col1", "col2"] or partition_cols= |
| Edition | edition: ADVANCED |
Pipeline YAML | ❌ NEVER use CORE or PRO (expectations require ADVANCED) |
| Photon | photon: true |
Pipeline YAML | ❌ NEVER set photon: false |
| Row Tracking | "delta.enableRowTracking": "true" |
Every table's table_properties |
❌ NEVER omit (breaks downstream MV refresh) |
| Change Data Feed | "delta.enableChangeDataFeed": "true" |
Every table's table_properties |
❌ NEVER omit (required for incremental propagation) |
# ✅ CORRECT: Every @dlt.table() MUST include these
@dlt.table(
name="silver_anything",
table_properties={
"delta.enableChangeDataFeed": "true",
"delta.enableRowTracking": "true",
# ... other properties from databricks-table-properties
},
cluster_by_auto=True # 🔴 MANDATORY on every table, including monitoring views
)
# ✅ CORRECT: Pipeline YAML MUST include these
serverless: true # 🔴 MANDATORY - no classic clusters
photon: true # 🔴 MANDATORY - vectorized execution
edition: ADVANCED # 🔴 MANDATORY - required for expectations
Silver-Domain Dependencies
| Skill | Requirement | What It Provides |
|---|---|---|
silver/01-dlt-expectations-patterns |
MUST read | DQ rules table DDL, rules loader cache pattern, DLT decorators, quarantine generation, runtime rule updates |
silver/02-dqx-patterns |
Optional | Read only when user needs richer diagnostics than DLT expectations, or pre-merge validation |
Core Philosophy: Schema Cloning
The Silver layer should essentially clone the source Bronze schema with minimal transformations:
- Same column names as Bronze (no complex renaming)
- Same data types (minimal type conversions)
- Same grain (no aggregation - that's for Gold)
- Add data quality rules (the main value-add)
- Add derived flags (business indicators like
is_return,is_out_of_stock) - Add business keys (SHA256 hashes for tracking)
- Add timestamps (
processed_timestamp)
What NOT to do in Silver:
- No major schema restructuring
- No aggregations (save for Gold)
- No complex business logic (simple flags only)
- No joining across tables (dimension lookups in Gold)
Why: Silver is the validated copy of source data. Gold handles complex transformations. This keeps Silver focused on data quality and makes troubleshooting easier (column names match source).
Python API: this skill standardizes on import dlt (dp is the recommended forward path)
Databricks recommends the modern dp API (from pyspark import pipelines as dp) and it fully supports expectations. This skill and its DQ-rules framework (dlt-expectations-patterns) are currently written against import dlt, so use import dlt here to stay consistent with the framework's decorators. The dp equivalents are drop-in — migrating is a mechanical swap of the import and decorator prefix.
# ✅ CURRENT STANDARD for this skill: legacy `dlt` API (matches the DQ-rules framework)
import dlt
from dq_rules_loader import get_critical_rules_for_table
@dlt.table(name="silver_transactions", cluster_by_auto=True)
@dlt.expect_all_or_drop(get_critical_rules_for_table("silver_transactions"))
def silver_transactions():
return dlt.read_stream(get_bronze_table("bronze_transactions"))
# ✅ RECOMMENDED forward path: modern `dp` API (expectations supported — dp.expect_all_or_drop)
from pyspark import pipelines as dp
from dq_rules_loader import get_critical_rules_for_table
@dp.table(name="silver_transactions", cluster_by_auto=True)
@dp.expect_all_or_drop(get_critical_rules_for_table("silver_transactions"))
def silver_transactions():
return spark.readStream.table("bronze_transactions")
Which to use? Databricks documents dp as the recommended API and both @dp.expect_all_or_drop() and @dp.expect_all() exist. We keep import dlt as this skill's standard only so the rules loader and decorators stay uniform across the framework — not because dp lacks expectations. To migrate: change import dlt → from pyspark import pipelines as dp, @dlt. → @dp., and dlt.read_stream(x) → spark.readStream.table(x). See the Lakeflow pipelines Python reference for the full decorator mapping.
File Structure
src/{project}_silver/
├── setup_dq_rules_table.py # Databricks notebook: Create and populate DQ rules Delta table
├── dq_rules_loader.py # Pure Python (NO notebook header): Load rules from Delta table
├── silver_dimensions.py # DLT notebook: Dimension tables (stores, products, etc.)
├── silver_transactions.py # DLT notebook: Fact table with quarantine
├── silver_inventory.py # DLT notebook: Additional fact tables (if applicable)
└── data_quality_monitoring.py # DLT notebook: DQ monitoring views
Critical Files:
dq_rules_loader.pymust be pure Python (NO# Databricks notebook sourceheader)- Run
silver_dq_setup_jobBEFORE deploying DLT pipeline
Working Memory Management
This orchestrator spans 6 phases (deployment and Phase 7 are user-triggered). To maintain coherence without context pollution:
After each phase, persist a brief summary note capturing:
- Phase 1 output: Schema names (catalog, silver_schema), table list, DQ rules strategy decision
- Phase 2 output: DQ rules table path, count of rules defined, rule severity distribution
- Phase 3 output:
dq_rules_loader.pypath, confirmation it is pure Python (no notebook header) - Phase 4 output: DLT notebook paths per table, expectation counts, SCD handling decisions
- Phase 5 output: Monitoring view paths, metric definitions
- Phase 6 output: Pipeline YAML path, job YAML path,
databricks.ymlsync status - Phase 7 output (if user-triggered): Anomaly detection config, schema monitoring status
What to keep in working memory: Only the current phase's context, the table list from Phase 1, and the previous phase's summary note. Discard intermediate outputs (full DDL strings, DQ rule DataFrames, raw DLT notebook contents) — they are on disk and reproducible.
Critical file note: dq_rules_loader.py must be pure Python (NO # Databricks notebook source header). Carry this constraint through all phases.
Phased Implementation Workflow
Phase 1: Requirements & Schema Setup (30 min)
Pre-Condition - MUST read these skills first:
- Read
skills/databricks-expert-agent/SKILL.md- Apply extraction principle throughout - Read
common/schema-management-patterns/SKILL.md- Use for Silver schema DDL
Steps:
MUST Read AND fill
assets/templates/requirements-template.mdbefore writing any code:- Map Bronze tables to Silver tables
- Define DQ rules per entity (critical vs warning)
- Identify quarantine candidates
- Skipping this step consistently leads to incomplete DQ coverage and ad-hoc quarantine patterns
Create Silver schema using pattern from
schema-management-patternsVerify Bronze tables exist AND pin each table's column inventory — run SQL, do NOT infer from local files:
databricks api post /api/2.0/sql/statements -p $PROFILE --json '{ "warehouse_id": "<WAREHOUSE_ID>", "catalog": "<CATALOG>", "statement": "SHOW TABLES IN <CATALOG>.<BRONZE_SCHEMA>", "wait_timeout": "30s" }'If the Bronze schema doesn't exist or has zero tables, STOP and report — the Bronze layer must be completed first. Reading a clone script or inferring from the schema CSV is NOT runtime verification.
Then, for EVERY Bronze table you will read, run
DESCRIBE TABLE <CATALOG>.<BRONZE_SCHEMA>.<table>and capture the column names into a{table: [columns]}map held in working memory (the pinned column inventory). Every DQ rule'sconstraint_sql, every Silver column reference, and everyget_bronze_table()column authored in Phases 2-4 MUST use a name from this pinned inventory — a reference to a column absent from the liveDESCRIBEis a hard error, not a "close enough" guess. PRD/CSV names (e.g.price,latitude) routinely differ from live prefixed names (e.g.base_price,property_latitude); pinning the inventory first prevents authoring rules against names that do not exist.
Phase 2: DQ Rules Table Setup (30 min)
Pre-Condition - MUST read these skills first:
- Read
silver/01-dlt-expectations-patterns/SKILL.md- Use for DQ rules table DDL and population - Read
common/databricks-table-properties/SKILL.md- Apply metadata table TBLPROPERTIES - Read
common/unity-catalog-constraints/SKILL.md- Apply PK constraint on (table_name, rule_name)
Steps:
- Create
setup_dq_rules_table.pynotebook - Define DQ rules table DDL (schema from
dlt-expectations-patterns) - Apply TBLPROPERTIES from
databricks-table-properties - Apply PK constraint:
CONSTRAINT pk_dq_rules PRIMARY KEY (table_name, rule_name) NOT ENFORCED - Populate rules using the requirements from Phase 1
- Verify file created:
setup_dq_rules_table.pyis ready for deployment (deployment is user-triggered)
Phase 3: Rules Loader Module (15 min)
Pre-Condition - MUST read these skills first:
- Read
common/databricks-python-imports/SKILL.md- CRITICAL: loader must be pure Python - Read
silver/01-dlt-expectations-patterns/SKILL.md- Use cache pattern withtoPandas()
Steps:
- Create
dq_rules_loader.pyas pure Python file (NO notebook header!) - Implement functions:
get_critical_rules_for_table(),get_warning_rules_for_table(),get_quarantine_condition() - Use module-level cache pattern with
toPandas()(NOT.collect()) fromdlt-expectations-patterns - Test import:
from dq_rules_loader import get_critical_rules_for_table
Phase 4: DLT Notebooks - Silver Tables (1-2 hours)
Pre-Condition - MUST read these skills first:
- Read
common/databricks-table-properties/SKILL.md- Extract Silver TBLPROPERTIES - Read
silver/01-dlt-expectations-patterns/SKILL.md- Use decorator patterns - (Optional) Read
silver/02-dqx-patterns/SKILL.md- Only if user needs hybrid DQX+DLT
Steps:
- Create DLT notebooks using patterns from
references/silver-table-patterns.md - Include
get_bronze_table()helper in every notebook (see references/) - For each table:
- Apply Silver TBLPROPERTIES from
databricks-table-properties - Apply
@dlt.expect_all_or_drop(get_critical_rules_for_table(...))decorator - Apply
@dlt.expect_all(get_warning_rules_for_table(...))decorator - Clone Bronze schema with minimal transformations
- Add derived flags, business keys,
processed_timestamp - Set
cluster_by_auto=True(NEVER specify columns manually)
- Apply Silver TBLPROPERTIES from
- For high-volume fact tables: create quarantine table using
get_quarantine_condition()
See: references/silver-table-patterns.md for complete templates
Phase 5: Monitoring Views (30 min)
No external skill dependencies - use references/monitoring-patterns.md
Steps:
- Create
data_quality_monitoring.pyDLT notebook - Add per-table DQ metrics views (record counts, pass/fail rates)
- Add referential integrity checks (orphaned records between fact and dimension)
- Add data freshness monitoring
See: references/monitoring-patterns.md for complete patterns
Phase 6: Pipeline & Job Configuration (15 min)
Pre-Condition - MUST read these skills first:
- Read
skills/databricks-asset-bundles/SKILL.md- DLT pipeline YAML, job YAML patterns
Steps:
- Create
resources/silver_dlt_pipeline.ymlusing patterns fromdatabricks-asset-bundles - Create
resources/silver_dq_setup_job.ymlfor the DQ rules setup job - Set DLT Direct Publishing Mode:
catalog+schemafields (NOTtarget) - Pass configuration:
catalog,bronze_schema,silver_schema - Set:
serverless: true,edition: ADVANCED,photon: true - Multi-user safety: In shared workspaces, include
${var.user_prefix}in every pipeline/jobname:field. Seeskills/databricks-asset-bundles→ "Shared Workspace Naming" section for the exact pattern. Without it, the second user to deploy hits apipeline name is already usederror — and--forcedoes NOT fix it (seeskills/databricks-asset-bundles/references/common-errors.mdError 17).
See: references/pipeline-configuration.md for Silver-specific examples
🛑 STOP — Artifact Creation Complete
Phases 1–6 are complete. All files (DQ rules table script, rules loader, DLT notebooks, monitoring views, pipeline/job YAMLs) have been created. Do NOT proceed to deployment or Phase 7 unless the user explicitly requests it.
Contract test before any deploy (read-only). Before reporting completion, validate the authored files against the live schema so column/DDL bugs surface now, not in a failed job run: (1) dry-import dq_rules_loader.py — it must import cleanly and stay pure Python (no notebook header); (2) for every rule, run its constraint_sql read-only as SELECT <constraint_sql> FROM <catalog>.<bronze_schema>.<table> LIMIT 1 and confirm each referenced column is in the Phase 1 pinned column inventory — an UNRESOLVED_COLUMN/parse error here is the exact failure that otherwise only appears as a failed DQ-setup/pipeline run; (3) confirm the loader's expected dq_rules row shape matches setup_dq_rules_table.py's INSERT columns, and that no DDL uses a DEFAULT clause or an invented column. Fix and re-run until clean before deploying.
Report what was created and ask the user if they want to deploy and run.
Deployment Order (USER-TRIGGERED ONLY — do not auto-execute):
Client note: IDE runs these in a terminal; Genie Code runs the
databricks bundle …commands viarunDatabricksCli. Generated bundle files anchor todp_bundle_root(=<artifact_root>/<use_case_slug>_dab), and on Genie Code that folder is also thebundle deploypage-context root — be on thedp_bundle_rootpage to deploy. The pipeline/job is the only mechanism that creates Silver tables; never run the DDL/ingest directly. Seeskills/genie-code-environment.
# 1. Deploy everything
databricks bundle deploy -t dev
# 2. Run DQ rules setup FIRST (creates dq_rules table)
databricks bundle run silver_dq_setup_job -t dev
# 3. Verify rules table exists (NOTE: raw `databricks api` calls do NOT inherit
# the profile from databricks.yml — pass `-p <profile>` explicitly. See
# common/databricks-autonomous-operations/SKILL.md "Profile & Workspace Resolution".)
# SELECT * FROM {catalog}.{silver_schema}.dq_rules
# 4. THEN run DLT pipeline (loads rules from table)
databricks pipelines start-update --pipeline-name "[${bundle.target} ${var.user_prefix}] Silver Layer Pipeline"
Post-Run Verification (after pipeline completes)
After the DLT pipeline finishes, verify expectations were applied using the DLT system event_log() TVF. Do NOT use databricks pipelines list-pipeline-events — it returns lifecycle events but lacks per-expectation pass/fail counts.
SELECT
event_type,
details:flow_progress.data_quality.dropped_records AS dropped,
details:flow_progress.data_quality.expectations AS expectations
FROM event_log("<PIPELINE_ID>")
WHERE details:flow_progress.data_quality IS NOT NULL
ORDER BY timestamp DESC
LIMIT 10;
See: silver/01-dlt-expectations-patterns/SKILL.md (Pattern 5) for the Silver-table-scoped variant, and common/databricks-autonomous-operations/references/dlt-pipeline-troubleshooting.md for the full DLT verification playbook.
Phase 7: Enable Anomaly Detection on Silver Schema (5 min) — USER-TRIGGERED ONLY
This phase is executed ONLY when the user explicitly requests it. Do not auto-execute.
Pre-Condition - MUST read this skill first:
- Read
monitoring/04-anomaly-detection/SKILL.md— Schema-level freshness/completeness monitoring
Why: Every Silver schema should have anomaly detection enabled from day one. It builds freshness and completeness ML baselines immediately, catching stale/incomplete tables before downstream consumers notice.
Steps:
- Enable anomaly detection on the Silver schema (uses
enable_anomaly_detection_on_schema()from the anomaly-detection skill) - Exclude metadata tables that are not data pipeline outputs (e.g.,
dq_rules) - Verify enablement via Catalog Explorer or SDK
from databricks.sdk import WorkspaceClient
from databricks.sdk.service.dataquality import Monitor, AnomalyDetectionConfig
w = WorkspaceClient()
# Get Silver schema UUID
schema_info = w.schemas.get(full_name=f"{catalog}.{silver_schema}")
schema_id = schema_info.schema_id
# Enable anomaly detection (exclude metadata tables)
try:
w.data_quality.create_monitor(
monitor=Monitor(
object_type="schema",
object_id=schema_id,
anomaly_detection_config=AnomalyDetectionConfig(
excluded_table_full_names=[
f"{catalog}.{silver_schema}.dq_rules", # Metadata, not pipeline output
]
)
)
)
print(f"✓ Anomaly detection enabled on {catalog}.{silver_schema}")
except Exception as e:
if "already exists" in str(e).lower():
print(f"✓ Already enabled (skipping)")
else:
print(f"⚠️ Non-blocking: {e}")
Note: This is non-blocking — if anomaly detection fails to enable (permissions, preview limitations), the Silver layer setup continues. Retry later via monitoring/04-anomaly-detection/scripts/enable_anomaly_detection.py.
Common Mistakes (Silver-Specific)
Mistake 1: Deploying DLT Before DQ Setup Job
Pipeline Error: Table or view not found: dq_rules
Fix: Run silver_dq_setup_job BEFORE deploying/running DLT pipeline.
Mistake 2: Notebook Header in Loader File
# dq_rules_loader.py
# Databricks notebook source # <-- Makes it a notebook, breaks imports!
Fix: Remove # Databricks notebook source line. Read databricks-python-imports for correct pattern.
Mistake 3: Aggregation in Silver
# WRONG: Aggregation belongs in Gold
def silver_sales_daily():
return dlt.read_stream(...).groupBy("store", "date").agg(sum("revenue"))
Fix: Keep Silver at transaction grain. Aggregate in Gold.
Mistake 4: Manual Clustering Columns
# WRONG
@dlt.table(cluster_by=["store_number", "transaction_date"])
Fix: Always use cluster_by_auto=True. Never specify columns.
Mistake 5: Using expect_or_fail
# WRONG: Pipeline fails on bad data
@dlt.expect_or_fail("valid_id", "id IS NOT NULL")
Fix: Use @dlt.expect_all_or_drop() for critical rules. Pipeline continues, bad records quarantined.
Mistake 6: Hardcoding Table Names
# WRONG: Hardcoded table reference
dlt.read_stream("my_catalog.bronze.transactions")
Fix: Use get_bronze_table() helper with DLT configuration. See references/silver-table-patterns.md.
Mistake 7: Schema Evolution Without Full Refresh
Error: Incompatible schema change detected on streaming table
Fix: Streaming tables require a full refresh for incompatible schema changes (adding NOT NULL columns, changing types). Trigger with: databricks pipelines start-update --pipeline-name "..." --full-refresh
Mistake 8: Missing Row Tracking (Breaks Downstream MVs)
# ❌ WRONG: Missing delta.enableRowTracking
table_properties={
"delta.enableChangeDataFeed": "true",
# Row tracking missing!
}
Fix: ALWAYS include "delta.enableRowTracking": "true" in Silver table properties. Without it, downstream Gold materialized views cannot use incremental refresh and will do expensive full recomputation.
Mistake 9: Mixing dlt and dp decorators in the same table definition
# ❌ WRONG: mixing APIs — @dp.table with a @dlt.* decorator
from pyspark import pipelines as dp
@dp.table(name="silver_transactions")
@dlt.expect_all_or_drop(get_critical_rules_for_table(...)) # Mixes APIs!
Fix: Pick one API and use it consistently. Both support expectations — dp is Databricks' recommended API (@dp.table + @dp.expect_all_or_drop), while this skill's DQ-rules framework standardizes on import dlt (@dlt.table + @dlt.expect_all_or_drop). Don't combine @dp.* and @dlt.* on the same function. See "Python API" section above.
Post-Creation Validation
Before considering the Silver layer complete, verify each item and confirm its source:
Common Skill Compliance
- Table properties match
databricks-table-propertiesSilver layer spec (not generated from memory) - Python imports follow
databricks-python-importspatterns (loader has NO notebook header) - Asset Bundle YAML follows
databricks-asset-bundlespatterns (notebook_task, base_parameters) - Schema DDL follows
schema-management-patterns(IF NOT EXISTS, governance metadata) - PK constraint follows
unity-catalog-constraintssyntax (NOT ENFORCED keyword) - Names extracted from source files per
databricks-expert-agent(not hardcoded)
Silver-Domain Skill Compliance
- DQ rules table follows
dlt-expectations-patternsDDL - Rules loader uses cache pattern from
dlt-expectations-patterns(toPandas, not collect) - DLT decorators follow
dlt-expectations-patterns(expect_all_or_drop, expect_all) - Quarantine condition uses
dlt-expectations-patternsgeneration pattern
Silver Layer Specifics
- Schema cloning: Silver columns match Bronze (no aggregation, no joins)
-
get_bronze_table()helper used for all source table references -
cluster_by_auto=Trueon every table (NEVER manual cluster keys) -
delta.enableRowTracking=trueon every Silver table (required for downstream MV incremental refresh) - Quarantine tables created for high-volume fact tables
- DQ monitoring views created (including data freshness)
- (User-triggered) Deployment order documented: DQ setup job runs BEFORE DLT pipeline
- One pipelines API used consistently —
import dltis this skill's current standard;dpis the recommended forward path (don't mix@dlt.*and@dp.*) -
serverless: truein pipeline YAML (NEVER classic clusters) -
photon: truein pipeline YAML -
edition: ADVANCEDset in pipeline YAML (required for expectations/CDC) - No
clusters:block in pipeline YAML (serverless manages compute) - Deduplication applied where Bronze may have duplicate records
-
processed_timestampadded to every Silver table - Event timestamps preserved from Bronze (not replaced by processing time)
- (User-triggered) Anomaly detection enabled on Silver schema (Phase 7)
- (User-triggered) Metadata tables (e.g.,
dq_rules) excluded from anomaly detection
Reference Files
Silver Table Patterns
references/silver-table-patterns.md- Complete DLT table templates: standard pattern, dimension example, fact example with quarantine,get_bronze_table()helper, derived field patterns
Monitoring Patterns
references/monitoring-patterns.md- DQ monitoring views: per-table metrics, referential integrity checks, data freshness monitoring
Pipeline Configuration
references/pipeline-configuration.md- Silver-specific DLT pipeline YAML and DQ setup job YAML examples (supplementsdatabricks-asset-bundles)
Templates
Requirements Template
assets/templates/requirements-template.md- Fill-in-first requirements gathering: project context, Bronze-to-Silver table mapping, DQ rules per entity, quarantine strategy
Related Skills
| Skill | Relationship | Path |
|---|---|---|
dlt-expectations-patterns |
Mandatory - DQ rules, loader, decorators | silver/01-dlt-expectations-patterns/SKILL.md |
dqx-patterns |
Optional - Advanced validation | silver/02-dqx-patterns/SKILL.md |
anomaly-detection |
Mandatory - Schema freshness/completeness monitoring | monitoring/04-anomaly-detection/SKILL.md |
databricks-expert-agent |
Mandatory - Extraction principle | skills/databricks-expert-agent/SKILL.md |
databricks-table-properties |
Mandatory - Silver TBLPROPERTIES | common/databricks-table-properties/SKILL.md |
databricks-python-imports |
Mandatory - Pure Python loader | common/databricks-python-imports/SKILL.md |
databricks-asset-bundles |
Mandatory - Pipeline/job YAML | skills/databricks-asset-bundles/SKILL.md |
schema-management-patterns |
Mandatory - Schema DDL | common/schema-management-patterns/SKILL.md |
unity-catalog-constraints |
Mandatory - PK constraint | common/unity-catalog-constraints/SKILL.md |
Pipeline Progression
Previous stage: bronze/00-bronze-layer-setup → Bronze tables must exist before creating Silver
Next stage: After completing the Silver layer, proceed to:
gold/01-gold-layer-setup— Implement Gold layer tables, merge scripts, and FK constraints from the YAML designs created in stage 1
Post-Completion: Skill Usage Summary (MANDATORY)
After completing all phases of this orchestrator, output a Skill Usage Summary reflecting what you ACTUALLY did — not a pre-written summary.
What to Include
- Every skill
SKILL.mdorreferences/file you read (via the Read tool), in the order you read them - Which phase you were in when you read it
- Whether it was a Worker, Common, Cross-domain, or Reference file
- A one-line description of what you specifically used it for in this session
Format
| # | Phase | Skill / Reference Read | Type | What It Was Used For |
|---|---|---|---|---|
| 1 | Phase N | path/to/SKILL.md |
Worker / Common / Cross-domain / Reference | One-line description |
Summary Footer
End with:
- Totals: X worker skills, Y common skills, Z reference files read across N phases
- Skipped: List any skills from the dependency table above that you did NOT need to read, and why (e.g., "phase not applicable", "user skipped", "no issues encountered")
- Unplanned: List any skills you read that were NOT listed in the dependency table (e.g., for troubleshooting, edge cases, or user-requested detours)
References
Official Databricks Documentation
- DLT Expectations
- Portable and Reusable Expectations
- Share Code Between Notebooks
- Automatic Clustering
- Lakeflow Declarative Pipelines (SDP) - Modern pipeline framework overview
- Python API:
pyspark.pipelines- Modern Python API reference (future migration target) - Row Tracking - Required for incremental MV refresh
- Schema Evolution in Streaming Tables - Full refresh requirements
- Pipeline Edition Comparison - ADVANCED required for expectations/CDC
See Also
- Authoritative upstream (alternate registry): databricks-agent-skills /
databricks-pipelines— canonical DLT / Spark Declarative Pipelines guidance.
Version History
- 2026-08-30 — Reconciled the
dlt-vs-dppremise: expectations are available in the moderndpAPI (dp.expect_all_or_drop), which Databricks recommends. Corrected the "not yet available indp" wording, added adpequivalent snippet, reframed Mistake 9 (mixingdlt/dpdecorators) and the checklist item, and keptimport dltas this skill's standard with a mechanical migration note. Bumpedlast_verified.