dreamforge 0.2.0__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.
- dreamforge-0.2.0/LICENSE +21 -0
- dreamforge-0.2.0/PKG-INFO +156 -0
- dreamforge-0.2.0/README.md +111 -0
- dreamforge-0.2.0/pyproject.toml +72 -0
- dreamforge-0.2.0/setup.cfg +4 -0
- dreamforge-0.2.0/src/dreamforge/__init__.py +8 -0
- dreamforge-0.2.0/src/dreamforge/core/__init__.py +6 -0
- dreamforge-0.2.0/src/dreamforge/core/config.py +142 -0
- dreamforge-0.2.0/src/dreamforge/core/models/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/core/models/dream_context.py +323 -0
- dreamforge-0.2.0/src/dreamforge/core/models/events.py +310 -0
- dreamforge-0.2.0/src/dreamforge/core/models/memory_graph.py +385 -0
- dreamforge-0.2.0/src/dreamforge/core/models/neurochemistry.py +124 -0
- dreamforge-0.2.0/src/dreamforge/core/models/sleep_cycle.py +394 -0
- dreamforge-0.2.0/src/dreamforge/core/provenance/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/core/provenance/clock.py +38 -0
- dreamforge-0.2.0/src/dreamforge/core/providers/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/core/providers/narrative.py +230 -0
- dreamforge-0.2.0/src/dreamforge/core/scoring/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/core/scoring/bizarreness.py +87 -0
- dreamforge-0.2.0/src/dreamforge/core/serialization/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/core/serialization/dqcj.py +283 -0
- dreamforge-0.2.0/src/dreamforge/demo.py +120 -0
- dreamforge-0.2.0/src/dreamforge/integrations/__init__.py +5 -0
- dreamforge-0.2.0/src/dreamforge/integrations/anthropic_compat.py +174 -0
- dreamforge-0.2.0/src/dreamforge/integrations/errors.py +33 -0
- dreamforge-0.2.0/src/dreamforge/integrations/openai_compat.py +177 -0
- dreamforge-0.2.0/src/dreamforge/integrations/retry.py +72 -0
- dreamforge-0.2.0/src/dreamforge/integrations/transport.py +69 -0
- dreamforge-0.2.0/src/dreamforge/simulation/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/simulation/counterfactual.py +178 -0
- dreamforge-0.2.0/src/dreamforge/simulation/engine.py +310 -0
- dreamforge-0.2.0/src/dreamforge/simulation/ensemble.py +135 -0
- dreamforge-0.2.0/src/dreamforge/simulation/export_import.py +471 -0
- dreamforge-0.2.0/src/dreamforge/simulation/report.py +153 -0
- dreamforge-0.2.0/src/dreamforge/simulation/run_repository.py +176 -0
- dreamforge-0.2.0/src/dreamforge/simulation/sweeps.py +133 -0
- dreamforge-0.2.0/src/dreamforge/visualization/__init__.py +1 -0
- dreamforge-0.2.0/src/dreamforge/visualization/dashboard.py +183 -0
- dreamforge-0.2.0/src/dreamforge/visualization/loader.py +68 -0
- dreamforge-0.2.0/src/dreamforge.egg-info/PKG-INFO +156 -0
- dreamforge-0.2.0/src/dreamforge.egg-info/SOURCES.txt +44 -0
- dreamforge-0.2.0/src/dreamforge.egg-info/dependency_links.txt +1 -0
- dreamforge-0.2.0/src/dreamforge.egg-info/entry_points.txt +3 -0
- dreamforge-0.2.0/src/dreamforge.egg-info/requires.txt +15 -0
- dreamforge-0.2.0/src/dreamforge.egg-info/top_level.txt +1 -0
dreamforge-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JToSound
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dreamforge
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Deterministic, offline sandbox for non-clinical sleep/dream simulation proxies (research and visualization simulator; no medical claims).
|
|
5
|
+
Author: JToSound
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 JToSound
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Requires-Python: >=3.11
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: numpy<3,>=2
|
|
32
|
+
Requires-Dist: pydantic<3,>=2.7
|
|
33
|
+
Requires-Dist: networkx<4,>=3.3
|
|
34
|
+
Provides-Extra: dashboard
|
|
35
|
+
Requires-Dist: streamlit>=1.37; extra == "dashboard"
|
|
36
|
+
Requires-Dist: plotly>=5.22; extra == "dashboard"
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest>=9.0.3; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-cov<7,>=5; extra == "dev"
|
|
40
|
+
Requires-Dist: hypothesis<7,>=6; extra == "dev"
|
|
41
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
42
|
+
Requires-Dist: black>=24; extra == "dev"
|
|
43
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# DreamForge AI
|
|
47
|
+
|
|
48
|
+
> DreamForge is a research and visualization simulator. It does not measure brains, diagnose conditions, predict dreams, infer psychological meaning, or provide medical advice.
|
|
49
|
+
|
|
50
|
+
An open-source, deterministic, offline sandbox for simulating explicit,
|
|
51
|
+
configurable, **non-clinical proxies** related to sleep regulation, sleep-stage
|
|
52
|
+
dynamics, normalized neuromodulatory patterns, synthetic-memory graph
|
|
53
|
+
selection, and structured dream-context features — under active construction
|
|
54
|
+
toward the milestone plan in [`MASTER_PROMPT.md`](MASTER_PROMPT.md).
|
|
55
|
+
|
|
56
|
+
## Status
|
|
57
|
+
|
|
58
|
+
First execution slice + M1 (complete) and M2 groundwork: deterministic core with
|
|
59
|
+
an 8-hour (960 × 30 s epoch) offline trace, event sourcing, DQCJ-1 canonical
|
|
60
|
+
serialization, hash-verified exports, structured dream context/features/score,
|
|
61
|
+
and the mandatory offline narrative provider with labeled report blocks. See
|
|
62
|
+
[`ARCHITECTURE.md`](ARCHITECTURE.md), [`RESEARCH.md`](RESEARCH.md),
|
|
63
|
+
[`LIMITATIONS.md`](LIMITATIONS.md), and `docs/`.
|
|
64
|
+
|
|
65
|
+
**Not yet built** (by explicit scope control): API, plugins, notebooks,
|
|
66
|
+
streaming/tool-use adapter features.
|
|
67
|
+
|
|
68
|
+
## Optional: local / OpenAI-compatible narrative provider (opt-in)
|
|
69
|
+
|
|
70
|
+
The offline mock is always the default. To use a local model via Ollama's
|
|
71
|
+
OpenAI-compatible endpoint (or any `/chat/completions` service), construct the
|
|
72
|
+
adapter explicitly in your own script — nothing is enabled by configuration
|
|
73
|
+
alone:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from dreamforge.core.providers.narrative import NarrativeRequest
|
|
77
|
+
from dreamforge.integrations.openai_compat import OpenAICompatConfig, OpenAICompatProvider
|
|
78
|
+
from dreamforge.integrations.transport import UrllibTransport
|
|
79
|
+
|
|
80
|
+
config = OpenAICompatConfig(
|
|
81
|
+
base_url="http://127.0.0.1:11434/v1", # Ollama loopback example
|
|
82
|
+
model="llama3.2:3b",
|
|
83
|
+
timeout_seconds=20,
|
|
84
|
+
max_retries=2,
|
|
85
|
+
)
|
|
86
|
+
provider = OpenAICompatProvider(config, UrllibTransport())
|
|
87
|
+
response = provider.generate(request) # request = validated NarrativeRequest
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Guarantees (ADR 0005): allowlisted projection only; strict response schema;
|
|
91
|
+
per-attempt timeout; bounded retries then fail-closed; errors redacted to
|
|
92
|
+
status code + response hash; every response labeled `generative_interpretation`.
|
|
93
|
+
|
|
94
|
+
An Anthropic-native adapter with the same guarantees ships alongside it
|
|
95
|
+
(`AnthropicCompatProvider` — messages API, `x-api-key` +
|
|
96
|
+
`anthropic-version` headers, content-block extraction); both share one
|
|
97
|
+
vetted bounded-retry/redaction implementation (`integrations/retry.py`).
|
|
98
|
+
|
|
99
|
+
## Dashboard (optional extras)
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
".venv/Scripts/python.exe" -m pip install -c constraints.txt streamlit plotly
|
|
103
|
+
".venv/Scripts/python.exe" -m streamlit run src/dreamforge/visualization/dashboard.py -- exports/demo_8h
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Renders verified exports only; accessibility/theme documentation in
|
|
107
|
+
[`DASHBOARD.md`](DASHBOARD.md).
|
|
108
|
+
|
|
109
|
+
## What it simulates (and what that means)
|
|
110
|
+
|
|
111
|
+
- Conceptual two-process-inspired sleep-regulation equations (homeostatic "S"
|
|
112
|
+
pressure + sinusoidal circadian proxy) — mathematical constructs, not physiology.
|
|
113
|
+
- A semi-Markov Wake/N1/N2/N3/REM stage process at 30-second resolution —
|
|
114
|
+
explicitly *not* PSG scoring.
|
|
115
|
+
- Four normalized `[0,1]` neuromodulatory proxy indices — qualitative synthetic
|
|
116
|
+
values, never concentrations or measurements.
|
|
117
|
+
- Selection over a synthetic directed weighted memory graph — graph selection,
|
|
118
|
+
not neural replay.
|
|
119
|
+
- Deterministic structured features and scores derived only from the above.
|
|
120
|
+
|
|
121
|
+
All parameters carry evidence grades (`assumption`, `synthetic_demo`, …) in
|
|
122
|
+
[`docs/scientific_model/claim_registry.yaml`](docs/scientific_model/claim_registry.yaml).
|
|
123
|
+
No empirical or clinical claim is made anywhere in this repository.
|
|
124
|
+
|
|
125
|
+
## Quick start (offline demo)
|
|
126
|
+
|
|
127
|
+
Requires Python 3.11+ (developed on 3.12, Windows). No network egress at runtime;
|
|
128
|
+
install needs PyPI once.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
python -m venv .venv
|
|
132
|
+
".venv/Scripts/python.exe" -m pip install -c constraints.txt -e . # Windows path; use .venv/bin elsewhere
|
|
133
|
+
".venv/Scripts/python.exe" -m dreamforge.demo # runs examples/configs/demo_8h.json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The demo validates its configuration, runs 960 epochs, verifies stage-transition
|
|
137
|
+
legality, writes an export under `exports/demo_8h/`
|
|
138
|
+
(`events.ndjson` + `manifest.json`), re-imports it, and re-verifies all hashes.
|
|
139
|
+
|
|
140
|
+
## Development checks
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
".venv/Scripts/python.exe" -m pytest -q # tests
|
|
144
|
+
".venv/Scripts/python.exe" -m pytest -q --cov=src/dreamforge --cov-report=term-missing
|
|
145
|
+
".venv/Scripts/python.exe" -m ruff check src tests examples # lint
|
|
146
|
+
".venv/Scripts/python.exe" -m black --check src tests examples # format-check
|
|
147
|
+
".venv/Scripts/python.exe" -m mypy src/dreamforge/core # typecheck
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Repository layout
|
|
151
|
+
|
|
152
|
+
See [`ARCHITECTURE.md`](ARCHITECTURE.md) for the diagram and component table.
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT — see [`LICENSE`](LICENSE). Copyright (c) 2026 JToSound.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# DreamForge AI
|
|
2
|
+
|
|
3
|
+
> DreamForge is a research and visualization simulator. It does not measure brains, diagnose conditions, predict dreams, infer psychological meaning, or provide medical advice.
|
|
4
|
+
|
|
5
|
+
An open-source, deterministic, offline sandbox for simulating explicit,
|
|
6
|
+
configurable, **non-clinical proxies** related to sleep regulation, sleep-stage
|
|
7
|
+
dynamics, normalized neuromodulatory patterns, synthetic-memory graph
|
|
8
|
+
selection, and structured dream-context features — under active construction
|
|
9
|
+
toward the milestone plan in [`MASTER_PROMPT.md`](MASTER_PROMPT.md).
|
|
10
|
+
|
|
11
|
+
## Status
|
|
12
|
+
|
|
13
|
+
First execution slice + M1 (complete) and M2 groundwork: deterministic core with
|
|
14
|
+
an 8-hour (960 × 30 s epoch) offline trace, event sourcing, DQCJ-1 canonical
|
|
15
|
+
serialization, hash-verified exports, structured dream context/features/score,
|
|
16
|
+
and the mandatory offline narrative provider with labeled report blocks. See
|
|
17
|
+
[`ARCHITECTURE.md`](ARCHITECTURE.md), [`RESEARCH.md`](RESEARCH.md),
|
|
18
|
+
[`LIMITATIONS.md`](LIMITATIONS.md), and `docs/`.
|
|
19
|
+
|
|
20
|
+
**Not yet built** (by explicit scope control): API, plugins, notebooks,
|
|
21
|
+
streaming/tool-use adapter features.
|
|
22
|
+
|
|
23
|
+
## Optional: local / OpenAI-compatible narrative provider (opt-in)
|
|
24
|
+
|
|
25
|
+
The offline mock is always the default. To use a local model via Ollama's
|
|
26
|
+
OpenAI-compatible endpoint (or any `/chat/completions` service), construct the
|
|
27
|
+
adapter explicitly in your own script — nothing is enabled by configuration
|
|
28
|
+
alone:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from dreamforge.core.providers.narrative import NarrativeRequest
|
|
32
|
+
from dreamforge.integrations.openai_compat import OpenAICompatConfig, OpenAICompatProvider
|
|
33
|
+
from dreamforge.integrations.transport import UrllibTransport
|
|
34
|
+
|
|
35
|
+
config = OpenAICompatConfig(
|
|
36
|
+
base_url="http://127.0.0.1:11434/v1", # Ollama loopback example
|
|
37
|
+
model="llama3.2:3b",
|
|
38
|
+
timeout_seconds=20,
|
|
39
|
+
max_retries=2,
|
|
40
|
+
)
|
|
41
|
+
provider = OpenAICompatProvider(config, UrllibTransport())
|
|
42
|
+
response = provider.generate(request) # request = validated NarrativeRequest
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Guarantees (ADR 0005): allowlisted projection only; strict response schema;
|
|
46
|
+
per-attempt timeout; bounded retries then fail-closed; errors redacted to
|
|
47
|
+
status code + response hash; every response labeled `generative_interpretation`.
|
|
48
|
+
|
|
49
|
+
An Anthropic-native adapter with the same guarantees ships alongside it
|
|
50
|
+
(`AnthropicCompatProvider` — messages API, `x-api-key` +
|
|
51
|
+
`anthropic-version` headers, content-block extraction); both share one
|
|
52
|
+
vetted bounded-retry/redaction implementation (`integrations/retry.py`).
|
|
53
|
+
|
|
54
|
+
## Dashboard (optional extras)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
".venv/Scripts/python.exe" -m pip install -c constraints.txt streamlit plotly
|
|
58
|
+
".venv/Scripts/python.exe" -m streamlit run src/dreamforge/visualization/dashboard.py -- exports/demo_8h
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Renders verified exports only; accessibility/theme documentation in
|
|
62
|
+
[`DASHBOARD.md`](DASHBOARD.md).
|
|
63
|
+
|
|
64
|
+
## What it simulates (and what that means)
|
|
65
|
+
|
|
66
|
+
- Conceptual two-process-inspired sleep-regulation equations (homeostatic "S"
|
|
67
|
+
pressure + sinusoidal circadian proxy) — mathematical constructs, not physiology.
|
|
68
|
+
- A semi-Markov Wake/N1/N2/N3/REM stage process at 30-second resolution —
|
|
69
|
+
explicitly *not* PSG scoring.
|
|
70
|
+
- Four normalized `[0,1]` neuromodulatory proxy indices — qualitative synthetic
|
|
71
|
+
values, never concentrations or measurements.
|
|
72
|
+
- Selection over a synthetic directed weighted memory graph — graph selection,
|
|
73
|
+
not neural replay.
|
|
74
|
+
- Deterministic structured features and scores derived only from the above.
|
|
75
|
+
|
|
76
|
+
All parameters carry evidence grades (`assumption`, `synthetic_demo`, …) in
|
|
77
|
+
[`docs/scientific_model/claim_registry.yaml`](docs/scientific_model/claim_registry.yaml).
|
|
78
|
+
No empirical or clinical claim is made anywhere in this repository.
|
|
79
|
+
|
|
80
|
+
## Quick start (offline demo)
|
|
81
|
+
|
|
82
|
+
Requires Python 3.11+ (developed on 3.12, Windows). No network egress at runtime;
|
|
83
|
+
install needs PyPI once.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
python -m venv .venv
|
|
87
|
+
".venv/Scripts/python.exe" -m pip install -c constraints.txt -e . # Windows path; use .venv/bin elsewhere
|
|
88
|
+
".venv/Scripts/python.exe" -m dreamforge.demo # runs examples/configs/demo_8h.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The demo validates its configuration, runs 960 epochs, verifies stage-transition
|
|
92
|
+
legality, writes an export under `exports/demo_8h/`
|
|
93
|
+
(`events.ndjson` + `manifest.json`), re-imports it, and re-verifies all hashes.
|
|
94
|
+
|
|
95
|
+
## Development checks
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
".venv/Scripts/python.exe" -m pytest -q # tests
|
|
99
|
+
".venv/Scripts/python.exe" -m pytest -q --cov=src/dreamforge --cov-report=term-missing
|
|
100
|
+
".venv/Scripts/python.exe" -m ruff check src tests examples # lint
|
|
101
|
+
".venv/Scripts/python.exe" -m black --check src tests examples # format-check
|
|
102
|
+
".venv/Scripts/python.exe" -m mypy src/dreamforge/core # typecheck
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Repository layout
|
|
106
|
+
|
|
107
|
+
See [`ARCHITECTURE.md`](ARCHITECTURE.md) for the diagram and component table.
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT — see [`LICENSE`](LICENSE). Copyright (c) 2026 JToSound.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dreamforge"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Deterministic, offline sandbox for non-clinical sleep/dream simulation proxies (research and visualization simulator; no medical claims)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "JToSound" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"numpy>=2,<3",
|
|
15
|
+
"pydantic>=2.7,<3",
|
|
16
|
+
"networkx>=3.3,<4",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
dashboard = [
|
|
21
|
+
"streamlit>=1.37",
|
|
22
|
+
"plotly>=5.22",
|
|
23
|
+
]
|
|
24
|
+
dev = [
|
|
25
|
+
"pytest>=9.0.3",
|
|
26
|
+
"pytest-cov>=5,<7",
|
|
27
|
+
"hypothesis>=6,<7",
|
|
28
|
+
"ruff>=0.6",
|
|
29
|
+
"black>=24",
|
|
30
|
+
"mypy>=1.10",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
dreamforge-demo = "dreamforge.demo:main"
|
|
35
|
+
dreamforge-dashboard = "dreamforge.visualization.dashboard:main"
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["src"]
|
|
39
|
+
|
|
40
|
+
[tool.ruff]
|
|
41
|
+
line-length = 100
|
|
42
|
+
target-version = "py311"
|
|
43
|
+
src = ["src", "tests", "examples"]
|
|
44
|
+
|
|
45
|
+
[tool.ruff.lint]
|
|
46
|
+
select = ["E", "W", "F", "I", "B", "UP"]
|
|
47
|
+
ignore = []
|
|
48
|
+
|
|
49
|
+
[tool.black]
|
|
50
|
+
line-length = 100
|
|
51
|
+
target-version = ["py311"]
|
|
52
|
+
|
|
53
|
+
[tool.mypy]
|
|
54
|
+
strict = true
|
|
55
|
+
files = ["src/dreamforge/core", "src/dreamforge/integrations"]
|
|
56
|
+
# Checked under 3.12 semantics because numpy>=2.5 stubs use 3.12-only syntax;
|
|
57
|
+
# the package runtime floor stays >=3.11 and no source uses 3.12-only features.
|
|
58
|
+
python_version = "3.12"
|
|
59
|
+
warn_unreachable = true
|
|
60
|
+
show_error_codes = true
|
|
61
|
+
|
|
62
|
+
[[tool.mypy.overrides]]
|
|
63
|
+
module = "networkx.*"
|
|
64
|
+
ignore_missing_imports = true
|
|
65
|
+
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
testpaths = ["tests"]
|
|
68
|
+
addopts = "-ra"
|
|
69
|
+
markers = [
|
|
70
|
+
"integration: long-running deterministic integration tests",
|
|
71
|
+
"property: hypothesis property-based tests",
|
|
72
|
+
]
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""DreamForge — deterministic research and visualization simulator.
|
|
2
|
+
|
|
3
|
+
DreamForge is a research and visualization simulator. It does not measure
|
|
4
|
+
brains, diagnose conditions, predict dreams, infer psychological meaning, or
|
|
5
|
+
provide medical advice.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "0.2.0"
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Strict simulation configuration loading (fail closed).
|
|
2
|
+
|
|
3
|
+
The configuration is the only external input to a run. It is validated into
|
|
4
|
+
frozen Pydantic models before any engine object is constructed; any violation
|
|
5
|
+
raises :class:`ConfigError` with a machine-readable ``code``. No environment
|
|
6
|
+
variables, clocks, or network access participate.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
15
|
+
|
|
16
|
+
from dreamforge.core.models.events import ALL_STAGES, StageName
|
|
17
|
+
from dreamforge.core.models.memory_graph import GraphSpecConfig, ReplaySelectorConfig
|
|
18
|
+
from dreamforge.core.models.neurochemistry import NeurochemistryConfig
|
|
19
|
+
from dreamforge.core.models.sleep_cycle import (
|
|
20
|
+
CircadianConfig,
|
|
21
|
+
DwellDistribution,
|
|
22
|
+
ProcessSConfig,
|
|
23
|
+
TransitionMatrixConfig,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
#: Hard limits guarding against oversized/hostile configs (section 6.3).
|
|
27
|
+
MAX_EPOCH_SECONDS = 3600.0
|
|
28
|
+
MIN_EPOCH_SECONDS = 1.0
|
|
29
|
+
MAX_TOTAL_TICKS = 100_000
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ConfigError(ValueError):
|
|
33
|
+
"""Raised when configuration fails validation; ``code`` is stable."""
|
|
34
|
+
|
|
35
|
+
def __init__(self, code: str, message: str) -> None:
|
|
36
|
+
super().__init__(message)
|
|
37
|
+
self.code = code
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ReplayPolicyConfig(BaseModel):
|
|
41
|
+
"""Where replay selection gets its graph and its policy."""
|
|
42
|
+
|
|
43
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
44
|
+
|
|
45
|
+
synthetic_graph: GraphSpecConfig = Field(default_factory=GraphSpecConfig)
|
|
46
|
+
selector: ReplaySelectorConfig = Field(default_factory=ReplaySelectorConfig)
|
|
47
|
+
replay_every_n_epochs: int = Field(default=8, ge=1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class SimulationConfig(BaseModel):
|
|
51
|
+
"""Fully validated run configuration (immutable after load)."""
|
|
52
|
+
|
|
53
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
|
54
|
+
|
|
55
|
+
schema_version: str = Field(pattern=r"^\d+\.\d+$")
|
|
56
|
+
run_id: str = Field(min_length=8, max_length=64, pattern=r"^[A-Za-z0-9._-]+$")
|
|
57
|
+
run_seed: int = Field(ge=0, le=2**64 - 1)
|
|
58
|
+
epoch_seconds: float = Field(default=30.0)
|
|
59
|
+
total_ticks: int = Field(ge=1)
|
|
60
|
+
initial_stage: StageName = "Wake"
|
|
61
|
+
process_s: ProcessSConfig = Field(default_factory=ProcessSConfig)
|
|
62
|
+
circadian: CircadianConfig = Field(default_factory=CircadianConfig)
|
|
63
|
+
transitions: TransitionMatrixConfig
|
|
64
|
+
dwells: dict[StageName, DwellDistribution]
|
|
65
|
+
chemistry: NeurochemistryConfig
|
|
66
|
+
replay_policy: ReplayPolicyConfig = Field(default_factory=ReplayPolicyConfig)
|
|
67
|
+
|
|
68
|
+
@field_validator("epoch_seconds")
|
|
69
|
+
@classmethod
|
|
70
|
+
def _epoch_bounds(cls, value: float) -> float:
|
|
71
|
+
if not MIN_EPOCH_SECONDS <= value <= MAX_EPOCH_SECONDS:
|
|
72
|
+
msg = f"epoch_seconds must be within " f"[{MIN_EPOCH_SECONDS}, {MAX_EPOCH_SECONDS}]"
|
|
73
|
+
raise ValueError(msg)
|
|
74
|
+
return value
|
|
75
|
+
|
|
76
|
+
@field_validator("total_ticks")
|
|
77
|
+
@classmethod
|
|
78
|
+
def _ticks_cap(cls, value: int) -> int:
|
|
79
|
+
if value > MAX_TOTAL_TICKS:
|
|
80
|
+
msg = f"total_ticks exceeds MAX_TOTAL_TICKS={MAX_TOTAL_TICKS}"
|
|
81
|
+
raise ValueError(msg)
|
|
82
|
+
return value
|
|
83
|
+
|
|
84
|
+
@model_validator(mode="after")
|
|
85
|
+
def _dwell_support(self) -> SimulationConfig:
|
|
86
|
+
missing = [s for s in ALL_STAGES if s not in self.dwells]
|
|
87
|
+
if missing:
|
|
88
|
+
msg = f"dwells missing stages: {missing}"
|
|
89
|
+
raise ValueError(msg)
|
|
90
|
+
for stage, dwell in self.dwells.items():
|
|
91
|
+
longest = dwell.min_epochs + len(dwell.weights) - 1
|
|
92
|
+
if longest > self.total_ticks:
|
|
93
|
+
msg = f"dwell support for {stage} exceeds total_ticks"
|
|
94
|
+
raise ValueError(msg)
|
|
95
|
+
return self
|
|
96
|
+
|
|
97
|
+
def simulated_time_minutes(self, tick: int) -> float:
|
|
98
|
+
"""Documented conversion: tick × epoch_seconds / 60."""
|
|
99
|
+
return tick * self.epoch_seconds / 60.0
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def dumps_config_canonical(config: SimulationConfig) -> bytes:
|
|
103
|
+
"""Canonical configuration snapshot bytes (embedded into exports).
|
|
104
|
+
|
|
105
|
+
Lives here rather than in the simulation package so that export/import
|
|
106
|
+
verification never needs to load the engine module at all.
|
|
107
|
+
"""
|
|
108
|
+
from dreamforge.core.serialization.dqcj import dumps_canonical
|
|
109
|
+
|
|
110
|
+
return dumps_canonical(config.model_dump(mode="json"))
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def load_config(source: str | Path | dict[str, Any]) -> SimulationConfig:
|
|
114
|
+
"""Load and strictly validate a run configuration.
|
|
115
|
+
|
|
116
|
+
``source`` may be an already-parsed dict or a path to UTF-8 JSON. Raises
|
|
117
|
+
:class:`ConfigError` on any violation (schema, ranges, structure).
|
|
118
|
+
"""
|
|
119
|
+
if isinstance(source, dict):
|
|
120
|
+
raw = source
|
|
121
|
+
else:
|
|
122
|
+
path = Path(source)
|
|
123
|
+
try:
|
|
124
|
+
text = path.read_text(encoding="utf-8")
|
|
125
|
+
except OSError as exc:
|
|
126
|
+
msg = f"config file unreadable: {exc.__class__.__name__}"
|
|
127
|
+
raise ConfigError("config_unreadable", msg) from exc
|
|
128
|
+
from dreamforge.core.serialization.dqcj import loads_strict
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
raw = loads_strict(text)
|
|
132
|
+
except ValueError as exc:
|
|
133
|
+
raise ConfigError("config_invalid_json", str(exc)) from exc
|
|
134
|
+
if not isinstance(raw, dict):
|
|
135
|
+
raise ConfigError(
|
|
136
|
+
"config_invalid_json",
|
|
137
|
+
"top-level configuration must be a JSON object",
|
|
138
|
+
)
|
|
139
|
+
try:
|
|
140
|
+
return SimulationConfig.model_validate(raw)
|
|
141
|
+
except Exception as exc: # noqa: BLE001 - re-raised typed below
|
|
142
|
+
raise ConfigError("config_validation_failed", str(exc)) from exc
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Domain models: sleep cycle, neurochemistry, memory graph, events."""
|