stochology 0.1.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.
- stochology-0.1.0/Cargo.toml +28 -0
- stochology-0.1.0/LICENSE +21 -0
- stochology-0.1.0/PKG-INFO +154 -0
- stochology-0.1.0/README.md +100 -0
- stochology-0.1.0/crates/stochology/Cargo.toml +17 -0
- stochology-0.1.0/crates/stochology/README.md +12 -0
- stochology-0.1.0/crates/stochology/src/dyad.rs +256 -0
- stochology-0.1.0/crates/stochology/src/engine.rs +1925 -0
- stochology-0.1.0/crates/stochology/src/epistemic.rs +1469 -0
- stochology-0.1.0/crates/stochology/src/governance.rs +2822 -0
- stochology-0.1.0/crates/stochology/src/grammar.rs +2024 -0
- stochology-0.1.0/crates/stochology/src/kernel.rs +1157 -0
- stochology-0.1.0/crates/stochology/src/lib.rs +61 -0
- stochology-0.1.0/crates/stochology/src/multilayer.rs +2077 -0
- stochology-0.1.0/crates/stochology/src/reception.rs +174 -0
- stochology-0.1.0/crates/stochology/src/synthesis.rs +2255 -0
- stochology-0.1.0/crates/stochology/src/vital.rs +1540 -0
- stochology-0.1.0/crates/stochology/tests/audit_spec.rs +511 -0
- stochology-0.1.0/crates/stochology/tests/book_anchors.rs +846 -0
- stochology-0.1.0/crates/stochology/tests/challenger_stress_spec.rs +649 -0
- stochology-0.1.0/crates/stochology/tests/corpus_guards.rs +1150 -0
- stochology-0.1.0/crates/stochology/tests/empirical_stress_spec.rs +329 -0
- stochology-0.1.0/crates/stochology/tests/grammar_spec.rs +528 -0
- stochology-0.1.0/crates/stochology/tests/multilayer_spec.rs +245 -0
- stochology-0.1.0/crates/stochology-cli/Cargo.toml +23 -0
- stochology-0.1.0/crates/stochology-cli/README.md +14 -0
- stochology-0.1.0/crates/stochology-cli/src/chapters.rs +1597 -0
- stochology-0.1.0/crates/stochology-cli/src/csv.rs +162 -0
- stochology-0.1.0/crates/stochology-cli/src/ledger/basics.rs +662 -0
- stochology-0.1.0/crates/stochology-cli/src/ledger/framework.rs +767 -0
- stochology-0.1.0/crates/stochology-cli/src/ledger/part_v.rs +249 -0
- stochology-0.1.0/crates/stochology-cli/src/ledger.rs +348 -0
- stochology-0.1.0/crates/stochology-cli/src/lib.rs +56 -0
- stochology-0.1.0/crates/stochology-cli/src/loaders.rs +822 -0
- stochology-0.1.0/crates/stochology-cli/src/main.rs +146 -0
- stochology-0.1.0/pyproject.toml +138 -0
- stochology-0.1.0/src/.python-version +1 -0
- stochology-0.1.0/src/Cargo.lock +145 -0
- stochology-0.1.0/src/Cargo.toml +38 -0
- stochology-0.1.0/src/LICENSE +21 -0
- stochology-0.1.0/src/README.md +100 -0
- stochology-0.1.0/src/main.rs +22 -0
- stochology-0.1.0/src/rust/datasets.rs +203 -0
- stochology-0.1.0/src/rust/engine.rs +461 -0
- stochology-0.1.0/src/rust/epistemic.rs +489 -0
- stochology-0.1.0/src/rust/errors.rs +33 -0
- stochology-0.1.0/src/rust/governance.rs +629 -0
- stochology-0.1.0/src/rust/grammar.rs +101 -0
- stochology-0.1.0/src/rust/kernel.rs +288 -0
- stochology-0.1.0/src/rust/labs.rs +774 -0
- stochology-0.1.0/src/rust/lib.rs +62 -0
- stochology-0.1.0/src/rust/multilayer.rs +318 -0
- stochology-0.1.0/src/rust/synthesis.rs +574 -0
- stochology-0.1.0/src/rust/util.rs +16 -0
- stochology-0.1.0/src/rust/vital.rs +575 -0
- stochology-0.1.0/src/scripts/build_notebooks.py +479 -0
- stochology-0.1.0/src/scripts/run_notebooks.py +101 -0
- stochology-0.1.0/src/tests/__init__.py +0 -0
- stochology-0.1.0/src/tests/paths.py +22 -0
- stochology-0.1.0/src/tests/test_cli_parity.py +165 -0
- stochology-0.1.0/src/tests/test_datasets.py +113 -0
- stochology-0.1.0/src/tests/test_engine.py +106 -0
- stochology-0.1.0/src/tests/test_kernel.py +112 -0
- stochology-0.1.0/src/tests/test_multilayer_grammar.py +91 -0
- stochology-0.1.0/src/tests/test_notebooks.py +117 -0
- stochology-0.1.0/src/tests/test_operators.py +239 -0
- stochology-0.1.0/src/uv.lock +1468 -0
- stochology-0.1.0/stochology/__init__.py +49 -0
- stochology-0.1.0/stochology/_core.pyi +970 -0
- stochology-0.1.0/stochology/checks.py +101 -0
- stochology-0.1.0/stochology/datasets.py +48 -0
- stochology-0.1.0/stochology/engine.py +18 -0
- stochology-0.1.0/stochology/epistemic.py +35 -0
- stochology-0.1.0/stochology/governance.py +28 -0
- stochology-0.1.0/stochology/grammar.py +32 -0
- stochology-0.1.0/stochology/kernel.py +58 -0
- stochology-0.1.0/stochology/labs.py +36 -0
- stochology-0.1.0/stochology/multilayer.py +20 -0
- stochology-0.1.0/stochology/plots.py +117 -0
- stochology-0.1.0/stochology/py.typed +0 -0
- stochology-0.1.0/stochology/synthesis.py +31 -0
- stochology-0.1.0/stochology/vital.py +29 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[workspace]
|
|
2
|
+
resolver = "3"
|
|
3
|
+
members = [
|
|
4
|
+
"crates/stochology",
|
|
5
|
+
"crates/stochology-cli",
|
|
6
|
+
]
|
|
7
|
+
# `src/` is the optional PyO3/maturin lab layer. It is deliberately NOT a member: the
|
|
8
|
+
# shipped artifacts stay dependency-free (AGENTS.md §IV) and `cargo llvm-cov --workspace`
|
|
9
|
+
# keeps measuring exactly the two core crates.
|
|
10
|
+
exclude = ["src"]
|
|
11
|
+
|
|
12
|
+
[workspace.package]
|
|
13
|
+
version = "0.1.0"
|
|
14
|
+
edition = "2024"
|
|
15
|
+
rust-version = "1.88"
|
|
16
|
+
authors = ["Silvano Neto <dev@silvanoneto.com>"]
|
|
17
|
+
license = "MIT"
|
|
18
|
+
repository = "https://github.com/0b3st4f3r4/stochology"
|
|
19
|
+
homepage = "https://stochology.org"
|
|
20
|
+
keywords = ["stochastic", "calibration", "causality", "uncertainty", "decision"]
|
|
21
|
+
categories = ["science", "mathematics", "simulation", "algorithms"]
|
|
22
|
+
description = "Stochology: The Theory and Ethics of Aim for Judgment and Decision-Making under Uncertainty"
|
|
23
|
+
|
|
24
|
+
[workspace.dependencies]
|
|
25
|
+
stochology = { version = "0.1.0", path = "crates/stochology" }
|
|
26
|
+
|
|
27
|
+
[workspace.lints.rustdoc]
|
|
28
|
+
broken_intra_doc_links = "allow"
|
stochology-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Silvano Neto
|
|
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,154 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stochology
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Rust
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Dist: numpy>=2.0
|
|
19
|
+
Requires-Dist: matplotlib>=3.9
|
|
20
|
+
Requires-Dist: nbformat>=5.10 ; extra == 'all'
|
|
21
|
+
Requires-Dist: nbclient>=0.10 ; extra == 'all'
|
|
22
|
+
Requires-Dist: jupyter-client>=8.6 ; extra == 'all'
|
|
23
|
+
Requires-Dist: ipykernel>=6.29 ; extra == 'all'
|
|
24
|
+
Requires-Dist: pytest>=8.3 ; extra == 'all'
|
|
25
|
+
Requires-Dist: pytest-cov>=6.0 ; extra == 'all'
|
|
26
|
+
Requires-Dist: ruff>=0.13 ; extra == 'all'
|
|
27
|
+
Requires-Dist: bandit>=1.8 ; extra == 'all'
|
|
28
|
+
Requires-Dist: maturin>=1.16,<2.0 ; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.3 ; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov>=6.0 ; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.13 ; extra == 'dev'
|
|
32
|
+
Requires-Dist: bandit>=1.8 ; extra == 'dev'
|
|
33
|
+
Requires-Dist: nbformat>=5.10 ; extra == 'notebooks'
|
|
34
|
+
Requires-Dist: nbclient>=0.10 ; extra == 'notebooks'
|
|
35
|
+
Requires-Dist: jupyter-client>=8.6 ; extra == 'notebooks'
|
|
36
|
+
Requires-Dist: ipykernel>=6.29 ; extra == 'notebooks'
|
|
37
|
+
Provides-Extra: all
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Provides-Extra: notebooks
|
|
40
|
+
License-File: LICENSE
|
|
41
|
+
Summary: Stochology: the theory and ethics of aim — PyO3 bindings and interactive laboratories
|
|
42
|
+
Keywords: stochastic,calibration,causality,uncertainty,decision-making,risk,epistemic,governance,vital-margin,pyo3
|
|
43
|
+
Home-Page: https://stochology.org
|
|
44
|
+
Author-email: Silvano Neto <dev@silvanoneto.com>
|
|
45
|
+
Maintainer-email: Silvano Neto <dev@silvanoneto.com>
|
|
46
|
+
License-Expression: MIT
|
|
47
|
+
Requires-Python: >=3.13
|
|
48
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
49
|
+
Project-URL: Bug Tracker, https://github.com/0b3st4f3r4/stochology/issues
|
|
50
|
+
Project-URL: Documentation, https://stochology.org
|
|
51
|
+
Project-URL: Homepage, https://stochology.org
|
|
52
|
+
Project-URL: Repository, https://github.com/0b3st4f3r4/stochology
|
|
53
|
+
|
|
54
|
+
# Stochology (`stochology`)
|
|
55
|
+
|
|
56
|
+
[](https://pypi.org/project/stochology/)
|
|
57
|
+
[](https://pypi.org/project/stochology/)
|
|
58
|
+
[](https://opensource.org/licenses/MIT)
|
|
59
|
+
|
|
60
|
+
**The Theory and Ethics of Aim** for judgment and decision-making under structural uncertainty when action must precede the outcome.
|
|
61
|
+
|
|
62
|
+
`stochology` provides high-performance Python bindings (via [PyO3](https://pyo3.rs/) and pure Rust) to the core mathematical operators, sequential agent–world–institution simulation environments, and empirical verification laboratories of the Stochology framework.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## The Nuclear Triad of Aim
|
|
67
|
+
|
|
68
|
+
Stochology organizes judgment under uncertainty into three non-substitutable safeguards:
|
|
69
|
+
|
|
70
|
+
$$M_{\mathrm{Leontief}} = \min(S_{\mathrm{epi}},\, S_{\mathrm{vital}},\, S_{\mathrm{gov}})$$
|
|
71
|
+
|
|
72
|
+
1. **Filter I · Epistemic Margin ($S_{\mathrm{epi}}$)** (`stochology.epistemic`): Manski–Lee partial identification bounds, Meng big-data paradox ($\rho_{R,Y}$), cluster design effects ($\mathrm{DEFF}$), multiverse analysis, and agnotology detection.
|
|
73
|
+
2. **Filter II · Vital Margin ($S_{\mathrm{vital}}$)** (`stochology.vital`): Hill heavy-tail index ($\alpha$), Jensen shortfall ($\Delta_J$), Kingman queueing basin, and non-ergodic survival criteria ($\mathrm{TTS}_{\mathrm{survival}} \ge \mathrm{TTR}_{\mathrm{recovery}}$).
|
|
74
|
+
3. **Filter III · Institutional Governance ($S_{\mathrm{gov}}$)** (`stochology.governance`): Goodhart performativity audits, CRPS decompositions, verifiable temporal commitments (`TemporalVault`), and algedonic channel verification.
|
|
75
|
+
|
|
76
|
+
Removing any single axis triggers structural collapse (Collapse Propositions 1, 2, and 3).
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install stochology
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For interactive Jupyter notebook laboratories with visualization support:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install "stochology[notebooks]"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Quickstart
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import stochology as st
|
|
96
|
+
|
|
97
|
+
# 1. Simulate the Sequential Agent-World-Institution Loop
|
|
98
|
+
env = st.engine.CommunityReserveEnv(seed=2026)
|
|
99
|
+
print(f"Initial reserve: {env.reserve}")
|
|
100
|
+
|
|
101
|
+
# 2. Access canonical operators and indicators
|
|
102
|
+
lab5 = st.labs.chapter(5)
|
|
103
|
+
print(f"Danish fire tail index (Hill alpha): {lab5['danish_tail_alpha']:.4f}")
|
|
104
|
+
|
|
105
|
+
# 3. Test triadic integrity and collapse propositions
|
|
106
|
+
agent = st.engine.StochologicalAgent()
|
|
107
|
+
report = agent.evaluate_integrity()
|
|
108
|
+
print(f"Triadic status: {report.status}")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Architectural Invariants
|
|
114
|
+
|
|
115
|
+
1. **Pure Rust Foundation**: The underlying mathematical core (`crates/stochology` and `crates/stochology-cli`) is implemented in pure Rust (`std` only, zero external dependencies) with deterministic `SplitMix64` pseudo-random generators (`DEFAULT_SEED = 2026`).
|
|
116
|
+
2. **Deterministic & Bitwise Replicable**: Notebooks and laboratory scripts carry zero wall-clock reads and zero network access, guaranteeing bit-for-bit reproducibility.
|
|
117
|
+
3. **Sealed Datasets**: `stochology.datasets` reads sealed empirical datasets validated against cryptographic `SHA256SUMS` manifests.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Layout & Local Development
|
|
122
|
+
|
|
123
|
+
When working directly within the source repository:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
src/
|
|
127
|
+
├── Cargo.toml standalone crate `stochology-py` (_core cdylib)
|
|
128
|
+
├── pyproject.toml maturin configuration
|
|
129
|
+
├── rust/ PyO3 bindings to Rust core
|
|
130
|
+
├── stochology/ public Python surface & typed stubs (py.typed)
|
|
131
|
+
├── tests/ pytest parity and contract verification suite
|
|
132
|
+
└── scripts/run_notebooks.py headless execution gate for notebooks/
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Development Setup
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv sync --directory src
|
|
139
|
+
uv run --directory src maturin develop --release
|
|
140
|
+
uv run --directory src pytest
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Full gate from repository root:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
./scripts/verify.sh --with-python
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Links
|
|
150
|
+
|
|
151
|
+
- **Textbook & Treatise**: [https://stochology.org](https://stochology.org)
|
|
152
|
+
- **Source Code**: [https://github.com/0b3st4f3r4/stochology](https://github.com/0b3st4f3r4/stochology)
|
|
153
|
+
- **Bug Tracker**: [https://github.com/0b3st4f3r4/stochology/issues](https://github.com/0b3st4f3r4/stochology/issues)
|
|
154
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Stochology (`stochology`)
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/stochology/)
|
|
4
|
+
[](https://pypi.org/project/stochology/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
**The Theory and Ethics of Aim** for judgment and decision-making under structural uncertainty when action must precede the outcome.
|
|
8
|
+
|
|
9
|
+
`stochology` provides high-performance Python bindings (via [PyO3](https://pyo3.rs/) and pure Rust) to the core mathematical operators, sequential agent–world–institution simulation environments, and empirical verification laboratories of the Stochology framework.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## The Nuclear Triad of Aim
|
|
14
|
+
|
|
15
|
+
Stochology organizes judgment under uncertainty into three non-substitutable safeguards:
|
|
16
|
+
|
|
17
|
+
$$M_{\mathrm{Leontief}} = \min(S_{\mathrm{epi}},\, S_{\mathrm{vital}},\, S_{\mathrm{gov}})$$
|
|
18
|
+
|
|
19
|
+
1. **Filter I · Epistemic Margin ($S_{\mathrm{epi}}$)** (`stochology.epistemic`): Manski–Lee partial identification bounds, Meng big-data paradox ($\rho_{R,Y}$), cluster design effects ($\mathrm{DEFF}$), multiverse analysis, and agnotology detection.
|
|
20
|
+
2. **Filter II · Vital Margin ($S_{\mathrm{vital}}$)** (`stochology.vital`): Hill heavy-tail index ($\alpha$), Jensen shortfall ($\Delta_J$), Kingman queueing basin, and non-ergodic survival criteria ($\mathrm{TTS}_{\mathrm{survival}} \ge \mathrm{TTR}_{\mathrm{recovery}}$).
|
|
21
|
+
3. **Filter III · Institutional Governance ($S_{\mathrm{gov}}$)** (`stochology.governance`): Goodhart performativity audits, CRPS decompositions, verifiable temporal commitments (`TemporalVault`), and algedonic channel verification.
|
|
22
|
+
|
|
23
|
+
Removing any single axis triggers structural collapse (Collapse Propositions 1, 2, and 3).
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install stochology
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For interactive Jupyter notebook laboratories with visualization support:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install "stochology[notebooks]"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quickstart
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
import stochology as st
|
|
43
|
+
|
|
44
|
+
# 1. Simulate the Sequential Agent-World-Institution Loop
|
|
45
|
+
env = st.engine.CommunityReserveEnv(seed=2026)
|
|
46
|
+
print(f"Initial reserve: {env.reserve}")
|
|
47
|
+
|
|
48
|
+
# 2. Access canonical operators and indicators
|
|
49
|
+
lab5 = st.labs.chapter(5)
|
|
50
|
+
print(f"Danish fire tail index (Hill alpha): {lab5['danish_tail_alpha']:.4f}")
|
|
51
|
+
|
|
52
|
+
# 3. Test triadic integrity and collapse propositions
|
|
53
|
+
agent = st.engine.StochologicalAgent()
|
|
54
|
+
report = agent.evaluate_integrity()
|
|
55
|
+
print(f"Triadic status: {report.status}")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Architectural Invariants
|
|
61
|
+
|
|
62
|
+
1. **Pure Rust Foundation**: The underlying mathematical core (`crates/stochology` and `crates/stochology-cli`) is implemented in pure Rust (`std` only, zero external dependencies) with deterministic `SplitMix64` pseudo-random generators (`DEFAULT_SEED = 2026`).
|
|
63
|
+
2. **Deterministic & Bitwise Replicable**: Notebooks and laboratory scripts carry zero wall-clock reads and zero network access, guaranteeing bit-for-bit reproducibility.
|
|
64
|
+
3. **Sealed Datasets**: `stochology.datasets` reads sealed empirical datasets validated against cryptographic `SHA256SUMS` manifests.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Layout & Local Development
|
|
69
|
+
|
|
70
|
+
When working directly within the source repository:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
src/
|
|
74
|
+
├── Cargo.toml standalone crate `stochology-py` (_core cdylib)
|
|
75
|
+
├── pyproject.toml maturin configuration
|
|
76
|
+
├── rust/ PyO3 bindings to Rust core
|
|
77
|
+
├── stochology/ public Python surface & typed stubs (py.typed)
|
|
78
|
+
├── tests/ pytest parity and contract verification suite
|
|
79
|
+
└── scripts/run_notebooks.py headless execution gate for notebooks/
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Development Setup
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv sync --directory src
|
|
86
|
+
uv run --directory src maturin develop --release
|
|
87
|
+
uv run --directory src pytest
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Full gate from repository root:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
./scripts/verify.sh --with-python
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Links
|
|
97
|
+
|
|
98
|
+
- **Textbook & Treatise**: [https://stochology.org](https://stochology.org)
|
|
99
|
+
- **Source Code**: [https://github.com/0b3st4f3r4/stochology](https://github.com/0b3st4f3r4/stochology)
|
|
100
|
+
- **Bug Tracker**: [https://github.com/0b3st4f3r4/stochology/issues](https://github.com/0b3st4f3r4/stochology/issues)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "stochology"
|
|
3
|
+
description = "Stochology: The Theory and Ethics of Aim under Uncertainty — integrative framework for the sequential Agent-World-Institution loop, epistemic margin, vital margin, institutional governance, formal grammar of aim, and 35-layer multilayer knowledge graph in pure Rust"
|
|
4
|
+
version.workspace = true
|
|
5
|
+
edition.workspace = true
|
|
6
|
+
rust-version.workspace = true
|
|
7
|
+
authors.workspace = true
|
|
8
|
+
license.workspace = true
|
|
9
|
+
repository.workspace = true
|
|
10
|
+
homepage.workspace = true
|
|
11
|
+
keywords.workspace = true
|
|
12
|
+
categories.workspace = true
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
|
|
15
|
+
[lints]
|
|
16
|
+
workspace = true
|
|
17
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# `stochology`
|
|
2
|
+
|
|
3
|
+
Pure-Rust (`std` only, zero external dependencies) library implementing **Stochology** (from *stókhos*, aim or conjecture, and *lógos*, reasoned account), an integrative framework and transversal research program for the theory and ethics of aim in judgment and decision-making under structural uncertainty when action must precede the outcome.
|
|
4
|
+
|
|
5
|
+
## Architecture: The Full Mediation Circuit and the Nuclear Triad
|
|
6
|
+
|
|
7
|
+
- [`kernel`](src/kernel.rs): Deterministic `SplitMix64` simulation (`DEFAULT_SEED = 2026`), FIPS 180-4 SHA-256 and RFC 2104 keyed HMAC-SHA256 sealing, Welford online moments, Pool-Adjacent-Violators (PAV) isotonic regression, and Cholesky SPD solver.
|
|
8
|
+
- [`engine`](src/engine.rs): The sequential Agent–World–Institution loop (`CommunityReserveEnv`), `NaiveOptimizer`, `StochologicalAgent`, and the $2\times 2\times 2$ factorial ablations + 100-seed Monte Carlo evaluation.
|
|
9
|
+
- [`epistemic`](src/epistemic.rs) (**Filter I · Axis 1 [$S_{\mathrm{epi}}$]: Chapters 2–4**): `EpistemicMarginState` (Canonical Operator I): antidogmatic openness (`cromwell_clamp`), severe testing vs. agnotology, Kimball/Mitroff Type III framing, *e*-BH multiverse discovery control, Ville *e*-processes, Manski & Lee partial-identification bounds, and the unified harmonic effective sample size law ($n_{\mathrm{eff}}$ uniting Meng's $\rho_{R,Y}$, Campbell–Moulton $\mathrm{DEFF}$, Kish weighting, Chao $\hat{n}_{00}$, and bitemporal vintages).
|
|
10
|
+
- [`vital`](src/vital.rs) (**Filter II · Axis 2 [$S_{\mathrm{vital}}$]: Chapters 5–6**): `VitalMarginState` (Canonical Operator II): ordinal scale invariance, Jensen's convexity gap $\Delta_J$, empirical CRPS, Hill tail index $\hat{\alpha}$ with cluster-corrected `HollingTailRuptureAudit`, Itô variance drain, `KellySizingRegime` (Baker–McHale epistemic Kelly vs. tail-robust WDRO-CVaR Kelly), Kingman heavy-traffic queues, $\mathrm{TTS}_{\mathrm{survival}} \ge \mathrm{TTR}_{\mathrm{recovery}}$, Canguilhem–Holling resilience basins, Wald survivorship inversion, and Sniedovich No-Man's-Land safeguards.
|
|
11
|
+
- [`governance`](src/governance.rs) (**Filter III · Axis 3 [$S_{\mathrm{gov}}$]: Chapters 7–8**): `GovernanceState` (Canonical Operator III): Gate 1 ex-ante CORP-PAV calibration with Sparre Andersen harmonic degrees-of-freedom finite-sample debiasing $\hat{b}_{\mathrm{PAV}}(n_{\mathrm{eff}}) = H_{n_{\mathrm{eff}}}/(4 n_{\mathrm{eff}})$, `IcpIdentificationStatus` causal invariance, Kennedy–O'Hagan GP discrepancy, Tian–Pearl bounds, Perdomo/MacKenzie performativity, and Goodhart's Law; Gate 2 real-time Beer $S3^*$ algedonic bypass ($\delta_{\mathrm{cred}} = 0$), List–Pettit conjunctive veto, and `KairosSynchronousPanel` / `ZhengMeisterQueueAudit` two-tier cognitive queue ($\le 10\text{ bits/s}$); Gate 3 ex-post `TemporalVault`, Sosa's `TelicGrade`, Holmström–Innes liability vs. Simon–Girard scapegoating, and Chouldechova's fairness trilemma.
|
|
12
|
+
- [`synthesis`](src/synthesis.rs) (**Triadic Synthesis [$M_{\mathrm{Leontief}}$]: Chapter 9**): `TriadicIntegrity` ($M_{\mathrm{Leontief}} = \min(S_{\mathrm{epi}}, S_{\mathrm{vital}}, S_{\mathrm{gov}})$), `CollapseProposition`, `ProcessTracingInference`, `ReflexiveBrakeAudit`, `LeontiefVsMultiplicativeAudit`, and `PreregisteredFalsifier`.
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
//! **Minimal Two-Agent Dialogue Environment (`dyad.rs`) — Interpersonal Circuit of `notes/Aiming Between Mirrors.md`.**
|
|
2
|
+
//!
|
|
3
|
+
//! Instantiates the three mediation planes ($\mathcal{W}, \mathcal{A}, \mathcal{I}$) and seven guard sites
|
|
4
|
+
//! at the interpersonal scale (`EXP-MIR-13`): two [`AgentPolicy`] participants exchange utterances
|
|
5
|
+
//! across a noisy communicative channel under bifurcated [`SplitMix64::split_fork_join_pair`] streams.
|
|
6
|
+
|
|
7
|
+
use crate::engine::{AgentPolicy, ArchiveObservation};
|
|
8
|
+
use crate::kernel::SplitMix64;
|
|
9
|
+
use crate::reception::{ReceptionMarginState, solve_dialogue_basin};
|
|
10
|
+
use crate::synthesis::TriadicIntegrity;
|
|
11
|
+
|
|
12
|
+
/// Outcome of one dialogic exchange step $t$ in [`DyadEnv`].
|
|
13
|
+
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
14
|
+
pub struct DialogueStepOutcome {
|
|
15
|
+
/// Step index $t$.
|
|
16
|
+
pub step_t: usize,
|
|
17
|
+
/// Epistemic bounds $[L_{A,t}, U_{A,t}]$ declared by Agent A.
|
|
18
|
+
pub speaker_bounds: (f64, f64),
|
|
19
|
+
/// Epistemic bounds $[L_{B,t}, U_{B,t}]$ declared by Agent B.
|
|
20
|
+
pub listener_bounds: (f64, f64),
|
|
21
|
+
/// Evaluated [`ReceptionMarginState`] at step $t$.
|
|
22
|
+
pub reception_margin: ReceptionMarginState,
|
|
23
|
+
/// Remaining dialogic attraction-basin radius $\Theta_{\mathrm{basin}, t} \in [0, 1]$.
|
|
24
|
+
pub dialogue_basin_radius: f64,
|
|
25
|
+
/// Remaining relational reserve $R_{\mathrm{rel}, t+1} \ge 0$.
|
|
26
|
+
pub relational_reserve: f64,
|
|
27
|
+
/// True if the dialogue hit the absorbing relational rupture barrier at step $t$.
|
|
28
|
+
pub hit_relational_rupture: bool,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Summary report of a full two-agent trajectory in [`DyadEnv`].
|
|
32
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
33
|
+
pub struct DialogueTrajectoryReport {
|
|
34
|
+
/// Name of the primary speaking policy (Agent A).
|
|
35
|
+
pub speaker_name: String,
|
|
36
|
+
/// Name of the responding policy (Agent B).
|
|
37
|
+
pub listener_name: String,
|
|
38
|
+
/// Total dialogue steps simulated.
|
|
39
|
+
pub total_steps: usize,
|
|
40
|
+
/// Mean reception margin score $\bar{S}_{\mathrm{rec}} \in [0, 1]$.
|
|
41
|
+
pub mean_reception_score: f64,
|
|
42
|
+
/// Terminal dialogic basin radius $\Theta_{\mathrm{basin}, T} \in [0, 1]$.
|
|
43
|
+
pub terminal_dialogue_basin: f64,
|
|
44
|
+
/// Terminal relational reserve $R_{\mathrm{rel}, T} \ge 0$.
|
|
45
|
+
pub terminal_relational_reserve: f64,
|
|
46
|
+
/// Step at which irreversible relational rupture occurred (`None` if the dyad survived).
|
|
47
|
+
pub rupture_step: Option<usize>,
|
|
48
|
+
/// Triadic structural integrity diagnosis over the dyadic trajectory.
|
|
49
|
+
pub triadic_integrity: TriadicIntegrity,
|
|
50
|
+
/// Step-by-step dialogic trace.
|
|
51
|
+
pub steps: Vec<DialogueStepOutcome>,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// **Minimal Two-Agent Sequential Dialogue Environment (`DyadEnv`):**
|
|
55
|
+
/// Re-instantiates the three canonical operators across two interacting agents (`EXP-MIR-13`).
|
|
56
|
+
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
57
|
+
pub struct DyadEnv {
|
|
58
|
+
/// Deterministic PRNG seed.
|
|
59
|
+
pub seed: u64,
|
|
60
|
+
/// Number of dialogic turns $T$.
|
|
61
|
+
pub horizon_steps: usize,
|
|
62
|
+
/// Initial relational reserve $R_{\mathrm{rel}, 0} > 0$.
|
|
63
|
+
pub initial_relational_reserve: f64,
|
|
64
|
+
/// Communicative channel noise scale $\sigma_{\mathrm{chan}} \ge 0$.
|
|
65
|
+
pub communication_channel_noise: f64,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
impl DyadEnv {
|
|
69
|
+
/// Creates a new [`DyadEnv`] with explicit seed, horizon, relational reserve, and channel noise.
|
|
70
|
+
pub const fn new(
|
|
71
|
+
seed: u64,
|
|
72
|
+
horizon_steps: usize,
|
|
73
|
+
initial_relational_reserve: f64,
|
|
74
|
+
communication_channel_noise: f64,
|
|
75
|
+
) -> Self {
|
|
76
|
+
Self {
|
|
77
|
+
seed,
|
|
78
|
+
horizon_steps,
|
|
79
|
+
initial_relational_reserve,
|
|
80
|
+
communication_channel_noise,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// Simulates a full two-agent dialogic trajectory between `agent_a` and `agent_b`.
|
|
85
|
+
pub fn run_dialogue_trajectory<P1: AgentPolicy, P2: AgentPolicy>(
|
|
86
|
+
&self,
|
|
87
|
+
agent_a: &mut P1,
|
|
88
|
+
agent_b: &mut P2,
|
|
89
|
+
) -> DialogueTrajectoryReport {
|
|
90
|
+
let mut root_rng = SplitMix64::new(self.seed);
|
|
91
|
+
let mut reserve = self.initial_relational_reserve.max(0.0);
|
|
92
|
+
let mut rupture_step = if reserve <= 1e-6 { Some(0) } else { None };
|
|
93
|
+
let mut drift = 0.0_f64;
|
|
94
|
+
let mut sum_rec = 0.0_f64;
|
|
95
|
+
let mut sum_vital = 0.0_f64;
|
|
96
|
+
let mut sum_gov = 0.0_f64;
|
|
97
|
+
let mut last_basin = if reserve <= 1e-6 { 0.0 } else { 1.0 };
|
|
98
|
+
let mut steps = Vec::with_capacity(self.horizon_steps);
|
|
99
|
+
|
|
100
|
+
for t in 0..self.horizon_steps {
|
|
101
|
+
let (mut rng_a, mut rng_b) = root_rng.split_fork_join_pair(t as u64);
|
|
102
|
+
let mut clusters_a = Vec::with_capacity(4);
|
|
103
|
+
let mut clusters_b = Vec::with_capacity(4);
|
|
104
|
+
for _ in 0..4 {
|
|
105
|
+
let mut ca = Vec::with_capacity(8);
|
|
106
|
+
let mut cb = Vec::with_capacity(8);
|
|
107
|
+
for _ in 0..8 {
|
|
108
|
+
ca.push((20.0 + rng_a.normal(0.0, 2.5)).clamp(5.0, 60.0));
|
|
109
|
+
cb.push((20.0 + rng_b.normal(0.0, 2.5)).clamp(5.0, 60.0));
|
|
110
|
+
}
|
|
111
|
+
clusters_a.push(ca);
|
|
112
|
+
clusters_b.push(cb);
|
|
113
|
+
}
|
|
114
|
+
let obs_a = ArchiveObservation {
|
|
115
|
+
step_t: t,
|
|
116
|
+
observed_clusters: clusters_a,
|
|
117
|
+
missing_count: 4,
|
|
118
|
+
demand_support: (5.0, 60.0),
|
|
119
|
+
current_reserve: reserve,
|
|
120
|
+
frontline_distress_e_factor: 1.5,
|
|
121
|
+
};
|
|
122
|
+
let obs_b = ArchiveObservation {
|
|
123
|
+
step_t: t,
|
|
124
|
+
observed_clusters: clusters_b,
|
|
125
|
+
missing_count: 4,
|
|
126
|
+
demand_support: (5.0, 60.0),
|
|
127
|
+
current_reserve: reserve,
|
|
128
|
+
frontline_distress_e_factor: 1.5,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
let dec_a = agent_a.act(&obs_a);
|
|
132
|
+
let dec_b = agent_b.act(&obs_b);
|
|
133
|
+
|
|
134
|
+
let mid_b = 0.50 * (dec_b.epistemic_demand_bounds.0 + dec_b.epistemic_demand_bounds.1);
|
|
135
|
+
let channel_shock =
|
|
136
|
+
self.communication_channel_noise.max(0.0) * rng_a.standard_normal().abs();
|
|
137
|
+
let witnessed_b = mid_b + channel_shock;
|
|
138
|
+
let width_a =
|
|
139
|
+
(dec_a.epistemic_demand_bounds.1 - dec_a.epistemic_demand_bounds.0).max(0.0);
|
|
140
|
+
let openness = (width_a / 7.5).clamp(0.15, 0.95);
|
|
141
|
+
let surv_pressure = (0.50 * dec_a.proxy_incentive_pressure
|
|
142
|
+
+ 0.50 * dec_b.proxy_incentive_pressure)
|
|
143
|
+
.clamp(0.0, 1.0);
|
|
144
|
+
let rec = ReceptionMarginState::from_dialogic_exposure(
|
|
145
|
+
dec_a.epistemic_demand_bounds,
|
|
146
|
+
witnessed_b,
|
|
147
|
+
openness,
|
|
148
|
+
surv_pressure,
|
|
149
|
+
);
|
|
150
|
+
sum_rec += rec.reception_margin_score;
|
|
151
|
+
|
|
152
|
+
let tol_alloc = (0.50 * dec_a.vital_reserve_allocation
|
|
153
|
+
+ 0.50 * dec_b.vital_reserve_allocation)
|
|
154
|
+
.max(0.5);
|
|
155
|
+
if rec.witnessed_reception_error > 0.0 || surv_pressure > 0.50 {
|
|
156
|
+
drift =
|
|
157
|
+
(drift + 0.18 * rec.witnessed_reception_error + 1.25 * surv_pressure).min(15.0);
|
|
158
|
+
}
|
|
159
|
+
let basin = if rupture_step.is_some() {
|
|
160
|
+
0.0
|
|
161
|
+
} else {
|
|
162
|
+
solve_dialogue_basin(tol_alloc, drift, channel_shock)
|
|
163
|
+
};
|
|
164
|
+
last_basin = basin;
|
|
165
|
+
sum_vital += basin;
|
|
166
|
+
|
|
167
|
+
let brake_both = dec_a.constitutional_brake_active && dec_b.constitutional_brake_active;
|
|
168
|
+
let discount_max = dec_a
|
|
169
|
+
.frontline_testimonial_discount
|
|
170
|
+
.max(dec_b.frontline_testimonial_discount);
|
|
171
|
+
let gov_score = if brake_both {
|
|
172
|
+
(0.92 - 0.40 * discount_max - 0.30 * surv_pressure).clamp(0.0, 1.0)
|
|
173
|
+
} else {
|
|
174
|
+
(0.32 - 0.25 * discount_max - 0.20 * surv_pressure).clamp(0.0, 1.0)
|
|
175
|
+
};
|
|
176
|
+
sum_gov += gov_score;
|
|
177
|
+
|
|
178
|
+
if rupture_step.is_some() {
|
|
179
|
+
reserve = 0.0;
|
|
180
|
+
} else {
|
|
181
|
+
let drain = 0.35 * rec.witnessed_reception_error
|
|
182
|
+
+ 2.40 * surv_pressure
|
|
183
|
+
+ if basin < 0.25 { 2.50 } else { 0.0 };
|
|
184
|
+
let replenish = if brake_both && rec.reception_margin_score > 0.55 {
|
|
185
|
+
1.20
|
|
186
|
+
} else {
|
|
187
|
+
0.15
|
|
188
|
+
};
|
|
189
|
+
reserve = (reserve + replenish - drain).max(0.0);
|
|
190
|
+
if reserve <= 1e-6 || basin <= 0.0 {
|
|
191
|
+
reserve = 0.0;
|
|
192
|
+
rupture_step = Some(t);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
steps.push(DialogueStepOutcome {
|
|
197
|
+
step_t: t,
|
|
198
|
+
speaker_bounds: dec_a.epistemic_demand_bounds,
|
|
199
|
+
listener_bounds: dec_b.epistemic_demand_bounds,
|
|
200
|
+
reception_margin: rec,
|
|
201
|
+
dialogue_basin_radius: basin,
|
|
202
|
+
relational_reserve: reserve,
|
|
203
|
+
hit_relational_rupture: rupture_step.is_some(),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let tf = self.horizon_steps.max(1) as f64;
|
|
208
|
+
let s_epi = (sum_rec / tf).clamp(0.0, 1.0);
|
|
209
|
+
let s_vital = (sum_vital / tf).clamp(0.0, 1.0);
|
|
210
|
+
let s_gov = (sum_gov / tf).clamp(0.0, 1.0);
|
|
211
|
+
let triad = TriadicIntegrity::evaluate(s_epi, s_vital, s_gov, 0.50);
|
|
212
|
+
|
|
213
|
+
DialogueTrajectoryReport {
|
|
214
|
+
speaker_name: agent_a.name().to_string(),
|
|
215
|
+
listener_name: agent_b.name().to_string(),
|
|
216
|
+
total_steps: self.horizon_steps,
|
|
217
|
+
mean_reception_score: s_epi,
|
|
218
|
+
terminal_dialogue_basin: last_basin,
|
|
219
|
+
terminal_relational_reserve: reserve,
|
|
220
|
+
rupture_step,
|
|
221
|
+
triadic_integrity: triad,
|
|
222
|
+
steps,
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#[cfg(test)]
|
|
228
|
+
mod tests {
|
|
229
|
+
use super::*;
|
|
230
|
+
use crate::engine::{NaiveOptimizer, StochologicalAgent};
|
|
231
|
+
use crate::synthesis::CollapseProposition;
|
|
232
|
+
|
|
233
|
+
#[test]
|
|
234
|
+
fn dyad_env_sustains_stochological_dialogue_and_ruptures_naive_pair() {
|
|
235
|
+
let env = DyadEnv::new(crate::kernel::DEFAULT_SEED, 12, 18.0, 1.5);
|
|
236
|
+
let mut a_full = StochologicalAgent::full();
|
|
237
|
+
let mut b_full = StochologicalAgent::full();
|
|
238
|
+
let rep_intact = env.run_dialogue_trajectory(&mut a_full, &mut b_full);
|
|
239
|
+
assert!(rep_intact.rupture_step.is_none());
|
|
240
|
+
assert!(rep_intact.terminal_relational_reserve > 10.0);
|
|
241
|
+
assert_eq!(
|
|
242
|
+
rep_intact.triadic_integrity.diagnose,
|
|
243
|
+
CollapseProposition::IntactTriad
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
let mut a_naive = NaiveOptimizer;
|
|
247
|
+
let mut b_naive = NaiveOptimizer;
|
|
248
|
+
let rep_rupture = env.run_dialogue_trajectory(&mut a_naive, &mut b_naive);
|
|
249
|
+
assert!(rep_rupture.rupture_step.is_some());
|
|
250
|
+
assert_eq!(rep_rupture.terminal_relational_reserve, 0.0);
|
|
251
|
+
assert_ne!(
|
|
252
|
+
rep_rupture.triadic_integrity.diagnose,
|
|
253
|
+
CollapseProposition::IntactTriad
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|