Skip to content

Commit 984fe36

Browse files
Merge pull request #111 from BlockScience/dev
Release: merge dev into main
2 parents 41c77d0 + 78812a0 commit 984fe36

File tree

104 files changed

+3649
-480
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+3649
-480
lines changed

docs/business/getting-started.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ model = SupplyChainModel(
6868
SupplyNode(name="Retailer", initial_inventory=100),
6969
],
7070
shipments=[
71-
Shipment(name="F->D", source_node="Factory", target_node="Distributor"),
72-
Shipment(name="D->R", source_node="Distributor", target_node="Retailer"),
71+
Shipment(name="F->D", source="Factory", target="Distributor"),
72+
Shipment(name="D->R", source="Distributor", target="Retailer"),
7373
],
7474
demand_sources=[
75-
DemandSource(name="Customer", target_node="Retailer"),
75+
DemandSource(name="Customer", target="Retailer"),
7676
],
7777
order_policies=[
7878
OrderPolicy(name="Retailer Policy", node="Retailer", inputs=["Retailer"]),

docs/business/guide/diagram-types.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ model = SupplyChainModel(
103103
SupplyNode(name="Retail", initial_inventory=50),
104104
],
105105
shipments=[
106-
Shipment(name="W->R", source_node="Warehouse", target_node="Retail", lead_time=2.0),
106+
Shipment(name="W->R", source="Warehouse", target="Retail", lead_time=2.0),
107107
],
108108
demand_sources=[
109-
DemandSource(name="Customer Demand", target_node="Retail"),
109+
DemandSource(name="Customer Demand", target="Retail"),
110110
],
111111
order_policies=[
112112
OrderPolicy(name="Retail Reorder", node="Retail", inputs=["Retail"]),

docs/business/guide/verification.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ Self-loops (a variable causing itself) are structurally invalid:
6363
| ID | Name | Severity | What it checks |
6464
|----|------|----------|----------------|
6565
| SCN-001 | Network connectivity | WARNING | All nodes reachable via BFS from demand/supply paths |
66-
| SCN-002 | Shipment node validity | ERROR | source_node and target_node exist |
67-
| SCN-003 | Demand target validity | ERROR | target_node exists |
66+
| SCN-002 | Shipment node validity | ERROR | source and target exist |
67+
| SCN-003 | Demand target validity | ERROR | target exists |
6868
| SCN-004 | No orphan nodes | WARNING | Every node in at least one shipment or demand |
6969

7070
### SCN-001: Network Connectivity

docs/business/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ scn = SupplyChainModel(
7878
SupplyNode(name="Retailer", initial_inventory=100),
7979
],
8080
shipments=[
81-
Shipment(name="F->R", source_node="Factory", target_node="Retailer"),
81+
Shipment(name="F->R", source="Factory", target="Retailer"),
8282
],
8383
demand_sources=[
84-
DemandSource(name="Customer", target_node="Retailer"),
84+
DemandSource(name="Customer", target="Retailer"),
8585
],
8686
order_policies=[
8787
OrderPolicy(name="Reorder", node="Retailer", inputs=["Retailer"]),

docs/framework/ecosystem.md

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,53 @@ The GDS ecosystem is a family of composable packages for specifying, visualizing
44

55
## Packages
66

7-
| Package | Description | Docs | PyPI |
8-
|---|---|---|---|
9-
| **gds-framework** | Foundation — typed compositional specifications | [Docs](https://blockscience.github.io/gds-framework) | [PyPI](https://pypi.org/project/gds-framework/) |
10-
| **gds-viz** | Mermaid diagram renderers for GDS specifications | [Docs](https://blockscience.github.io/gds-viz) | [PyPI](https://pypi.org/project/gds-viz/) |
11-
| **gds-games** | Typed DSL for compositional game theory | [Docs](https://blockscience.github.io/gds-games) | [PyPI](https://pypi.org/project/gds-games/) |
12-
| **gds-examples** | Six tutorial models demonstrating every framework feature | [Docs](https://blockscience.github.io/gds-examples) | [PyPI](https://pypi.org/project/gds-examples/) |
7+
| Package | Import | Description |
8+
|---|---|---|
9+
| **gds-framework** | `gds` | Core engine — blocks, composition algebra, compiler, verification |
10+
| **gds-viz** | `gds_viz` | Mermaid diagram renderers for GDS specifications |
11+
| **gds-stockflow** | `stockflow` | Declarative stock-flow DSL over GDS semantics |
12+
| **gds-control** | `gds_control` | State-space control DSL over GDS semantics |
13+
| **gds-games** | `ogs` | Typed DSL for compositional game theory (Open Games) |
14+
| **gds-software** | `gds_software` | Software architecture DSL (DFD, state machine, C4, ERD, etc.) |
15+
| **gds-business** | `gds_business` | Business dynamics DSL (CLD, supply chain, value stream map) |
16+
| **gds-sim** | `gds_sim` | Simulation engine (standalone, Pydantic-only) |
17+
| **gds-examples** || Tutorial models demonstrating framework features |
1318

1419
## Dependency Graph
1520

1621
```mermaid
1722
graph TD
1823
F[gds-framework] --> V[gds-viz]
1924
F --> G[gds-games]
25+
F --> SF[gds-stockflow]
26+
F --> C[gds-control]
27+
F --> SW[gds-software]
28+
F --> B[gds-business]
2029
F --> E[gds-examples]
2130
V --> E
31+
G --> E
32+
SF --> E
33+
C --> E
34+
SW --> E
35+
B --> E
36+
SIM[gds-sim]
2237
```
2338

2439
## Architecture
2540

2641
```
27-
gds-framework (foundation)
28-
29-
│ Domain-neutral composition algebra, typed spaces,
30-
│ state model, verification engine, flat IR compiler.
31-
32-
├── gds-viz (visualization)
33-
│ └── 6 Mermaid diagram views of GDS specifications
34-
35-
├── gds-games (game theory DSL)
36-
│ └── Open games, pattern composition, verification, reports, CLI
37-
38-
└── gds-examples (tutorials)
39-
└── 6 complete domain models with tests and visualizations
42+
gds-framework ← core engine (no GDS dependencies)
43+
44+
gds-viz ← visualization (depends on gds-framework)
45+
gds-games ← game theory DSL (depends on gds-framework)
46+
gds-stockflow ← stock-flow DSL (depends on gds-framework)
47+
gds-control ← control systems DSL (depends on gds-framework)
48+
gds-software ← software architecture DSL (depends on gds-framework)
49+
gds-business ← business dynamics DSL (depends on gds-framework)
50+
51+
gds-examples ← tutorials (depends on gds-framework + gds-viz + all DSLs)
52+
53+
gds-sim ← simulation engine (standalone — no gds-framework dep, only pydantic)
4054
```
4155

4256
## Links

docs/framework/guide/architecture.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ Blocks with bidirectional typed interfaces, composed via four operators (`>>`, `
1010

1111
TypeDef with runtime constraints, typed Spaces, Entities with StateVariables, Block roles (BoundaryAction/Policy/Mechanism/ControlAction), GDSSpec registry, ParameterSchema (Θ), canonical projection (CanonicalGDS), Tagged mixin, semantic verification (SC-001..SC-007), SpecQuery for dependency analysis, and JSON serialization.
1212

13+
### Why Two Layers?
14+
15+
Layer 0 is domain-neutral by design. It knows about blocks with typed ports, four composition operators, and structural topology — nothing about games, stocks, or controllers. This neutrality is what allows five different DSLs to compile to the same IR.
16+
17+
Domain judgment enters at Layer 1: when a modeler decides "this is a Mechanism, not a Policy" or "this variable is part of the system state." Layer 0 cannot make these decisions because they require knowledge of the problem being modeled. The three-stage compiler (flatten, wire, extract hierarchy) is pure algebra. The role annotations (BoundaryAction, Policy, Mechanism) are domain commitments.
18+
19+
This separation means Layer 0 specifications stay verifiable without knowing anything about the domain — they can be composed and checked formally. Layer 1 adds the meaning that makes a specification useful for a particular problem.
20+
1321
## Foundation + Domain Packages
1422

1523
```

docs/guides/best-practices.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ Policy(name="Process", ...)
4949

5050
---
5151

52+
## Modeling Decisions
53+
54+
Before writing any composition, three choices shape the entire specification:
55+
56+
**Role assignment.** Which processes become BoundaryActions (exogenous inputs), Policies (decision/observation logic), or Mechanisms (state updates)? This determines the canonical decomposition `h = f . g`. A temperature sensor could be a BoundaryAction (external data arrives) or a Policy (compute reading from state) — the right answer depends on what you want to verify, not on the physics alone.
57+
58+
**State identification.** Which quantities are state variables and which are derived? An SIR model with three state variables (S, I, R) produces a different canonical form than one that derives R = N - S - I and tracks only two. Finer state identification lets SC-001 catch orphan variables; coarser identification creates fewer obligations.
59+
60+
**Block granularity.** One large block or several small ones? The algebra composes anything with compatible ports, but finer granularity makes the [hierarchy tree](../framework/guide/composition.md) more informative and gives verification more to check. A single-block model passes all structural checks trivially.
61+
62+
These are design choices, not discoveries. Different choices lead to different verifiable specifications — neither is "wrong." Start from the question you want to answer ("Does this system avoid write conflicts on state?") and design roles backward from there.
63+
64+
---
65+
5266
## Composition Patterns
5367

5468
### The Three-Tier Pipeline

docs/guides/choosing-a-dsl.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ Five domain-specific languages compile to the same GDS core. This guide helps yo
44

55
---
66

7+
## Starting from the Problem
8+
9+
The Decision Matrix below is a technical reference — it assumes you already know your primitives. In practice, most modelers start earlier: with a domain question.
10+
11+
The same system can often be modeled with more than one DSL. An epidemic could be stockflow (if you care about accumulation rates) or raw framework (if you just need a state transition). A supply chain could be stockflow (stocks and flows), CLD (causal influences), or SCN (inventory and topology). The DSL choice depends on **what you want to verify**, not just what domain you are in.
12+
13+
The natural workflow is: **Problem → What do I want to check? → DSL**. Once you pick a DSL, roles and block structure follow more naturally because the DSL embeds domain conventions about what matters.
14+
15+
---
16+
717
## Decision Matrix
818

919
| If your system has... | Use | Package | Why |

docs/guides/getting-started.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -425,30 +425,30 @@ From here, explore the [example models](../examples/index.md) or the [Rosetta St
425425
## Interactive Notebook
426426

427427
/// marimo-embed-file
428-
filepath: packages/gds-examples/guides/getting_started/notebook.py
428+
filepath: packages/gds-examples/notebooks/getting_started.py
429429
height: 800px
430430
mode: read
431431
///
432432

433433
To run the notebook locally:
434434

435435
```bash
436-
uv run marimo run packages/gds-examples/guides/getting_started/notebook.py
436+
uv run marimo run packages/gds-examples/notebooks/getting_started.py
437437
```
438438

439439
Run the test suite:
440440

441441
```bash
442-
uv run --package gds-examples pytest packages/gds-examples/guides/getting_started/ -v
442+
uv run --package gds-examples pytest packages/gds-examples/tests/test_getting_started.py -v
443443
```
444444

445445
## Source Files
446446

447447
| File | Purpose |
448448
|------|---------|
449-
| [`stage1_minimal.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/guides/getting_started/stage1_minimal.py) | Minimal heater model |
450-
| [`stage2_feedback.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/guides/getting_started/stage2_feedback.py) | Feedback loop with policies |
451-
| [`stage3_dsl.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/guides/getting_started/stage3_dsl.py) | gds-control DSL version |
452-
| [`stage4_verify_viz.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/guides/getting_started/stage4_verify_viz.py) | Verification and visualization |
453-
| [`stage5_query.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/guides/getting_started/stage5_query.py) | SpecQuery API |
454-
| [`notebook.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/guides/getting_started/notebook.py) | Interactive marimo notebook |
449+
| [`stage1_minimal.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/gds_examples/getting_started/stage1_minimal.py) | Minimal heater model |
450+
| [`stage2_feedback.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/gds_examples/getting_started/stage2_feedback.py) | Feedback loop with policies |
451+
| [`stage3_dsl.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/gds_examples/getting_started/stage3_dsl.py) | gds-control DSL version |
452+
| [`stage4_verify_viz.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/gds_examples/getting_started/stage4_verify_viz.py) | Verification and visualization |
453+
| [`stage5_query.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/gds_examples/getting_started/stage5_query.py) | SpecQuery API |
454+
| [`getting_started.py`](https://github.com/BlockScience/gds-core/blob/main/packages/gds-examples/notebooks/getting_started.py) | Interactive marimo notebook |

docs/guides/interoperability.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ This validates GDS as an **interoperability substrate**, not just a modeling fra
235235
### Nash Equilibrium Analysis
236236

237237
/// marimo-embed-file
238-
filepath: packages/gds-examples/guides/nash_equilibrium/notebook.py
238+
filepath: packages/gds-examples/notebooks/nash_equilibrium.py
239239
height: 800px
240240
mode: read
241241
///
@@ -244,8 +244,7 @@ To run locally:
244244

245245
```bash
246246
uv sync --all-packages --extra nash
247-
cd packages/gds-examples && \
248-
uv run marimo run guides/nash_equilibrium/notebook.py
247+
uv run marimo run packages/gds-examples/notebooks/nash_equilibrium.py
249248
```
250249

251250
```bash
@@ -257,16 +256,15 @@ uv run --package gds-examples pytest \
257256
### Evolution of Trust Simulation
258257

259258
/// marimo-embed-file
260-
filepath: packages/gds-examples/guides/evolution_of_trust/notebook.py
259+
filepath: packages/gds-examples/notebooks/evolution_of_trust.py
261260
height: 800px
262261
mode: read
263262
///
264263

265264
To run locally:
266265

267266
```bash
268-
cd packages/gds-examples && \
269-
uv run marimo run guides/evolution_of_trust/notebook.py
267+
uv run marimo run packages/gds-examples/notebooks/evolution_of_trust.py
270268
```
271269

272270
```bash
@@ -283,8 +281,8 @@ uv run --package gds-examples pytest \
283281
| `games/evolution_of_trust/model.py` | OGS structure with Nicky Case payoffs |
284282
| `games/evolution_of_trust/strategies.py` | 8 strategy implementations |
285283
| `games/evolution_of_trust/tournament.py` | Match, tournament, evolutionary dynamics |
286-
| `guides/nash_equilibrium/notebook.py` | Interactive Nash analysis notebook |
287-
| `guides/evolution_of_trust/notebook.py` | Interactive simulation notebook |
284+
| `notebooks/nash_equilibrium.py` | Interactive Nash analysis notebook |
285+
| `notebooks/evolution_of_trust.py` | Interactive simulation notebook |
288286

289287
All paths relative to `packages/gds-examples/`.
290288

0 commit comments

Comments
 (0)