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.
Files changed (97) hide show
  1. {composable_data_stack-0.9.0/composable_data_stack.egg-info → composable_data_stack-0.9.1}/PKG-INFO +136 -103
  2. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/README.md +134 -101
  3. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/image_verification.py +12 -3
  4. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/k8s_renderer.py +5 -0
  5. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/k8s_runner.py +79 -2
  6. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/main.py +9 -8
  7. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1/composable_data_stack.egg-info}/PKG-INFO +136 -103
  8. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/SOURCES.txt +1 -0
  9. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/requires.txt +1 -1
  10. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/pyproject.toml +2 -2
  11. composable_data_stack-0.9.1/tests/test_bump_changelog.py +113 -0
  12. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_hardening.py +3 -1
  13. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_image_security_scan_workflow.py +7 -0
  14. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_image_verification.py +15 -0
  15. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k8s_renderer.py +25 -0
  16. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k8s_runner.py +116 -1
  17. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_main.py +51 -1
  18. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_publish_images_workflow.py +14 -11
  19. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/LICENSE +0 -0
  20. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/__init__.py +0 -0
  21. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/constants.py +0 -0
  22. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/diagnostics.py +0 -0
  23. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/getter.py +0 -0
  24. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/graph.py +0 -0
  25. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/image_updates.py +0 -0
  26. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/k8s_security.py +0 -0
  27. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/loader.py +0 -0
  28. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/overlay.py +0 -0
  29. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/planner.py +0 -0
  30. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/preflight.py +0 -0
  31. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/renderer.py +0 -0
  32. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resolver.py +0 -0
  33. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/__init__.py +0 -0
  34. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/contract.schema.json +0 -0
  35. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/module.schema.json +0 -0
  36. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/profile.schema.json +0 -0
  37. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/rule-schema.json +0 -0
  38. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/resources/rule-set.json +0 -0
  39. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/secrets.py +0 -0
  40. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/security.py +0 -0
  41. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/security_common.py +0 -0
  42. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/state.py +0 -0
  43. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/up_runner.py +0 -0
  44. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/utils.py +0 -0
  45. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/cli/validator.py +0 -0
  46. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/dependency_links.txt +0 -0
  47. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/entry_points.txt +0 -0
  48. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/composable_data_stack.egg-info/top_level.txt +0 -0
  49. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/setup.cfg +0 -0
  50. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_ai_profile_review.py +0 -0
  51. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_cds_workflow.py +0 -0
  52. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_completion.py +0 -0
  53. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_compose_runtime_smoke.py +0 -0
  54. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_compose_to_module.py +0 -0
  55. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_config_generation.py +0 -0
  56. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_definitions_uri.py +0 -0
  57. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dagster_entrypoint_backend_guard.py +0 -0
  58. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dbt_hardening.py +0 -0
  59. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_dlt_postgres_wiring.py +0 -0
  60. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_duckdb_hardening.py +0 -0
  61. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_environment_classification.py +0 -0
  62. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_environment_cli.py +0 -0
  63. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_getter.py +0 -0
  64. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_graph.py +0 -0
  65. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_image_updates.py +0 -0
  66. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k3d_e2e_profile.py +0 -0
  67. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k3d_exposure.py +0 -0
  68. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_k8s_security.py +0 -0
  69. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_loader.py +0 -0
  70. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_markdown_mermaid_blocks.py +0 -0
  71. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_module_isolation.py +0 -0
  72. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_modules_no_committed_secrets.py +0 -0
  73. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_mvp_proof_workflow.py +0 -0
  74. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_overlay.py +0 -0
  75. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_planner.py +0 -0
  76. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_preflight.py +0 -0
  77. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_python_version_alignment.py +0 -0
  78. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_release_version_check.py +0 -0
  79. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_render_example_profile.py +0 -0
  80. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_renderer.py +0 -0
  81. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_resolve_profile_path.py +0 -0
  82. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_resolver.py +0 -0
  83. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_secrets.py +0 -0
  84. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_security.py +0 -0
  85. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_smoke_example_profile.py +0 -0
  86. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_standalone_module_profile.py +0 -0
  87. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_state.py +0 -0
  88. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_superset_hardening.py +0 -0
  89. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_tender_analytics.py +0 -0
  90. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_tender_dashboard.py +0 -0
  91. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_test_runner_timeout.py +0 -0
  92. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_trivyignore.py +0 -0
  93. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_up_runner.py +0 -0
  94. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_upstream_image_hardening.py +0 -0
  95. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_utils.py +0 -0
  96. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_validator.py +0 -0
  97. {composable_data_stack-0.9.0 → composable_data_stack-0.9.1}/tests/test_vendored_llm_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: composable-data-stack
