Skip to content

Consolidate package ecosystem from 14 packages to ~6 #143

Description

@rororowyourboat

Summary

The monorepo has grown to 14 packages. While this works for development, it creates scaling issues for publishing, maintenance, and user experience. This issue proposes consolidating to ~6 packages for v0.2.0.

Current State (14 packages)

Package Role Hard deps
gds-framework Core engine pydantic
gds-control Control DSL gds-framework
gds-stockflow Stock-flow DSL gds-framework
gds-games Game theory DSL gds-framework
gds-software Software arch DSL gds-framework
gds-business Business dynamics DSL gds-framework
gds-symbolic SymPy bridge gds-framework, gds-control
gds-sim Discrete-time engine pydantic
gds-continuous Continuous-time ODE engine pydantic
gds-analysis Spec→sim bridge gds-framework, gds-sim
gds-psuu Param sweep/optimization gds-sim, optuna
gds-owl OWL/SHACL formal methods gds-framework, rdflib
gds-viz Visualization gds-framework
gds-examples Tutorials most packages

Problems

  1. Too many thin packages: The 5 domain DSLs follow the identical pattern and depend only on gds-framework. They're plugins, not independent libraries. gds-symbolic is really a gds-control feature.

  2. Two incompatible runtime stacks: gds-sim (discrete) and gds-continuous (continuous) have parallel-but-different APIs. gds-analysis bridges only to gds-sim. Every new analysis capability needs a new bridge package.

  3. N^2 integration problem: Each connection between packages adds maintenance burden. gds-symbolic bridges control→continuous. gds-analysis bridges spec→sim. Future bridges multiply.

  4. Publishing overhead: 14 packages × (pyproject.toml + version + tests + CI + PyPI release) = significant maintenance.

Proposed Structure (~6 packages)

gds-framework          ← core (unchanged)
gds-domains            ← all DSLs as submodules with extras
                         `uv add gds-domains[control,stockflow]`
gds-engine             ← unified runtime: discrete + continuous + analysis
                         `uv add gds-engine[continuous,scipy]`
gds-owl                ← formal methods (standalone, different audience)
gds-viz                ← visualization (standalone)
gds-examples           ← tutorials

gds-domains

Replaces: gds-control, gds-stockflow, gds-games, gds-software, gds-business, gds-symbolic

from gds_domains.control import ControlModel
from gds_domains.stockflow import StockFlowModel
from gds_domains.symbolic import SymbolicControlModel

Optional extras: [games] for typer/jinja2, [symbolic] for sympy.

gds-engine

Replaces: gds-sim, gds-continuous, gds-analysis, gds-psuu

from gds_engine.discrete import Model, Simulation
from gds_engine.continuous import ODEModel, ODESimulation
from gds_engine.analysis import spec_to_model, reachable_set
from gds_engine.psuu import sweep

Optional extras: [continuous] for scipy, [psuu] for optuna.

Key benefit: shared Results interface, unified spec_to_model() that returns discrete or continuous model, bridge problem disappears.

Benefits

  • Users install 1-2 packages instead of 5-6
  • Shared interfaces between discrete and continuous (one Results type, one analysis API)
  • 6 packages to version/publish instead of 14
  • N^2 bridge problem becomes internal module organization
  • Optional extras preserve modularity without package proliferation

When

After current APIs stabilize (post-v0.1.x). The consolidation is mechanical — move files, update imports, redirect old package names. Target: v0.2.0.

Migration Path

  1. Publish v0.1.x of all current packages (freeze current API)
  2. Create consolidated packages with new import paths
  3. Add __init__.py shims in old packages that re-export from new locations with deprecation warnings
  4. Remove old packages in v0.3.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions