composable-data-stack 0.9.0__tar.gz → 0.9.1__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.
- {composable_data_stack-0.9.0/composable_data_stack.egg-info → composable_data_stack-0.9.1}/PKG-INFO +136 -103
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/README.md +134 -101
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/image_verification.py +12 -3
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/k8s_renderer.py +5 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/k8s_runner.py +79 -2
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/main.py +9 -8
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1/composable_data_stack.egg-info}/PKG-INFO +136 -103
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/SOURCES.txt +1 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/requires.txt +1 -1
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/pyproject.toml +2 -2
- composable_data_stack-0.9.1/tests/test_bump_changelog.py +113 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_hardening.py +3 -1
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_image_security_scan_workflow.py +7 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_image_verification.py +15 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k8s_renderer.py +25 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k8s_runner.py +116 -1
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_main.py +51 -1
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_publish_images_workflow.py +14 -11
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/LICENSE +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/__init__.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/constants.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/diagnostics.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/getter.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/graph.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/image_updates.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/k8s_security.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/loader.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/overlay.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/planner.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/preflight.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/renderer.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resolver.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/__init__.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/contract.schema.json +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/module.schema.json +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/profile.schema.json +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/rule-schema.json +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/rule-set.json +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/secrets.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/security.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/security_common.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/state.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/up_runner.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/utils.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/validator.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/dependency_links.txt +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/entry_points.txt +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/top_level.txt +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/setup.cfg +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_ai_profile_review.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_cds_workflow.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_completion.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_compose_runtime_smoke.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_compose_to_module.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_config_generation.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_definitions_uri.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_entrypoint_backend_guard.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dbt_hardening.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dlt_postgres_wiring.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_duckdb_hardening.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_environment_classification.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_environment_cli.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_getter.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_graph.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_image_updates.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k3d_e2e_profile.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k3d_exposure.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k8s_security.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_loader.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_markdown_mermaid_blocks.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_module_isolation.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_modules_no_committed_secrets.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_mvp_proof_workflow.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_overlay.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_planner.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_preflight.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_python_version_alignment.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_release_version_check.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_render_example_profile.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_renderer.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_resolve_profile_path.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_resolver.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_secrets.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_security.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_smoke_example_profile.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_standalone_module_profile.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_state.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_superset_hardening.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_tender_analytics.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_tender_dashboard.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_test_runner_timeout.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_trivyignore.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_up_runner.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_upstream_image_hardening.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_utils.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_validator.py +0 -0
- {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_vendored_llm_client.py +0 -0
{composable_data_stack-0.9.0/composable_data_stack.egg-info → composable_data_stack-0.9.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: composable-data-stack
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: CLI for validating and composing composable data stack profiles
|
|
5
5
|
Author: Ronald Hensbergen
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -32,15 +32,15 @@ Provides-Extra: dev
|
|
|
32
32
|
Requires-Dist: coverage>=7.6; extra == "dev"
|
|
33
33
|
Requires-Dist: bandit>=1.7; extra == "dev"
|
|
34
34
|
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
35
|
-
Requires-Dist: ruff==0.16.
|
|
35
|
+
Requires-Dist: ruff==0.16.8; extra == "dev"
|
|
36
36
|
Dynamic: license-file
|
|
37
37
|
|
|
38
38
|
# 🚀 Composable Data Stack (CDS)
|
|
39
39
|
|
|
40
|
-
> **
|
|
41
|
-
>
|
|
40
|
+
> **The modern data stack has a composition problem. CDS is an open framework
|
|
41
|
+
> for building data platforms that can evolve without being rebuilt.**
|
|
42
42
|
|
|
43
|
-

|
|
43
|
+

|
|
44
44
|
|
|
45
45
|
Project:
|
|
46
46
|
|
|
@@ -69,43 +69,122 @@ SonarCloud — Metrics:
|
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
You start with a straightforward goal: orchestrate some pipelines, store the
|
|
73
|
+
data, and make it useful.
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
Then the tool decisions begin.
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
Airflow, Dagster, or Prefect? Iceberg, Delta, or Hudi? Superset or Metabase?
|
|
78
|
+
Every choice opens another comparison, another integration, and another
|
|
79
|
+
architecture diagram. Every diagram looks different. Every tool has its own
|
|
80
|
+
configuration model, assumptions, and lifecycle. Before long, the platform is
|
|
81
|
+
less a designed system than a collection of decisions held together by custom
|
|
82
|
+
code and institutional memory.
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
- **Proof it**: if you run it in a real workflow, share your feedback — good or bad
|
|
84
|
+
The hardest question is no longer **"Which tool is best?"** It is **"How do
|
|
85
|
+
these tools fit together, and can we change our minds later?"**
|
|
81
86
|
|
|
82
|
-
|
|
87
|
+
## Why Data Platforms Have a Composition Problem
|
|
83
88
|
|
|
84
|
-
|
|
89
|
+
The modern data ecosystem is excellent at producing capable tools and terrible
|
|
90
|
+
at making them work as interchangeable parts.
|
|
85
91
|
|
|
86
|
-
|
|
92
|
+
Teams are expected to assemble orchestration, storage, transformation,
|
|
93
|
+
cataloging, observability, security, and BI into one dependable platform. But
|
|
94
|
+
the boundaries between those tools are usually implicit. Connection details
|
|
95
|
+
leak into environment variables. Service names become dependencies. Deployment
|
|
96
|
+
logic assumes a specific vendor. Compatibility lives in a staff engineer's
|
|
97
|
+
head—or is discovered during an incident.
|
|
87
98
|
|
|
88
|
-
|
|
99
|
+
That fragmentation creates a familiar cycle:
|
|
89
100
|
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
101
|
+
- evaluate an overwhelming number of tools
|
|
102
|
+
- debate architecture instead of delivering data products
|
|
103
|
+
- hand-build integrations that only one team understands
|
|
104
|
+
- duplicate stacks across development, CI, and production
|
|
105
|
+
- postpone upgrades because nobody knows what they will break
|
|
106
|
+
- accept lock-in because replacing one component feels like replacing the
|
|
107
|
+
platform
|
|
93
108
|
|
|
94
|
-
|
|
109
|
+
This is not primarily a tooling problem. **It is a composition problem.** We
|
|
110
|
+
have many good components, but no shared way to declare what they provide,
|
|
111
|
+
what they need, and whether a particular assembly is valid.
|
|
95
112
|
|
|
96
|
-
|
|
113
|
+
## The Cost of Choosing Wrong
|
|
97
114
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
115
|
+
A technology choice that looks local rarely stays local.
|
|
116
|
+
|
|
117
|
+
Choose an orchestrator and its concepts spread into deployment, secrets,
|
|
118
|
+
logging, and team workflows. Choose a table format and it constrains engines,
|
|
119
|
+
catalogs, and migration paths. Choose a BI layer and dashboards become coupled
|
|
120
|
+
to authentication, database behavior, and operational assumptions.
|
|
121
|
+
|
|
122
|
+
The bill arrives later:
|
|
123
|
+
|
|
124
|
+
- migrations become multi-quarter programs
|
|
125
|
+
- upgrades become risky, manual compatibility exercises
|
|
126
|
+
- platform teams maintain glue code instead of platform capabilities
|
|
127
|
+
- product teams wait while engineers renegotiate architecture
|
|
128
|
+
- vendors gain leverage because the cost of leaving keeps rising
|
|
129
|
+
|
|
130
|
+
There is no universally correct stack, and pretending otherwise is expensive.
|
|
131
|
+
The right choice today may be the wrong choice at a different scale, under a
|
|
132
|
+
new regulatory constraint, or after the team learns more. A healthy platform
|
|
133
|
+
must make change routine—not heroic.
|
|
134
|
+
|
|
135
|
+
## What If Data Platforms Were Composable?
|
|
136
|
+
|
|
137
|
+
What if a data platform described capabilities and interfaces before naming
|
|
138
|
+
products?
|
|
139
|
+
|
|
140
|
+
What if an orchestrator could request a database contract without hardcoding a
|
|
141
|
+
specific database? What if a profile could declare a supported combination,
|
|
142
|
+
validate it before deployment, and produce the runtime configuration? What if
|
|
143
|
+
replacing a component meant satisfying the same contract instead of rebuilding
|
|
144
|
+
every integration around it?
|
|
145
|
+
|
|
146
|
+
That is the goal of **Composable Data Stack (CDS)**.
|
|
147
|
+
|
|
148
|
+
CDS is an open-source framework for defining, validating, securing, and
|
|
149
|
+
assembling data platforms from reusable components. Think of it as
|
|
150
|
+
**Infrastructure as Code for the shape of a data platform**: the components,
|
|
151
|
+
the interfaces between them, and the rules that make the whole stack coherent.
|
|
152
|
+
|
|
153
|
+
CDS introduces three building blocks:
|
|
154
|
+
|
|
155
|
+
- 🔧 **Modules** package reusable capabilities such as orchestration, storage,
|
|
156
|
+
BI, and secret management.
|
|
157
|
+
- 🔗 **Contracts** define explicit, testable interfaces between those
|
|
158
|
+
capabilities.
|
|
159
|
+
- 🧩 **Profiles** compose modules into supported, reproducible stacks.
|
|
102
160
|
|
|
103
|
-
|
|
161
|
+
Instead of burying platform architecture in scripts and tribal knowledge, CDS
|
|
162
|
+
makes it declarative. It answers:
|
|
104
163
|
|
|
105
|
-
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
|
|
164
|
+
- **How do these tools fit together?** Through explicit contracts and declared
|
|
165
|
+
bindings.
|
|
166
|
+
- **What happens if I replace a component later?** CDS validates the new
|
|
167
|
+
composition against the same requirements before runtime.
|
|
168
|
+
- **How do I avoid vendor and technology lock-in?** Consumers depend on
|
|
169
|
+
capabilities, not hardcoded product identities.
|
|
170
|
+
|
|
171
|
+
The result is composability without chaos, flexibility with guarantees, and a
|
|
172
|
+
platform that can evolve without starting over.
|
|
173
|
+
|
|
174
|
+
## ⚡ Why CDS
|
|
175
|
+
|
|
176
|
+
Most teams are forced into one of two bad options:
|
|
177
|
+
|
|
178
|
+
|Approach|What You Gain|What It Costs|
|
|
179
|
+
|---|---|---|
|
|
180
|
+
|Monolithic stack|A consistent starting point|Rigid boundaries and an expensive exit|
|
|
181
|
+
|Custom integrations|Freedom to choose every component|Fragile glue, inconsistent stacks, and hidden coupling|
|
|
182
|
+
|CDS|Explicit composition and replaceable components|A contract and profile model the community maintains together|
|
|
183
|
+
|
|
184
|
+
CDS does not claim that every tool is interchangeable or that integration
|
|
185
|
+
complexity disappears. It makes compatibility explicit, validates known
|
|
186
|
+
constraints early, and gives the ecosystem a shared place to improve how tools
|
|
187
|
+
compose.
|
|
109
188
|
|
|
110
189
|
---
|
|
111
190
|
|
|
@@ -113,10 +192,12 @@ CDS gives you the best of both:
|
|
|
113
192
|
|
|
114
193
|
Use CDS if you:
|
|
115
194
|
|
|
195
|
+
- expect your architecture to evolve as requirements change
|
|
116
196
|
- want to swap tools (Airflow ↔ Dagster, Superset ↔ Metabase)
|
|
117
197
|
- need reproducible environments across dev, CI, and prod
|
|
118
198
|
- are building a platform for multiple teams
|
|
119
199
|
- want contract-driven integration instead of implicit coupling
|
|
200
|
+
- want to contribute to an open interoperability model for data tooling
|
|
120
201
|
|
|
121
202
|
CDS may be overkill if:
|
|
122
203
|
|
|
@@ -125,7 +206,7 @@ CDS may be overkill if:
|
|
|
125
206
|
|
|
126
207
|
---
|
|
127
208
|
|
|
128
|
-
## 🏗️
|
|
209
|
+
## 🏗️ See Composition in Practice
|
|
129
210
|
|
|
130
211
|
The `local-dagster-postgres-superset` profile defines:
|
|
131
212
|
|
|
@@ -133,7 +214,7 @@ The `local-dagster-postgres-superset` profile defines:
|
|
|
133
214
|
- Postgres -> storage
|
|
134
215
|
- Superset -> BI
|
|
135
216
|
|
|
136
|
-
|
|
217
|
+
CDS then:
|
|
137
218
|
|
|
138
219
|
1. Validates module definitions
|
|
139
220
|
2. Resolves contract bindings
|
|
@@ -142,7 +223,8 @@ The `local-dagster-postgres-superset` profile defines:
|
|
|
142
223
|
|
|
143
224
|
`cds plan` resolves the full dependency graph before runtime configuration is generated, ensuring all module interactions are valid and predictable.
|
|
144
225
|
|
|
145
|
-
|
|
226
|
+
The composition model creates a path to replace components while preserving
|
|
227
|
+
the contracts the rest of the platform depends on:
|
|
146
228
|
|
|
147
229
|
```text
|
|
148
230
|
Dagster -> Airflow
|
|
@@ -160,23 +242,7 @@ CDS wires modules through **contracts**, not direct dependencies. This section h
|
|
|
160
242
|
|
|
161
243
|
Below, `local-dagster-postgres-superset` wires Dagster to Postgres to Superset through contracts:
|
|
162
244
|
|
|
163
|
-
|
|
164
|
-
flowchart TD
|
|
165
|
-
Dagster[Dagster]
|
|
166
|
-
Postgres[(Postgres)]
|
|
167
|
-
Superset[Superset]
|
|
168
|
-
|
|
169
|
-
Dagster -->|transformation-runner| Postgres
|
|
170
|
-
Postgres -->|warehouse-query| Superset
|
|
171
|
-
|
|
172
|
-
classDef tool stroke:#818cf8,fill:#eef2ff
|
|
173
|
-
classDef database stroke:#2dd4bf,fill:#f0fdfa
|
|
174
|
-
classDef viz stroke:#a78bfa,fill:#f5f3ff
|
|
175
|
-
|
|
176
|
-
class Dagster tool
|
|
177
|
-
class Postgres database
|
|
178
|
-
class Superset viz
|
|
179
|
-
```
|
|
245
|
+

|
|
180
246
|
|
|
181
247
|
### Internal Flow
|
|
182
248
|
|
|
@@ -198,51 +264,7 @@ consumption in Superset), see
|
|
|
198
264
|
[docs/profile-testing/test-plan.md](docs/profile-testing/test-plan.md) and
|
|
199
265
|
[docs/profile-testing/failure-path-and-ci.md](docs/profile-testing/failure-path-and-ci.md).
|
|
200
266
|
|
|
201
|
-
|
|
202
|
-
flowchart TD
|
|
203
|
-
subgraph compile["Compile-time (cds)"]
|
|
204
|
-
direction TB
|
|
205
|
-
Profile[/profile.yaml/]
|
|
206
|
-
Validate[Validate]
|
|
207
|
-
Security["Security checks<br/>(cds test only)"]
|
|
208
|
-
Plan[Plan]
|
|
209
|
-
Render[Render]
|
|
210
|
-
Compose[/docker-compose.yaml/]
|
|
211
|
-
Stop1((stops here))
|
|
212
|
-
|
|
213
|
-
Profile --> Validate
|
|
214
|
-
Validate -->|structural + contract checks| Security
|
|
215
|
-
Security -->|rule-based checks| Plan
|
|
216
|
-
Plan -->|resolve + substitute| Render
|
|
217
|
-
Render --> Compose
|
|
218
|
-
|
|
219
|
-
Validate -.->|E020, E041, E042, E081| Stop1
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
subgraph runtime["Runtime (docker compose, cds up only)"]
|
|
223
|
-
direction TB
|
|
224
|
-
Build["docker compose build<br/>(skip with --no-build)"]
|
|
225
|
-
Up["docker compose up"]
|
|
226
|
-
Env[(".env file")]
|
|
227
|
-
Containers["running containers,<br/>real secret values injected"]
|
|
228
|
-
|
|
229
|
-
Build --> Up
|
|
230
|
-
Env -.->|resolves CDS_VAR| Up
|
|
231
|
-
Up --> Containers
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
Compose --> Build
|
|
235
|
-
|
|
236
|
-
classDef stage stroke:#818cf8,fill:#eef2ff
|
|
237
|
-
classDef artifact stroke:#2dd4bf,fill:#f0fdfa
|
|
238
|
-
classDef stop stroke:#f87171,fill:#fef2f2,stroke-dasharray: 3 3
|
|
239
|
-
classDef runtimeNode stroke:#a78bfa,fill:#f5f3ff
|
|
240
|
-
|
|
241
|
-
class Validate,Security,Plan,Render stage
|
|
242
|
-
class Profile,Compose artifact
|
|
243
|
-
class Stop1 stop
|
|
244
|
-
class Build,Up,Env,Containers runtimeNode
|
|
245
|
-
```
|
|
267
|
+

|
|
246
268
|
|
|
247
269
|
This mirrors the [`cds` command table](#️-cli) below: `validate`, `plan`, and `render` are each callable on their own; `security` only runs as part of `cds test`, not `cds up`. Module and contract definitions follow the [Contract-First](#contract-first) design principle, so most of what "Validate" and "Plan" check comes directly from `module.yaml` and `profile.yaml`.
|
|
248
270
|
|
|
@@ -272,7 +294,7 @@ cds security local-dagster-postgres-superset
|
|
|
272
294
|
|
|
273
295
|
## 📦 What You Get
|
|
274
296
|
|
|
275
|
-
When
|
|
297
|
+
When a profile compiles, CDS produces:
|
|
276
298
|
|
|
277
299
|
- validated module graph
|
|
278
300
|
- resolved contract bindings
|
|
@@ -281,7 +303,9 @@ When you run CDS:
|
|
|
281
303
|
- generated Helm chart for Kubernetes
|
|
282
304
|
- reproducible stack definition
|
|
283
305
|
|
|
284
|
-
This
|
|
306
|
+
This turns a declarative platform design into a reproducible, runnable local
|
|
307
|
+
data stack—and turns architectural assumptions into things the project can
|
|
308
|
+
inspect, validate, and improve.
|
|
285
309
|
|
|
286
310
|
---
|
|
287
311
|
|
|
@@ -990,7 +1014,20 @@ See [docs/support-policy.md](docs/support-policy.md) for OS support policy and p
|
|
|
990
1014
|
|
|
991
1015
|
## 🤝 Contributing
|
|
992
1016
|
|
|
993
|
-
|
|
1017
|
+
CDS will only become a useful interoperability layer if the people building and
|
|
1018
|
+
operating data platforms shape it together.
|
|
1019
|
+
|
|
1020
|
+
- **Run a profile** and report what works, what breaks, and what is missing.
|
|
1021
|
+
- **Document compatibility** between providers and consumers with evidence.
|
|
1022
|
+
- **Add or improve modules** without coupling them to a specific stack.
|
|
1023
|
+
- **Strengthen the model** through contracts, validation, security rules, and
|
|
1024
|
+
representative profiles.
|
|
1025
|
+
- **Star and follow** the
|
|
1026
|
+
[repository](https://github.com/RonaldHensbergen/composable-data-stack) if
|
|
1027
|
+
you want to track the project.
|
|
1028
|
+
|
|
1029
|
+
Real-world feedback is especially valuable. CDS should reflect how platforms
|
|
1030
|
+
actually fail and evolve, not how architecture diagrams pretend they do.
|
|
994
1031
|
|
|
995
1032
|
Please read these first:
|
|
996
1033
|
|
|
@@ -1002,12 +1039,8 @@ Please read these first:
|
|
|
1002
1039
|
- [CHANGELOG.md](CHANGELOG.md)
|
|
1003
1040
|
- [RELEASE.md](RELEASE.md)
|
|
1004
1041
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
- adding new modules
|
|
1008
|
-
- improving profile examples
|
|
1009
|
-
- extending contract definitions
|
|
1010
|
-
- adding validation or security rules
|
|
1042
|
+
Development helper tools are located in the gitignored `tools/` directory. See
|
|
1043
|
+
`tools/pr-cli/README.md` for PR creation scripts.
|
|
1011
1044
|
|
|
1012
1045
|
---
|
|
1013
1046
|
|