diff --git a/docs/index.md b/docs/index.md
index eafa59f..7465447 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -65,28 +65,52 @@ Install just what you need: `uv add gds-core[control,continuous]`
## Architecture
+```mermaid
+graph TD
+ classDef core fill:#e0e7ff,stroke:#4f46e5,stroke-width:2px,color:#1e1b4b
+ classDef dsl fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#78350f
+ classDef sim fill:#d1fae5,stroke:#059669,stroke-width:2px,color:#064e3b
+ classDef tool fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px,color:#4c1d95
+ classDef ext fill:#e5e7eb,stroke:#6b7280,stroke-width:1px,color:#374151
+
+ FW["gds-framework
core engine (pydantic only)"]:::core
+
+ VIZ["gds-viz
Mermaid + phase portraits"]:::tool
+ OWL["gds-owl
OWL / SHACL / SPARQL"]:::tool
+
+ GAMES["gds-games
game theory DSL"]:::dsl
+ SF["gds-stockflow
stock-flow DSL"]:::dsl
+ CTRL["gds-control
control systems DSL"]:::dsl
+ SW["gds-software
software architecture DSL"]:::dsl
+ BIZ["gds-business
business dynamics DSL"]:::dsl
+
+ SYM["gds-symbolic
SymPy + Hamiltonian"]:::tool
+ EX["gds-examples
tutorials + notebooks"]:::ext
+
+ SIM["gds-sim
discrete-time simulation"]:::sim
+ AN["gds-analysis
reachability + metrics"]:::sim
+ PSUU["gds-psuu
parameter sweep"]:::sim
+
+ CONT["gds-continuous
ODE engine (scipy)"]:::sim
+
+ FW --> VIZ
+ FW --> OWL
+ FW --> GAMES
+ FW --> SF
+ FW --> CTRL
+ FW --> SW
+ FW --> BIZ
+ CTRL --> SYM
+ FW --> EX
+ VIZ --> EX
+
+ FW --> AN
+ SIM --> AN
+ SIM --> PSUU
+ CONT --> AN
```
-gds-framework ← core engine (pydantic only)
- ↑
- ├── gds-viz ← Mermaid diagrams + phase portraits [matplotlib]
- ├── gds-games ← game theory DSL + Nash equilibrium [nashpy]
- ├── gds-stockflow ← stock-flow DSL
- ├── gds-control ← control systems DSL
- ├── gds-software ← software architecture DSL
- ├── gds-business ← business dynamics DSL (CLD, SCN, VSM)
- └── gds-owl ← OWL/SHACL/SPARQL export (rdflib, pyshacl)
- ↑
- gds-symbolic ← SymPy bridge (extends gds-control) [sympy]
- ↑
- gds-examples ← tutorials (depends on most DSLs + viz)
-
-gds-sim ← discrete-time simulation (standalone, pydantic only)
- ↑
- ├── gds-analysis ← spec→sim bridge, reachability
- └── gds-psuu ← parameter sweep + Optuna
-
-gds-continuous ← continuous-time ODE engine (standalone) [scipy]
-```
+
+**Legend:** :blue_square: Core | :yellow_square: Domain DSLs | :green_square: Simulation & Analysis | :purple_square: Tooling
## License
diff --git a/docs/research/formal-representability.md b/docs/research/formal-representability.md
index 2eae545..0788f94 100644
--- a/docs/research/formal-representability.md
+++ b/docs/research/formal-representability.md
@@ -118,6 +118,14 @@ specifications: you can represent everything about a system except what
its programs actually do. The canonical decomposition h = f ∘ g makes this
boundary explicit and exploitable.
+> **Paper alignment note.** Rice's theorem applies here because the
+> *software implementation* uses arbitrary Python callables for f_behav.
+> The paper's mathematical proofs (Theorem 3.6, existence) assume the
+> constraint set is compact, convex, and continuous (Assumption 3.5) —
+> a much more restricted class than Turing-complete programs. The R3
+> boundary reflects the implementation's scope, not the paper's
+> mathematical scope.
+
---
## 1. Preliminaries
@@ -132,6 +140,14 @@ construction, but the full categorical axioms (interchange law, coherence
conditions, traced monoidal structure for feedback) have not been formally
verified.
+> **Paper alignment note.** The foundational paper (Zargham & Shorish 2022)
+> defines GDS via standard function composition h(x) = f(x, g(x)) and does
+> not mandate categorical structure. The paper explicitly contrasts ACT
+> (Applied Category Theory) with GDS, noting ACT "can be difficult to
+> implement computationally." The categorical semantics here are a
+> *framework design choice* for compositionality, not a mathematical
+> requirement of the paper's GDS definition.
+
The components are:
- **Objects** are Interfaces: I = (F_in, F_out, B_in, B_out), each a tuple
@@ -516,6 +532,13 @@ semantics (what h actually computes given inputs) is R3.
pattern).** An AdmissibleInputConstraint (Paper Def 2.5: U_x) decomposes
as:
+> **Paper alignment note.** The paper defines the Admissible Input Map as
+> a single function U: X -> P(U) (Def 2.5) with no structural/behavioral
+> decomposition. The split below into U_x_struct (dependency graph) and
+> U_x_behav (constraint predicate) is a *framework design choice* for
+> ontological representation, enabling the dependency graph to be
+> serialized as R1 while the predicate remains R3.
+
```
U_x_struct : A -> P(E x V)
The dependency relation: "BoundaryAction B's admissible outputs
@@ -538,6 +561,11 @@ is a BoundaryAction, depends_on references valid entity.variable pairs).
**Property 4.6 (Transition Signatures follow the same pattern).**
A TransitionSignature (Paper Def 2.7: f|_x) provides:
+> **Paper alignment note.** The paper defines f|_x : U_x -> X (Def 2.7) as
+> a single restricted map. The decomposition into f_read (which variables
+> are read) and f_block_deps (which blocks feed this mechanism) is a
+> *framework design choice* to capture data-flow dependencies structurally.
+
```
f_read : Sig -> P(E x V)
The read dependency relation: "Mechanism M reads Entity E variable V."
@@ -643,7 +671,7 @@ G_struct concepts and their tiers:
- Space/entity structure: R1 (Property 4.1)
- Admissibility dependency graph (U_x_struct): R1 (Property 4.5)
- Transition read dependencies (f_read): R1 (Property 4.6)
-- State metric variable declarations (d_X_struct): R1 (Assumption 3.2)
+- State metric variable declarations (d_X_struct): R1 (Assumption 3.2) [*]
- Acyclicity: R2 (Section 5.1, G-006)
- Completeness/determinism: R2 (Section 5.2, SC-001, SC-002)
- Reference validation (dangling wirings): R2 (Section 5.1, G-004)
@@ -652,8 +680,14 @@ G_behav concepts and their tiers:
- Transition functions: R3 (Property 4.4, f_behav)
- Constraint predicates: R3 (Property 4.2, general case)
- Admissibility predicates (U_x_behav): R3 (Property 4.5)
-- State metric distance callable (d_X_behav): R3 (Assumption 3.2)
+- State metric distance callable (d_X_behav): R3 (Assumption 3.2) [*]
- Auto-wiring process: R3 (Property 3.2)
+
+> [*] **Paper alignment note.** The paper defines d_X : X x X -> R
+> (Assumption 3.2) as a single metric with no structural/behavioral
+> decomposition. The split into variable declarations (R1) and distance
+> callable (R3) follows the same framework pattern as Properties 4.5-4.6
+> — an ontological design choice, not a paper requirement.
- Construction validation: R3 (Proposition 3.4)
- Scheduling semantics: R3 (not stored in GDSSpec — external)
diff --git a/packages/gds-examples/software/gds_ecosystem/__init__.py b/packages/gds-examples/software/gds_ecosystem/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/packages/gds-examples/software/gds_ecosystem/dfd_pipeline.py b/packages/gds-examples/software/gds_ecosystem/dfd_pipeline.py
new file mode 100644
index 0000000..b15702e
--- /dev/null
+++ b/packages/gds-examples/software/gds_ecosystem/dfd_pipeline.py
@@ -0,0 +1,195 @@
+"""GDS User Pipeline — modeled as a Data Flow Diagram.
+
+Models the actual data transformation pipeline a user follows:
+User → define spec → compile → verify → export to OWL → simulate → analyze
+
+This DFD reveals the data flows between GDS subsystems and identifies
+where data transforms (processes) vs where it persists (data stores).
+
+GDS Decomposition:
+ X = {GDSSpec, SystemIR, VerificationReport, RDFGraph, Trajectory}
+ U = {User, DSL Definitions}
+ g = {Compile, Verify, Export, Adapt}
+ f = {Simulate, Analyze} (state-updating processes)
+"""
+
+from gds import project_canonical, verify
+from gds.ir.models import SystemIR
+from gds.spec import GDSSpec
+from gds_software.dfd.compile import compile_dfd, compile_dfd_to_system
+from gds_software.dfd.elements import DataFlow, DataStore, ExternalEntity, Process
+from gds_software.dfd.model import DFDModel
+from gds_viz import system_to_mermaid
+
+
+def build_dfd_model() -> DFDModel:
+ """Build the GDS user pipeline as a DFD."""
+ return DFDModel(
+ name="GDS User Pipeline",
+ description="Data flow through the GDS ecosystem from spec to analysis",
+ external_entities=[
+ ExternalEntity(name="User", description="Modeler defining a system"),
+ ExternalEntity(
+ name="DSL",
+ description="Domain-specific language (stockflow, control, etc.)",
+ ),
+ ],
+ processes=[
+ Process(
+ name="Register Spec",
+ description="Build GDSSpec from types, entities, blocks, wirings",
+ ),
+ Process(
+ name="Compile",
+ description="Flatten composition tree to SystemIR",
+ ),
+ Process(
+ name="Verify",
+ description="Run G-001..G-006 + SC-001..SC-009 checks",
+ ),
+ Process(
+ name="Export to OWL",
+ description="Serialize GDSSpec to RDF/Turtle via gds-owl",
+ ),
+ Process(
+ name="Adapt to Sim",
+ description="Bridge spec to gds-sim Model via gds-analysis",
+ ),
+ Process(
+ name="Simulate",
+ description="Execute trajectories via gds-sim or gds-continuous",
+ ),
+ Process(
+ name="Analyze",
+ description="Compute reachability, metrics, distances",
+ ),
+ ],
+ data_stores=[
+ DataStore(name="GDSSpec Store", description="Structural specification"),
+ DataStore(name="SystemIR Store", description="Flat IR"),
+ DataStore(name="RDF Graph", description="OWL/Turtle serialization"),
+ DataStore(name="Trajectory Store", description="Simulation results"),
+ ],
+ data_flows=[
+ # User inputs
+ DataFlow(
+ name="types + entities",
+ source="User",
+ target="Register Spec",
+ data="TypeDefs, Entities, Blocks",
+ ),
+ DataFlow(
+ name="DSL model",
+ source="DSL",
+ target="Register Spec",
+ data="Domain model (StockFlowModel, ControlModel, etc.)",
+ ),
+ # Spec registration
+ DataFlow(
+ name="spec",
+ source="Register Spec",
+ target="GDSSpec Store",
+ data="GDSSpec",
+ ),
+ # Compilation
+ DataFlow(
+ name="spec to compile",
+ source="GDSSpec Store",
+ target="Compile",
+ data="GDSSpec + Block tree",
+ ),
+ DataFlow(
+ name="system ir",
+ source="Compile",
+ target="SystemIR Store",
+ data="SystemIR",
+ ),
+ # Verification
+ DataFlow(
+ name="ir to verify",
+ source="SystemIR Store",
+ target="Verify",
+ data="SystemIR",
+ ),
+ DataFlow(
+ name="report",
+ source="Verify",
+ target="User",
+ data="VerificationReport",
+ ),
+ # OWL export
+ DataFlow(
+ name="spec to owl",
+ source="GDSSpec Store",
+ target="Export to OWL",
+ data="GDSSpec",
+ ),
+ DataFlow(
+ name="rdf",
+ source="Export to OWL",
+ target="RDF Graph",
+ data="Turtle/RDF",
+ ),
+ # Simulation
+ DataFlow(
+ name="spec to adapter",
+ source="GDSSpec Store",
+ target="Adapt to Sim",
+ data="GDSSpec + policies + SUFs",
+ ),
+ DataFlow(
+ name="model",
+ source="Adapt to Sim",
+ target="Simulate",
+ data="gds_sim.Model",
+ ),
+ DataFlow(
+ name="trajectory",
+ source="Simulate",
+ target="Trajectory Store",
+ data="Results (trajectory rows)",
+ ),
+ # Analysis
+ DataFlow(
+ name="trajectory to analyze",
+ source="Trajectory Store",
+ target="Analyze",
+ data="Trajectory + StateMetric",
+ ),
+ DataFlow(
+ name="analysis results",
+ source="Analyze",
+ target="User",
+ data="Distances, R(x), X_C",
+ ),
+ ],
+ )
+
+
+def build_dfd_spec() -> GDSSpec:
+ return compile_dfd(build_dfd_model())
+
+
+def build_dfd_system() -> SystemIR:
+ return compile_dfd_to_system(build_dfd_model())
+
+
+if __name__ == "__main__":
+ model = build_dfd_model()
+ spec = build_dfd_spec()
+ ir = build_dfd_system()
+ report = verify(ir)
+ canonical = project_canonical(spec)
+
+ print("=== GDS User Pipeline (DFD) ===")
+ print(f"Blocks: {len(spec.blocks)}")
+ print(f"Wirings: {len(spec.wirings)}")
+ print(f"Verification: {report.errors} errors")
+ print("")
+ print(f"=== Canonical: {canonical.formula} ===")
+ print(f"U: {canonical.boundary_blocks}")
+ print(f"g: {canonical.policy_blocks}")
+ print(f"f: {canonical.mechanism_blocks}")
+ print(f"X: {canonical.state_variables}")
+ print("")
+ print(system_to_mermaid(ir))
diff --git a/packages/gds-examples/software/gds_ecosystem/erd_datamodel.py b/packages/gds-examples/software/gds_ecosystem/erd_datamodel.py
new file mode 100644
index 0000000..8b38b88
--- /dev/null
+++ b/packages/gds-examples/software/gds_ecosystem/erd_datamodel.py
@@ -0,0 +1,197 @@
+"""GDS Data Model — modeled as an Entity-Relationship Diagram.
+
+Models the Pydantic model graph of gds-framework: GDSSpec has Blocks,
+Blocks have Interfaces, Interfaces have Ports, etc. This ERD formalizes
+the structural relationships that are currently implicit in the code.
+
+The ERD compiles to a GDSSpec where entities become stateful mechanisms
+and relationships become wirings — revealing the data model as a
+dynamical system where state = the registry contents.
+"""
+
+from gds import project_canonical, verify
+from gds.ir.models import SystemIR
+from gds.spec import GDSSpec
+from gds_software.erd.compile import compile_erd, compile_erd_to_system
+from gds_software.erd.elements import Attribute, Cardinality, ERDEntity, ERDRelationship
+from gds_software.erd.model import ERDModel
+from gds_viz import system_to_mermaid
+
+
+def build_erd_model() -> ERDModel:
+ """Build the GDS data model as an ERD."""
+ return ERDModel(
+ name="GDS Data Model",
+ description="The Pydantic model graph of gds-framework",
+ entities=[
+ ERDEntity(
+ name="GDSSpec",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="description", type="str", is_nullable=True),
+ ],
+ description="Central specification registry",
+ ),
+ ERDEntity(
+ name="Block",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="kind", type="str"),
+ ],
+ description="Compositional unit (AtomicBlock or composed)",
+ ),
+ ERDEntity(
+ name="Interface",
+ attributes=[
+ Attribute(name="forward_in", type="tuple[Port]"),
+ Attribute(name="forward_out", type="tuple[Port]"),
+ Attribute(name="backward_in", type="tuple[Port]"),
+ Attribute(name="backward_out", type="tuple[Port]"),
+ ],
+ description="Bidirectional typed boundary of a Block",
+ ),
+ ERDEntity(
+ name="Port",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="type_tokens", type="frozenset[str]"),
+ ],
+ description="Named typed connection point",
+ ),
+ ERDEntity(
+ name="TypeDef",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="python_type", type="type"),
+ Attribute(name="constraint", type="Callable", is_nullable=True),
+ ],
+ description="Runtime-constrained type definition",
+ ),
+ ERDEntity(
+ name="Entity",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ ],
+ description="State space dimension (groups StateVariables)",
+ ),
+ ERDEntity(
+ name="StateVariable",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="symbol", type="str", is_nullable=True),
+ ],
+ description="Single dimension of X",
+ ),
+ ERDEntity(
+ name="SpecWiring",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ ],
+ description="Explicit data flow connections between blocks",
+ ),
+ ERDEntity(
+ name="Wire",
+ attributes=[
+ Attribute(name="source", type="str"),
+ Attribute(name="target", type="str"),
+ Attribute(name="space", type="str", is_nullable=True),
+ ],
+ description="Single connection from source block to target",
+ ),
+ ],
+ relationships=[
+ ERDRelationship(
+ name="has_block",
+ source="GDSSpec",
+ target="Block",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="A spec registers many blocks",
+ ),
+ ERDRelationship(
+ name="has_interface",
+ source="Block",
+ target="Interface",
+ cardinality=Cardinality.ONE_TO_ONE,
+ description="Each block has exactly one interface",
+ ),
+ ERDRelationship(
+ name="has_port",
+ source="Interface",
+ target="Port",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="An interface has many ports across 4 slots",
+ ),
+ ERDRelationship(
+ name="has_type",
+ source="GDSSpec",
+ target="TypeDef",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="A spec registers many type definitions",
+ ),
+ ERDRelationship(
+ name="has_entity",
+ source="GDSSpec",
+ target="Entity",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="A spec registers many entities",
+ ),
+ ERDRelationship(
+ name="has_variable",
+ source="Entity",
+ target="StateVariable",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="An entity groups many state variables",
+ ),
+ ERDRelationship(
+ name="typed_by",
+ source="StateVariable",
+ target="TypeDef",
+ cardinality=Cardinality.MANY_TO_ONE,
+ description="Each variable is typed by a TypeDef",
+ ),
+ ERDRelationship(
+ name="has_wiring",
+ source="GDSSpec",
+ target="SpecWiring",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="A spec has many wiring groups",
+ ),
+ ERDRelationship(
+ name="has_wire",
+ source="SpecWiring",
+ target="Wire",
+ cardinality=Cardinality.ONE_TO_MANY,
+ description="A wiring group has many wires",
+ ),
+ ],
+ )
+
+
+def build_erd_spec() -> GDSSpec:
+ return compile_erd(build_erd_model())
+
+
+def build_erd_system() -> SystemIR:
+ return compile_erd_to_system(build_erd_model())
+
+
+if __name__ == "__main__":
+ model = build_erd_model()
+ spec = build_erd_spec()
+ ir = build_erd_system()
+ report = verify(ir)
+ canonical = project_canonical(spec)
+
+ print("=== GDS Data Model (ERD) ===")
+ print(f"Entities: {len(model.entities)}")
+ print(f"Relationships: {len(model.relationships)}")
+ print(f"Blocks: {len(spec.blocks)}")
+ print(f"Verification: {report.errors} errors")
+ print("")
+ print(f"=== Canonical: {canonical.formula} ===")
+ print(f"U: {canonical.boundary_blocks}")
+ print(f"g: {canonical.policy_blocks}")
+ print(f"f: {canonical.mechanism_blocks}")
+ print(f"X: {canonical.state_variables}")
+ print("")
+ print(system_to_mermaid(ir))
diff --git a/packages/gds-examples/software/gds_ecosystem/model.py b/packages/gds-examples/software/gds_ecosystem/model.py
new file mode 100644
index 0000000..c5631d5
--- /dev/null
+++ b/packages/gds-examples/software/gds_ecosystem/model.py
@@ -0,0 +1,208 @@
+"""GDS Ecosystem — the monorepo modeled using its own software architecture DSL.
+
+Dog-fooding: the GDS framework models its own package dependency graph
+as a component diagram, compiles it to GDSSpec, verifies it, and
+derives the canonical decomposition.
+
+Result: h = g (stateless — pure API composition). The ecosystem has no
+mutable state; all packages are pure API providers/consumers connected
+by typed interfaces.
+
+Concepts Covered:
+ - Component diagram with provides/requires interfaces
+ - Connector-based dependency wiring
+ - Compilation to GDSSpec and SystemIR
+ - Canonical decomposition of the ecosystem
+ - Self-referential modeling (framework models itself)
+
+GDS Decomposition:
+ X = {} (empty — no stateful components)
+ U = {GDSSpec, SimAPI, ODEAPI} (provider APIs)
+ g = {gds-games, gds-stockflow, gds-control, gds-owl,
+ gds-analysis, gds-symbolic} (consumer packages)
+ f = {} (no state updates)
+ h = g (stateless composition)
+"""
+
+from gds.ir.models import SystemIR
+from gds.spec import GDSSpec
+from gds_software.component.compile import (
+ compile_component,
+ compile_component_to_system,
+)
+from gds_software.component.elements import Component, Connector, InterfaceDef
+from gds_software.component.model import ComponentModel
+
+# ── Components (packages) ──────────────────────────────────────
+
+gds_framework = Component(
+ name="gds-framework",
+ provides=["GDSSpec"],
+ description="Core engine: blocks, composition, verification (pydantic only)",
+)
+
+gds_games = Component(
+ name="gds-games",
+ requires=["GDSSpec"],
+ description="Game theory DSL + Nash equilibrium",
+)
+
+gds_stockflow = Component(
+ name="gds-stockflow",
+ requires=["GDSSpec"],
+ description="Stock-flow DSL",
+)
+
+gds_control = Component(
+ name="gds-control",
+ requires=["GDSSpec"],
+ provides=["ControlAPI"],
+ description="Control systems DSL",
+)
+
+gds_owl = Component(
+ name="gds-owl",
+ requires=["GDSSpec"],
+ description="OWL/SHACL/SPARQL export/import",
+)
+
+gds_sim = Component(
+ name="gds-sim",
+ provides=["SimAPI"],
+ description="Discrete-time simulation engine (standalone)",
+)
+
+gds_analysis = Component(
+ name="gds-analysis",
+ requires=["GDSSpec", "SimAPI", "ODEAPI"],
+ description="Reachability, metrics, constraint enforcement",
+)
+
+gds_continuous = Component(
+ name="gds-continuous",
+ provides=["ODEAPI"],
+ description="Continuous-time ODE engine (standalone, scipy)",
+)
+
+gds_symbolic = Component(
+ name="gds-symbolic",
+ requires=["ControlAPI"],
+ description="SymPy bridge + Hamiltonian mechanics",
+)
+
+# ── Interfaces ─────────────────────────────────────────────────
+
+interfaces = [
+ InterfaceDef(
+ name="GDSSpec",
+ provided_by="gds-framework",
+ description="Structural specification registry",
+ ),
+ InterfaceDef(
+ name="SimAPI",
+ provided_by="gds-sim",
+ description="Discrete trajectory execution",
+ ),
+ InterfaceDef(
+ name="ODEAPI",
+ provided_by="gds-continuous",
+ description="ODE integration",
+ ),
+ InterfaceDef(
+ name="ControlAPI",
+ provided_by="gds-control",
+ description="Control model compilation",
+ ),
+]
+
+# ── Connectors (dependency wiring) ─────────────────────────────
+
+connectors = [
+ Connector(
+ name="games-uses-framework",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-games",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="stockflow-uses-framework",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-stockflow",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="control-uses-framework",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-control",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="owl-uses-framework",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-owl",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="symbolic-uses-control",
+ source="gds-control",
+ source_interface="ControlAPI",
+ target="gds-symbolic",
+ target_interface="ControlAPI",
+ ),
+ Connector(
+ name="analysis-uses-framework",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-analysis",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="analysis-uses-sim",
+ source="gds-sim",
+ source_interface="SimAPI",
+ target="gds-analysis",
+ target_interface="SimAPI",
+ ),
+ Connector(
+ name="analysis-uses-continuous",
+ source="gds-continuous",
+ source_interface="ODEAPI",
+ target="gds-analysis",
+ target_interface="ODEAPI",
+ ),
+]
+
+
+def build_model() -> ComponentModel:
+ """Build the GDS ecosystem component model."""
+ return ComponentModel(
+ name="GDS Ecosystem",
+ description="The GDS monorepo modeled using its own component DSL",
+ components=[
+ gds_framework,
+ gds_games,
+ gds_stockflow,
+ gds_control,
+ gds_owl,
+ gds_sim,
+ gds_analysis,
+ gds_continuous,
+ gds_symbolic,
+ ],
+ interfaces=interfaces,
+ connectors=connectors,
+ )
+
+
+def build_spec() -> GDSSpec:
+ """Compile the ecosystem model to a GDSSpec."""
+ return compile_component(build_model())
+
+
+def build_system() -> SystemIR:
+ """Compile the ecosystem model to a SystemIR."""
+ return compile_component_to_system(build_model())
diff --git a/packages/gds-examples/software/gds_ecosystem/notebook.py b/packages/gds-examples/software/gds_ecosystem/notebook.py
new file mode 100644
index 0000000..30315ab
--- /dev/null
+++ b/packages/gds-examples/software/gds_ecosystem/notebook.py
@@ -0,0 +1,586 @@
+import marimo
+
+__generated_with = "0.20.2"
+app = marimo.App(width="medium", app_title="GDS Ecosystem Self-Model")
+
+
+@app.cell
+def imports():
+ import marimo as mo
+
+ from gds import project_canonical, verify
+ from gds_software.component.compile import (
+ compile_component,
+ compile_component_to_system,
+ )
+ from gds_software.component.elements import (
+ Component,
+ Connector,
+ InterfaceDef,
+ )
+ from gds_software.component.model import ComponentModel
+ from gds_software.dfd.compile import compile_dfd, compile_dfd_to_system
+ from gds_software.dfd.elements import (
+ DataFlow,
+ DataStore,
+ ExternalEntity,
+ Process,
+ )
+ from gds_software.dfd.model import DFDModel
+ from gds_software.erd.compile import compile_erd, compile_erd_to_system
+ from gds_software.erd.elements import (
+ Attribute,
+ Cardinality,
+ ERDEntity,
+ ERDRelationship,
+ )
+ from gds_software.erd.model import ERDModel
+ from gds_viz import system_to_mermaid
+
+ return (
+ Attribute,
+ Cardinality,
+ Component,
+ ComponentModel,
+ Connector,
+ DFDModel,
+ DataFlow,
+ DataStore,
+ ERDEntity,
+ ERDModel,
+ ERDRelationship,
+ ExternalEntity,
+ InterfaceDef,
+ Process,
+ compile_component,
+ compile_component_to_system,
+ compile_dfd,
+ compile_dfd_to_system,
+ compile_erd,
+ compile_erd_to_system,
+ mo,
+ project_canonical,
+ system_to_mermaid,
+ verify,
+ )
+
+
+@app.cell
+def intro(mo):
+ mo.md("""
+ # GDS Ecosystem Self-Model
+
+ The GDS framework models **itself** using three of its own
+ software architecture diagram types. This is dog-fooding:
+ the framework's DSLs, compilers, and verification checks
+ are applied to the framework's own package structure.
+
+ Each diagram type reveals a different canonical form:
+
+ | Diagram | Canonical | What it reveals |
+ |---------|-----------|-----------------|
+ | Component | h = g | Package API dependencies (stateless) |
+ | DFD | h = f . g | User data pipeline (full dynamics) |
+ | ERD | h = f | Pydantic model graph (pure state) |
+ """)
+ return
+
+
+@app.cell
+def component_model(Component, ComponentModel, Connector, InterfaceDef, mo):
+ mo.md("## 1. Component Diagram — Package Dependencies")
+
+ comp_model = ComponentModel(
+ name="GDS Ecosystem",
+ description="Package dependency graph",
+ components=[
+ Component(
+ name="gds-framework",
+ provides=["GDSSpec"],
+ description="Core engine",
+ ),
+ Component(
+ name="gds-games",
+ requires=["GDSSpec"],
+ description="Game theory DSL",
+ ),
+ Component(
+ name="gds-stockflow",
+ requires=["GDSSpec"],
+ description="Stock-flow DSL",
+ ),
+ Component(
+ name="gds-control",
+ requires=["GDSSpec"],
+ provides=["ControlAPI"],
+ description="Control DSL",
+ ),
+ Component(
+ name="gds-owl",
+ requires=["GDSSpec"],
+ description="OWL/SHACL/SPARQL",
+ ),
+ Component(
+ name="gds-sim",
+ provides=["SimAPI"],
+ description="Simulation engine",
+ ),
+ Component(
+ name="gds-analysis",
+ requires=["GDSSpec", "SimAPI", "ODEAPI"],
+ description="Reachability + metrics",
+ ),
+ Component(
+ name="gds-continuous",
+ provides=["ODEAPI"],
+ description="ODE engine",
+ ),
+ Component(
+ name="gds-symbolic",
+ requires=["ControlAPI"],
+ description="SymPy + Hamiltonian",
+ ),
+ ],
+ interfaces=[
+ InterfaceDef(
+ name="GDSSpec",
+ provided_by="gds-framework",
+ description="Spec API",
+ ),
+ InterfaceDef(
+ name="SimAPI",
+ provided_by="gds-sim",
+ description="Sim API",
+ ),
+ InterfaceDef(
+ name="ODEAPI",
+ provided_by="gds-continuous",
+ description="ODE API",
+ ),
+ InterfaceDef(
+ name="ControlAPI",
+ provided_by="gds-control",
+ description="Control API",
+ ),
+ ],
+ connectors=[
+ Connector(
+ name="d1",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-games",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="d2",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-stockflow",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="d3",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-control",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="d4",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-owl",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="d5",
+ source="gds-control",
+ source_interface="ControlAPI",
+ target="gds-symbolic",
+ target_interface="ControlAPI",
+ ),
+ Connector(
+ name="d6",
+ source="gds-framework",
+ source_interface="GDSSpec",
+ target="gds-analysis",
+ target_interface="GDSSpec",
+ ),
+ Connector(
+ name="d7",
+ source="gds-sim",
+ source_interface="SimAPI",
+ target="gds-analysis",
+ target_interface="SimAPI",
+ ),
+ Connector(
+ name="d8",
+ source="gds-continuous",
+ source_interface="ODEAPI",
+ target="gds-analysis",
+ target_interface="ODEAPI",
+ ),
+ ],
+ )
+ return (comp_model,)
+
+
+@app.cell
+def component_results(
+ comp_model,
+ compile_component,
+ compile_component_to_system,
+ mo,
+ project_canonical,
+ system_to_mermaid,
+ verify,
+):
+ _spec = compile_component(comp_model)
+ _ir = compile_component_to_system(comp_model)
+ _report = verify(_ir)
+ _canonical = project_canonical(_spec)
+
+ _sv = ", ".join(f"{e}.{v}" for e, v in _canonical.state_variables)
+ _mf = ", ".join(_canonical.mechanism_blocks) or "(none)"
+ mo.md(
+ f"""
+ **Blocks:** {len(_spec.blocks)} |
+ **Verification errors:** {_report.errors}
+
+ **Canonical:** h = g (stateless)
+ - Boundary (U): {", ".join(_canonical.boundary_blocks)}
+ - Policy (g): {", ".join(_canonical.policy_blocks)}
+ - Mechanism (f): {_mf}
+ - State (X): {_sv or "(none)"}
+ """
+ )
+
+ _mermaid = system_to_mermaid(_ir)
+ mo.vstack(
+ [
+ mo.md("### Package Dependency Graph"),
+ mo.mermaid(_mermaid),
+ ]
+ )
+ return
+
+
+@app.cell
+def dfd_model(
+ DFDModel,
+ DataFlow,
+ DataStore,
+ ExternalEntity,
+ Process,
+ compile_dfd,
+ compile_dfd_to_system,
+ mo,
+ project_canonical,
+ system_to_mermaid,
+ verify,
+):
+ mo.md("## 2. DFD — User Data Pipeline")
+
+ _dfd = DFDModel(
+ name="GDS User Pipeline",
+ description="Data flow from spec definition to analysis",
+ external_entities=[
+ ExternalEntity(name="User", description="Modeler"),
+ ExternalEntity(name="DSL", description="Domain language"),
+ ],
+ processes=[
+ Process(name="Register Spec", description="Build GDSSpec"),
+ Process(name="Compile", description="Block tree to SystemIR"),
+ Process(name="Verify", description="G + SC checks"),
+ Process(name="Export to OWL", description="Serialize to RDF"),
+ Process(name="Adapt to Sim", description="spec_to_model()"),
+ Process(name="Simulate", description="Run trajectories"),
+ Process(name="Analyze", description="Reachability + metrics"),
+ ],
+ data_stores=[
+ DataStore(name="GDSSpec Store", description="Spec registry"),
+ DataStore(name="SystemIR Store", description="Flat IR"),
+ DataStore(name="RDF Graph", description="Turtle/OWL"),
+ DataStore(name="Trajectory Store", description="Results"),
+ ],
+ data_flows=[
+ DataFlow(
+ name="f1",
+ source="User",
+ target="Register Spec",
+ data="types, entities, blocks",
+ ),
+ DataFlow(
+ name="f2", source="DSL", target="Register Spec", data="domain model"
+ ),
+ DataFlow(
+ name="f3",
+ source="Register Spec",
+ target="GDSSpec Store",
+ data="GDSSpec",
+ ),
+ DataFlow(
+ name="f4",
+ source="GDSSpec Store",
+ target="Compile",
+ data="spec + block tree",
+ ),
+ DataFlow(
+ name="f5", source="Compile", target="SystemIR Store", data="SystemIR"
+ ),
+ DataFlow(
+ name="f6", source="SystemIR Store", target="Verify", data="SystemIR"
+ ),
+ DataFlow(
+ name="f7", source="Verify", target="User", data="VerificationReport"
+ ),
+ DataFlow(
+ name="f8",
+ source="GDSSpec Store",
+ target="Export to OWL",
+ data="GDSSpec",
+ ),
+ DataFlow(
+ name="f9", source="Export to OWL", target="RDF Graph", data="Turtle"
+ ),
+ DataFlow(
+ name="f10",
+ source="GDSSpec Store",
+ target="Adapt to Sim",
+ data="GDSSpec",
+ ),
+ DataFlow(
+ name="f11",
+ source="Adapt to Sim",
+ target="Simulate",
+ data="gds_sim.Model",
+ ),
+ DataFlow(
+ name="f12", source="Simulate", target="Trajectory Store", data="Results"
+ ),
+ DataFlow(
+ name="f13",
+ source="Trajectory Store",
+ target="Analyze",
+ data="trajectory",
+ ),
+ DataFlow(
+ name="f14", source="Analyze", target="User", data="R(x), distances"
+ ),
+ ],
+ )
+
+ _spec = compile_dfd(_dfd)
+ _ir = compile_dfd_to_system(_dfd)
+ _report = verify(_ir)
+ _canonical = project_canonical(_spec)
+
+ mo.md(
+ f"""
+ **Blocks:** {len(_spec.blocks)} |
+ **Verification errors:** {_report.errors}
+
+ **Canonical:** h = f . g (full dynamical system)
+ - Boundary (U): {", ".join(_canonical.boundary_blocks)}
+ - Policy (g): {", ".join(_canonical.policy_blocks)}
+ - Mechanism (f): {", ".join(_canonical.mechanism_blocks)}
+ - State (X): {", ".join(f"{e}.{v}" for e, v in _canonical.state_variables)}
+ """
+ )
+
+ mo.vstack(
+ [
+ mo.md("### User Data Pipeline"),
+ mo.mermaid(system_to_mermaid(_ir)),
+ ]
+ )
+ return
+
+
+@app.cell
+def erd_model(
+ Attribute,
+ Cardinality,
+ ERDEntity,
+ ERDModel,
+ ERDRelationship,
+ compile_erd,
+ compile_erd_to_system,
+ mo,
+ project_canonical,
+ system_to_mermaid,
+ verify,
+):
+ mo.md("## 3. ERD — GDS Data Model")
+
+ _erd = ERDModel(
+ name="GDS Data Model",
+ description="Pydantic model graph of gds-framework",
+ entities=[
+ ERDEntity(
+ name="GDSSpec",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ ],
+ ),
+ ERDEntity(
+ name="Block",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="kind", type="str"),
+ ],
+ ),
+ ERDEntity(
+ name="Interface",
+ attributes=[
+ Attribute(name="forward_in", type="tuple[Port]"),
+ Attribute(name="forward_out", type="tuple[Port]"),
+ ],
+ ),
+ ERDEntity(
+ name="Port",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="type_tokens", type="frozenset"),
+ ],
+ ),
+ ERDEntity(
+ name="TypeDef",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="python_type", type="type"),
+ ],
+ ),
+ ERDEntity(
+ name="Entity",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ ],
+ ),
+ ERDEntity(
+ name="StateVariable",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ Attribute(name="symbol", type="str", is_nullable=True),
+ ],
+ ),
+ ERDEntity(
+ name="SpecWiring",
+ attributes=[
+ Attribute(name="name", type="str", is_primary_key=True),
+ ],
+ ),
+ ERDEntity(
+ name="Wire",
+ attributes=[
+ Attribute(name="source", type="str"),
+ Attribute(name="target", type="str"),
+ ],
+ ),
+ ],
+ relationships=[
+ ERDRelationship(
+ name="has_block",
+ source="GDSSpec",
+ target="Block",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ERDRelationship(
+ name="has_interface",
+ source="Block",
+ target="Interface",
+ cardinality=Cardinality.ONE_TO_ONE,
+ ),
+ ERDRelationship(
+ name="has_port",
+ source="Interface",
+ target="Port",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ERDRelationship(
+ name="has_type",
+ source="GDSSpec",
+ target="TypeDef",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ERDRelationship(
+ name="has_entity",
+ source="GDSSpec",
+ target="Entity",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ERDRelationship(
+ name="has_variable",
+ source="Entity",
+ target="StateVariable",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ERDRelationship(
+ name="typed_by",
+ source="StateVariable",
+ target="TypeDef",
+ cardinality=Cardinality.MANY_TO_ONE,
+ ),
+ ERDRelationship(
+ name="has_wiring",
+ source="GDSSpec",
+ target="SpecWiring",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ERDRelationship(
+ name="has_wire",
+ source="SpecWiring",
+ target="Wire",
+ cardinality=Cardinality.ONE_TO_MANY,
+ ),
+ ],
+ )
+
+ _spec = compile_erd(_erd)
+ _ir = compile_erd_to_system(_erd)
+ _report = verify(_ir)
+ _canonical = project_canonical(_spec)
+
+ n_state_vars = len(_canonical.state_variables)
+ mo.md(
+ f"""
+ **Entities:** {len(_erd.entities)} |
+ **Relationships:** {len(_erd.relationships)} |
+ **State variables (X):** {n_state_vars}
+
+ **Canonical:** h = f (pure state, no external inputs)
+ - Mechanism (f): {", ".join(_canonical.mechanism_blocks)}
+ """
+ )
+
+ mo.vstack(
+ [
+ mo.md("### Pydantic Model Graph (Entity-Relationships)"),
+ mo.mermaid(system_to_mermaid(_ir)),
+ ]
+ )
+ return
+
+
+@app.cell
+def summary(mo):
+ mo.md("""
+ ## Canonical Spectrum
+
+ | Diagram | dim(X) | dim(f) | dim(g) | Form | Character |
+ |---------|--------|--------|--------|------|-----------|
+ | Component | 0 | 0 | 6 | h = g | Stateless API composition |
+ | DFD | 4 | 4 | 7 | h = f . g | Full dynamical pipeline |
+ | ERD | 20 | 9 | 0 | h = f | Pure state (closed system) |
+
+ The three canonical forms span the full spectrum of GDS
+ dynamical character -- from stateless (games-like) through full
+ dynamics (control-like) to pure state (data model). This
+ validates that GDS's canonical decomposition h = f . g is
+ genuinely universal across diagram types.
+ """)
+ return
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/packages/gds-examples/software/gds_ecosystem/test_model.py b/packages/gds-examples/software/gds_ecosystem/test_model.py
new file mode 100644
index 0000000..4b9bf86
--- /dev/null
+++ b/packages/gds-examples/software/gds_ecosystem/test_model.py
@@ -0,0 +1,69 @@
+"""Tests for the GDS Ecosystem self-model."""
+
+from gds import project_canonical, verify
+from software.gds_ecosystem.model import build_model, build_spec, build_system
+
+
+class TestEcosystemModel:
+ def test_model_builds(self):
+ model = build_model()
+ assert model.name == "GDS Ecosystem"
+ assert len(model.components) == 9
+ assert len(model.connectors) == 8
+
+ def test_spec_compiles(self):
+ spec = build_spec()
+ assert spec.name == "GDS Ecosystem"
+ assert len(spec.blocks) == 9
+ errors = spec.validate_spec()
+ assert errors == []
+
+ def test_system_compiles(self):
+ ir = build_system()
+ assert ir.name == "GDS Ecosystem"
+ assert len(ir.blocks) == 9
+
+ def test_canonical_is_stateless(self):
+ """The ecosystem has no state — h = g."""
+ spec = build_spec()
+ canonical = project_canonical(spec)
+ assert canonical.mechanism_blocks == ()
+ assert canonical.state_variables == ()
+ assert len(canonical.boundary_blocks) == 3 # providers
+ assert len(canonical.policy_blocks) == 6 # consumers
+
+ def test_providers_are_boundary(self):
+ """Provider packages become BoundaryActions."""
+ spec = build_spec()
+ canonical = project_canonical(spec)
+ providers = set(canonical.boundary_blocks)
+ assert "gds-framework" in providers
+ assert "gds-sim" in providers
+ assert "gds-continuous" in providers
+
+ def test_consumers_are_policy(self):
+ """Consumer packages become Policies."""
+ spec = build_spec()
+ canonical = project_canonical(spec)
+ consumers = set(canonical.policy_blocks)
+ assert "gds-games" in consumers
+ assert "gds-analysis" in consumers
+ assert "gds-symbolic" in consumers
+
+ def test_verification(self):
+ """Generic verification runs (G-002 expected on boundary/terminal)."""
+ ir = build_system()
+ report = verify(ir)
+ # G-002 fires on boundary (no inputs) and terminal (no outputs)
+ # blocks — expected for a pure dependency graph
+ g002 = [f for f in report.findings if f.check_id == "G-002"]
+ assert len(g002) > 0 # expected failures
+
+ def test_mermaid_output(self):
+ """Mermaid diagram generates without error."""
+ from gds_viz import system_to_mermaid
+
+ ir = build_system()
+ mermaid = system_to_mermaid(ir)
+ assert "gds-framework" in mermaid or "gds_framework" in mermaid
+ assert "GDSSpec" in mermaid