3
- Version: 0.9.0
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.7; extra == "dev"
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
- > **Terraform for data platforms.**
41
- > Build, validate, secure, and evolve data stacks using modular components and explicit contracts.
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
- ![Composable Data Stack logo](assets/branding/logo.svg)
43
+ ![Composable Data Stack logo](https://raw.githubusercontent.com/RonaldHensbergen/composable-data-stack/main/assets/branding/logo.svg)
44
44
 
45
45
  Project:
46
46
 
@@ -69,43 +69,122 @@ SonarCloud — Metrics:
69
69
 
70
70
  ---
71
71
 
72
- ## 🧠 What Is CDS (In 1 Minute)
72
+ You start with a straightforward goal: orchestrate some pipelines, store the
73
+ data, and make it useful.
73
74
 
74
- Composable Data Stack (CDS) is a framework for defining and assembling data platforms from reusable modules such as orchestrators, warehouses, BI tools, and secrets providers.
75
+ Then the tool decisions begin.
75
76
 
76
- ## 🤝 Get Involved
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
- - **Star and follow** on GitHub: [RonaldHensbergen/composable-data-stack](https://github.com/RonaldHensbergen/composable-data-stack)
79
- - **Contribute**: open a discussion, file an issue, or send a PR to help shape CDS
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
- > **Note:** Development helper tools are located in the `tools/` directory (git-ignored). See `tools/pr-cli/README.md` for PR creation scripts.
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
- ## ⚡ Why CDS
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
- Instead of hardcoding integrations or relying on fragile pipelines, CDS introduces:
99
+ That fragmentation creates a familiar cycle:
89
100
 
90
- - 🔧 **Modules**: reusable components (Dagster, Postgres, Superset)
91
- - 🔗 **Contracts**: explicit interfaces between components
92
- - 🧩 **Profiles**: fully composed, runnable stacks
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
- Think of it as Infrastructure as Code, but for data platforms.
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
- Modern data platforms force a trade-off:
113
+ ## The Cost of Choosing Wrong
97
114
 
98
- |Approach|Problem|
99
- |---|---|
100
- |Monolithic stack|Rigid, hard to evolve|
101
- |Custom pipelines|Flexible but fragile and inconsistent|
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
- CDS gives you the best of both:
161
+ Instead of burying platform architecture in scripts and tribal knowledge, CDS
162
+ makes it declarative. It answers:
104
163
 
105
- - composability without chaos
106
- - flexibility with guarantees
107
- - modularity with structure
108
- - no vendor lock-in by design
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
- ## 🏗️ Example
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
- ### What CDS Does
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
- You can replace components without changing system behavior:
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
- ```mermaid
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
+ ![Dagster, Postgres, and Superset connected through contracts](https://raw.githubusercontent.com/RonaldHensbergen/composable-data-stack/main/docs/diagrams/architecture/architecture_overview.svg)
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
- ```mermaid
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
+ ![CDS compile-time and runtime flow](https://raw.githubusercontent.com/RonaldHensbergen/composable-data-stack/main/docs/diagrams/processes/internal_flow.svg)
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 you run CDS:
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 allows you to go from a declarative profile to a runnable local data stack.
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
- Contributions are welcome.
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
- Good first contributions:
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