desitter 0.0.1__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.
Files changed (73) hide show
  1. desitter-0.0.1/MANIFEST.in +4 -0
  2. desitter-0.0.1/PKG-INFO +265 -0
  3. desitter-0.0.1/README.md +245 -0
  4. desitter-0.0.1/pyproject.toml +48 -0
  5. desitter-0.0.1/setup.cfg +4 -0
  6. desitter-0.0.1/src/desitter/__init__.py +28 -0
  7. desitter-0.0.1/src/desitter/__main__.py +11 -0
  8. desitter-0.0.1/src/desitter/adapters/__init__.py +11 -0
  9. desitter-0.0.1/src/desitter/adapters/json_repository.py +181 -0
  10. desitter-0.0.1/src/desitter/adapters/markdown_renderer.py +97 -0
  11. desitter-0.0.1/src/desitter/adapters/payload_validator.py +202 -0
  12. desitter-0.0.1/src/desitter/adapters/transaction_log.py +88 -0
  13. desitter-0.0.1/src/desitter/client.py +1066 -0
  14. desitter-0.0.1/src/desitter/config.py +143 -0
  15. desitter-0.0.1/src/desitter/controlplane/__init__.py +15 -0
  16. desitter-0.0.1/src/desitter/controlplane/automation.py +56 -0
  17. desitter-0.0.1/src/desitter/controlplane/check.py +110 -0
  18. desitter-0.0.1/src/desitter/controlplane/export.py +62 -0
  19. desitter-0.0.1/src/desitter/controlplane/factory.py +66 -0
  20. desitter-0.0.1/src/desitter/controlplane/gateway.py +718 -0
  21. desitter-0.0.1/src/desitter/controlplane/validate.py +77 -0
  22. desitter-0.0.1/src/desitter/epistemic/__init__.py +78 -0
  23. desitter-0.0.1/src/desitter/epistemic/codec.py +345 -0
  24. desitter-0.0.1/src/desitter/epistemic/invariants.py +507 -0
  25. desitter-0.0.1/src/desitter/epistemic/model.py +456 -0
  26. desitter-0.0.1/src/desitter/epistemic/ports.py +158 -0
  27. desitter-0.0.1/src/desitter/epistemic/types.py +275 -0
  28. desitter-0.0.1/src/desitter/epistemic/web.py +1658 -0
  29. desitter-0.0.1/src/desitter/interfaces/__init__.py +18 -0
  30. desitter-0.0.1/src/desitter/interfaces/cli/__init__.py +8 -0
  31. desitter-0.0.1/src/desitter/interfaces/cli/formatters.py +144 -0
  32. desitter-0.0.1/src/desitter/interfaces/cli/main.py +197 -0
  33. desitter-0.0.1/src/desitter/interfaces/mcp/__init__.py +11 -0
  34. desitter-0.0.1/src/desitter/interfaces/mcp/server.py +64 -0
  35. desitter-0.0.1/src/desitter/interfaces/mcp/tools.py +273 -0
  36. desitter-0.0.1/src/desitter/views/__init__.py +14 -0
  37. desitter-0.0.1/src/desitter/views/health.py +70 -0
  38. desitter-0.0.1/src/desitter/views/metrics.py +111 -0
  39. desitter-0.0.1/src/desitter/views/render.py +93 -0
  40. desitter-0.0.1/src/desitter/views/status.py +78 -0
  41. desitter-0.0.1/src/desitter.egg-info/PKG-INFO +265 -0
  42. desitter-0.0.1/src/desitter.egg-info/SOURCES.txt +71 -0
  43. desitter-0.0.1/src/desitter.egg-info/dependency_links.txt +1 -0
  44. desitter-0.0.1/src/desitter.egg-info/entry_points.txt +3 -0
  45. desitter-0.0.1/src/desitter.egg-info/requires.txt +17 -0
  46. desitter-0.0.1/src/desitter.egg-info/top_level.txt +1 -0
  47. desitter-0.0.1/tests/__init__.py +9 -0
  48. desitter-0.0.1/tests/adapters/__init__.py +4 -0
  49. desitter-0.0.1/tests/adapters/test_json_repository.py +114 -0
  50. desitter-0.0.1/tests/adapters/test_payload_validator.py +43 -0
  51. desitter-0.0.1/tests/adapters/test_transaction_log.py +74 -0
  52. desitter-0.0.1/tests/cli/__init__.py +4 -0
  53. desitter-0.0.1/tests/controlplane/__init__.py +5 -0
  54. desitter-0.0.1/tests/controlplane/test_automation.py +49 -0
  55. desitter-0.0.1/tests/controlplane/test_gateway.py +85 -0
  56. desitter-0.0.1/tests/controlplane/test_validate.py +28 -0
  57. desitter-0.0.1/tests/epistemic/__init__.py +5 -0
  58. desitter-0.0.1/tests/epistemic/conftest.py +281 -0
  59. desitter-0.0.1/tests/epistemic/test_invariants.py +566 -0
  60. desitter-0.0.1/tests/epistemic/test_model.py +319 -0
  61. desitter-0.0.1/tests/epistemic/test_ports.py +70 -0
  62. desitter-0.0.1/tests/epistemic/test_types.py +171 -0
  63. desitter-0.0.1/tests/epistemic/test_web_backlink_ownership.py +150 -0
  64. desitter-0.0.1/tests/epistemic/test_web_immutability.py +90 -0
  65. desitter-0.0.1/tests/epistemic/test_web_queries.py +291 -0
  66. desitter-0.0.1/tests/epistemic/test_web_register.py +465 -0
  67. desitter-0.0.1/tests/epistemic/test_web_remove.py +335 -0
  68. desitter-0.0.1/tests/epistemic/test_web_transitions.py +101 -0
  69. desitter-0.0.1/tests/epistemic/test_web_update.py +458 -0
  70. desitter-0.0.1/tests/mcp/__init__.py +5 -0
  71. desitter-0.0.1/tests/test_client.py +206 -0
  72. desitter-0.0.1/tests/test_config.py +74 -0
  73. desitter-0.0.1/tests/test_views_dataclasses.py +30 -0
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include pyproject.toml
3
+ recursive-include src *.py
4
+ recursive-include tests *.py
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.4
2
+ Name: desitter
3
+ Version: 0.0.1
4
+ Summary: A control plane for managing research epistemic webs
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: click>=8.1
8
+ Requires-Dist: jsonschema>=4.21
9
+ Requires-Dist: rich>=13.0
10
+ Provides-Extra: mcp
11
+ Requires-Dist: fastmcp>=0.1; extra == "mcp"
12
+ Provides-Extra: compute
13
+ Requires-Dist: numpy>=1.26; extra == "compute"
14
+ Requires-Dist: scipy>=1.12; extra == "compute"
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8.0; extra == "dev"
17
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
18
+ Provides-Extra: all
19
+ Requires-Dist: desitter[compute,mcp]; extra == "all"
20
+
21
+ # deSitter
22
+
23
+ *Versioned, invariant-enforced tracking for the epistemic structure of research.*
24
+
25
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
26
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
27
+ [![Status: Early Development](https://img.shields.io/badge/status-early%20development-orange.svg)](TRACKER.md)
28
+
29
+ > **Early development — not ready for production use.**
30
+ > The API, file formats, and CLI surface are unstable. See [TRACKER.md](TRACKER.md) for current build status.
31
+
32
+ ---
33
+
34
+ ## What It Is
35
+
36
+ The scientific method has a structure: you make **claims**, ground them in **assumptions**, derive **predictions**, run **analyses** to test those predictions, and record what the evidence shows. That structure exists in every research project, but it almost never gets tracked. It lives in Notion pages, email threads, and researcher memory — and it breaks silently.
37
+
38
+ A refuted prediction doesn't update the claims that depend on it. A revised assumption doesn't propagate to its consequences. Six months later, nobody can trace why a conclusion was drawn or whether the underlying support was ever intact.
39
+
40
+ deSitter makes that structure explicit and machine-enforceable. It is a versioned, graph-structured registry of your **epistemic chain** — every claim, assumption, prediction, analysis, and theory — with hard invariants that keep the graph consistent as research evolves.
41
+
42
+ deSitter is an **audit scaffold**, not a reasoning engine. It surfaces structural facts about the graph: missing links, untested assumptions, stale analyses, uncovered predictions. The researcher — or an AI agent — is the one who decides what to do about them.
43
+
44
+ For researchers, the primary interface is the Python API: `desitter.connect()` in scripts and notebooks. For AI agent sessions, the primary interface is the MCP server. The CLI remains important, but mainly as an inspection, health-check, render, and audit surface.
45
+
46
+ Nobody is expected to hand-author JSON payloads in the shell. deSitter's payloads are structured interchange formats for the gateway, external tooling, and file-based ingestion when needed — not the primary authoring workflow.
47
+
48
+ Every successful mutation is also recorded in the append-only transaction log at `project/data/transaction_log.jsonl`. That log is a first-class public artifact: external tools can watch it, index it, and react to it directly without going through deSitter.
49
+
50
+ ---
51
+
52
+ ## Core Capabilities
53
+
54
+ - **Register** claims, assumptions, predictions, analyses, theories, and parameters in a typed, versioned graph
55
+ - **Enforce** referential integrity, DAG acyclicity, bidirectional links, and tier constraints at write time — not after the fact
56
+ - **Validate** the full epistemic web on demand against ten domain invariants
57
+ - **Track evidence** through prediction tiers (`FULLY_SPECIFIED`, `CONDITIONAL`, `FIT_CHECK`) with explicit independence-group accounting
58
+ - **Detect staleness** when a parameter changes and propagates to analyses and predictions
59
+ - **Health-check** the entire project in one command, with a machine-readable `HEALTHY / WARNINGS / CRITICAL` result suitable for CI
60
+ - **Render** human-readable markdown views of the project graph, incrementally
61
+
62
+ deSitter never executes analyses. Researchers run their own tools — Python, R, SageMath, Jupyter — and record outcomes. deSitter records provenance, enforces structure, and tracks what changed.
63
+
64
+ ---
65
+
66
+ ## Interfaces
67
+
68
+ deSitter exposes the same core system through three interfaces with different primary users:
69
+
70
+ **Python API — primary for researchers in scripts and notebooks**
71
+
72
+ ```python
73
+ from desitter import connect
74
+
75
+ client = connect(".")
76
+ result = client.register_claim(
77
+ id="C-001",
78
+ statement="Catalyst X increases yield.",
79
+ type="foundational",
80
+ scope="global",
81
+ falsifiability="A replicated null result would falsify this claim.",
82
+ )
83
+ ```
84
+
85
+ The Python API is the intended authoring surface for researchers. It wraps the same gateway used everywhere else, but exposes a programmatic workflow that fits normal Python scripts, notebooks, and research automation.
86
+
87
+ **MCP server — primary for AI agent sessions**
88
+
89
+ ```bash
90
+ ds-mcp # start the MCP server
91
+ ```
92
+
93
+ The [Model Context Protocol](https://modelcontextprotocol.io) lets AI assistants (Claude, Copilot, Cursor, and others) call deSitter tools directly as structured operations — no subprocess, no parsing, no screen-scraping. An agent calls `register_resource`, `health_check`, or `query_web` with typed arguments and receives a structured response. The same gateway that serves the Python API serves the MCP server: there is no divergence in behaviour.
94
+
95
+ The MCP interface is designed with AI-assisted research in mind. An agent with access to the deSitter tool surface can audit a derivation chain, identify structural gaps, pre-flight a new prediction with `dry_run=True`, and commit it — all within a single session. The epistemic web provides the shared, persistent, invariant-enforced state. The AI provides the reasoning.
96
+
97
+ **CLI — inspection, health-check, and audit tool**
98
+
99
+ ```bash
100
+ ds health
101
+ ds validate
102
+ ds status
103
+ ds render
104
+ ```
105
+
106
+ Every command accepts `--json` for machine-readable output. Shell scripts, CI pipelines, and audit tooling work naturally against the CLI. When JSON payloads are involved, the intended path is file-based ingestion or generated artifacts — not hand-written inline shell blobs.
107
+
108
+ ---
109
+
110
+ ## Quick Start
111
+
112
+ ```bash
113
+ pip install desitter # CLI + core
114
+ pip install "desitter[mcp]" # + MCP server for AI agent use
115
+ ```
116
+
117
+ ```python
118
+ from desitter import connect
119
+
120
+ client = connect(".")
121
+
122
+ client.register_claim(
123
+ id="C-001",
124
+ statement="Catalyst X increases yield.",
125
+ type="foundational",
126
+ scope="global",
127
+ falsifiability="A replicated null result would falsify this claim.",
128
+ )
129
+
130
+ claims = client.list_claims().data or []
131
+ ```
132
+
133
+ ```bash
134
+ # Inspect and audit from the CLI
135
+ ds health
136
+ ds validate
137
+ ds status
138
+
139
+ # Start the MCP server for AI agent sessions
140
+ ds-mcp
141
+ ```
142
+
143
+ If external automation needs to react to changes, it can watch `project/data/transaction_log.jsonl` directly. deSitter writes the log; other tools are free to consume it without using the CLI, Python API, or MCP server.
144
+
145
+ ---
146
+
147
+ ## Architecture
148
+
149
+ deSitter is built in layers, from the inside out. The innermost layer — the **epistemic kernel** — is pure Python with no I/O dependencies. It defines the entity model, the `EpistemicWeb` aggregate root, and all invariant rules. Nothing in the kernel touches a file, a database, or a network socket. This is what makes the core fully testable in memory and reusable without any infrastructure.
150
+
151
+ The layers above the kernel — adapters, control plane, view services, interfaces — each have a single responsibility and depend only on layers below them.
152
+
153
+ ```
154
+ ┌──────────────────────────────────────────────────────┐
155
+ │ Interface Layer │
156
+ │ cli/ — humans & scripts mcp/ — AI agents │
157
+ └─────────────────────┬────────────────────────────────┘
158
+
159
+ ┌─────────────────────▼────────────────────────────────┐
160
+ │ View Services │
161
+ │ health · status · metrics · render │
162
+ └─────────────────────┬────────────────────────────────┘
163
+
164
+ ┌─────────────────────▼────────────────────────────────┐
165
+ │ Control Plane (single gateway for all mutations) │
166
+ │ gateway · validate · check · export · automation │
167
+ └─────────────────────┬────────────────────────────────┘
168
+
169
+ ┌─────────────────────▼────────────────────────────────┐
170
+ │ Adapters │
171
+ │ json_repository · transaction_log · renderer │
172
+ └─────────────────────┬────────────────────────────────┘
173
+
174
+ ┌─────────────────────▼────────────────────────────────┐
175
+ │ Epistemic Kernel — pure Python, no I/O │
176
+ │ types · model · web · invariants · ports │
177
+ └──────────────────────────────────────────────────────┘
178
+ ```
179
+
180
+ All mutations route through a single `Gateway`. Both the CLI and the MCP server call the same gateway methods — there is no interface-specific business logic. A bug fixed at the gateway is fixed for every interface simultaneously.
181
+
182
+ See [ARCHITECTURE.md](ARCHITECTURE.md) for a full technical walkthrough: the entity model, copy-on-write mutation semantics, bidirectional invariant enforcement, every graph traversal method, the full transaction lifecycle, and a concrete end-to-end trace through the stack.
183
+
184
+ ---
185
+
186
+ ## Design Goals
187
+
188
+ | Goal | Meaning |
189
+ |------|---------|
190
+ | **Audit scaffold** | Surfaces structural facts. Never prescribes research direction or makes logical judgments |
191
+ | **Invariants at write time** | Broken references, cycles, and constraint violations are caught at mutation — not discovered later |
192
+ | **Single gateway** | All mutations flow through one boundary. No MCP-specific or CLI-specific business logic |
193
+ | **Consumer model** | deSitter records results from researcher-run analyses. It never executes code itself |
194
+ | **AI-native interface** | MCP server exposes all capabilities as typed tools. No subprocess, no parsing, full structure |
195
+ | **Human parity** | Every MCP tool has a CLI equivalent. Humans get Rich terminal output; scripts get `--json` |
196
+ | **Domain-neutral** | Works for physics, ML, medicine, social science. The vocabulary is general empirical reasoning |
197
+ | **Minimal dependencies** | Epistemic kernel is stdlib-only. `click` and `rich` for CLI. `fastmcp` is opt-in for MCP |
198
+
199
+ ---
200
+
201
+ ## Package Layout
202
+
203
+ ```
204
+ src/desitter/
205
+ ├── config.py # ProjectContext, ProjectPaths — runtime configuration contract
206
+ ├── epistemic/ # Epistemic kernel — pure Python, zero I/O
207
+ │ ├── types.py # Typed IDs, enums, Finding, Severity
208
+ │ ├── model.py # Entity dataclasses: Claim, Assumption, Prediction, …
209
+ │ ├── web.py # EpistemicWeb — aggregate root, all mutations
210
+ │ ├── invariants.py # Ten pure validator functions
211
+ │ └── ports.py # Abstract interfaces: WebRepository, WebValidator, …
212
+ ├── adapters/ # Infrastructure implementations
213
+ │ ├── json_repository.py # Implements WebRepository over project/data/*.json
214
+ │ ├── markdown_renderer.py
215
+ │ └── transaction_log.py
216
+ ├── controlplane/ # Core services
217
+ │ ├── gateway.py # Single mutation/query boundary + GatewayResult
218
+ │ ├── factory.py # Wires concrete adapters into Gateway
219
+ │ ├── validate.py
220
+ │ ├── check.py # analysis staleness, reference integrity, prose sync
221
+ │ ├── export.py
222
+ │ └── automation.py # Render-trigger policy table
223
+ ├── views/ # Read-only composed summaries
224
+ │ ├── health.py # run_health_check → HealthReport
225
+ │ ├── render.py # SHA-256 fingerprint cache + incremental render
226
+ │ ├── status.py # get_status → ProjectStatus
227
+ │ └── metrics.py
228
+ └── interfaces/ # Thin adapters — no business logic
229
+ ├── cli/
230
+ │ ├── main.py # Click command tree
231
+ │ └── formatters.py # Rich tables + JSON fallback
232
+ └── mcp/
233
+ ├── server.py # FastMCP entry point
234
+ └── tools.py # Tool handlers → gateway + view services
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Development Status
240
+
241
+ ```bash
242
+ pip install -e ".[dev]"
243
+ pytest
244
+ pytest --cov
245
+ ```
246
+
247
+ | Phase | Scope | Status |
248
+ |---|---|---|
249
+ | 1 | Epistemic kernel — `EpistemicWeb`, all entities, ten invariants | **Complete** — implemented and validated |
250
+ | 2 | Persistence, config, packaging | **Partial** — config, transaction log, and automation done; JSON repository and renderer stubbed |
251
+ | 3 | Control plane and view services — gateway, validate, health, render | In progress |
252
+ | 4 | Interface layer — MCP server and CLI | Pending |
253
+ | 5 | Human-first UX — Rich output, `ds inspect` | Pending |
254
+ | 6 | Result recording — latest recorded analysis output and provenance | Pending |
255
+ | 7 | Governance — session tracking, close gates (opt-in) | Pending |
256
+
257
+ The epistemic kernel (Phase 1) is the foundation the rest is built on. It is complete, fully tested, and stable. Layers above it are being built in the order listed.
258
+
259
+ See [TRACKER.md](TRACKER.md) for the full task-level breakdown.
260
+
261
+ ---
262
+
263
+ ## License
264
+
265
+ Apache License 2.0 — see [LICENSE](LICENSE).
@@ -0,0 +1,245 @@
1
+ # deSitter
2
+
3
+ *Versioned, invariant-enforced tracking for the epistemic structure of research.*
4
+
5
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
6
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
7
+ [![Status: Early Development](https://img.shields.io/badge/status-early%20development-orange.svg)](TRACKER.md)
8
+
9
+ > **Early development — not ready for production use.**
10
+ > The API, file formats, and CLI surface are unstable. See [TRACKER.md](TRACKER.md) for current build status.
11
+
12
+ ---
13
+
14
+ ## What It Is
15
+
16
+ The scientific method has a structure: you make **claims**, ground them in **assumptions**, derive **predictions**, run **analyses** to test those predictions, and record what the evidence shows. That structure exists in every research project, but it almost never gets tracked. It lives in Notion pages, email threads, and researcher memory — and it breaks silently.
17
+
18
+ A refuted prediction doesn't update the claims that depend on it. A revised assumption doesn't propagate to its consequences. Six months later, nobody can trace why a conclusion was drawn or whether the underlying support was ever intact.
19
+
20
+ deSitter makes that structure explicit and machine-enforceable. It is a versioned, graph-structured registry of your **epistemic chain** — every claim, assumption, prediction, analysis, and theory — with hard invariants that keep the graph consistent as research evolves.
21
+
22
+ deSitter is an **audit scaffold**, not a reasoning engine. It surfaces structural facts about the graph: missing links, untested assumptions, stale analyses, uncovered predictions. The researcher — or an AI agent — is the one who decides what to do about them.
23
+
24
+ For researchers, the primary interface is the Python API: `desitter.connect()` in scripts and notebooks. For AI agent sessions, the primary interface is the MCP server. The CLI remains important, but mainly as an inspection, health-check, render, and audit surface.
25
+
26
+ Nobody is expected to hand-author JSON payloads in the shell. deSitter's payloads are structured interchange formats for the gateway, external tooling, and file-based ingestion when needed — not the primary authoring workflow.
27
+
28
+ Every successful mutation is also recorded in the append-only transaction log at `project/data/transaction_log.jsonl`. That log is a first-class public artifact: external tools can watch it, index it, and react to it directly without going through deSitter.
29
+
30
+ ---
31
+
32
+ ## Core Capabilities
33
+
34
+ - **Register** claims, assumptions, predictions, analyses, theories, and parameters in a typed, versioned graph
35
+ - **Enforce** referential integrity, DAG acyclicity, bidirectional links, and tier constraints at write time — not after the fact
36
+ - **Validate** the full epistemic web on demand against ten domain invariants
37
+ - **Track evidence** through prediction tiers (`FULLY_SPECIFIED`, `CONDITIONAL`, `FIT_CHECK`) with explicit independence-group accounting
38
+ - **Detect staleness** when a parameter changes and propagates to analyses and predictions
39
+ - **Health-check** the entire project in one command, with a machine-readable `HEALTHY / WARNINGS / CRITICAL` result suitable for CI
40
+ - **Render** human-readable markdown views of the project graph, incrementally
41
+
42
+ deSitter never executes analyses. Researchers run their own tools — Python, R, SageMath, Jupyter — and record outcomes. deSitter records provenance, enforces structure, and tracks what changed.
43
+
44
+ ---
45
+
46
+ ## Interfaces
47
+
48
+ deSitter exposes the same core system through three interfaces with different primary users:
49
+
50
+ **Python API — primary for researchers in scripts and notebooks**
51
+
52
+ ```python
53
+ from desitter import connect
54
+
55
+ client = connect(".")
56
+ result = client.register_claim(
57
+ id="C-001",
58
+ statement="Catalyst X increases yield.",
59
+ type="foundational",
60
+ scope="global",
61
+ falsifiability="A replicated null result would falsify this claim.",
62
+ )
63
+ ```
64
+
65
+ The Python API is the intended authoring surface for researchers. It wraps the same gateway used everywhere else, but exposes a programmatic workflow that fits normal Python scripts, notebooks, and research automation.
66
+
67
+ **MCP server — primary for AI agent sessions**
68
+
69
+ ```bash
70
+ ds-mcp # start the MCP server
71
+ ```
72
+
73
+ The [Model Context Protocol](https://modelcontextprotocol.io) lets AI assistants (Claude, Copilot, Cursor, and others) call deSitter tools directly as structured operations — no subprocess, no parsing, no screen-scraping. An agent calls `register_resource`, `health_check`, or `query_web` with typed arguments and receives a structured response. The same gateway that serves the Python API serves the MCP server: there is no divergence in behaviour.
74
+
75
+ The MCP interface is designed with AI-assisted research in mind. An agent with access to the deSitter tool surface can audit a derivation chain, identify structural gaps, pre-flight a new prediction with `dry_run=True`, and commit it — all within a single session. The epistemic web provides the shared, persistent, invariant-enforced state. The AI provides the reasoning.
76
+
77
+ **CLI — inspection, health-check, and audit tool**
78
+
79
+ ```bash
80
+ ds health
81
+ ds validate
82
+ ds status
83
+ ds render
84
+ ```
85
+
86
+ Every command accepts `--json` for machine-readable output. Shell scripts, CI pipelines, and audit tooling work naturally against the CLI. When JSON payloads are involved, the intended path is file-based ingestion or generated artifacts — not hand-written inline shell blobs.
87
+
88
+ ---
89
+
90
+ ## Quick Start
91
+
92
+ ```bash
93
+ pip install desitter # CLI + core
94
+ pip install "desitter[mcp]" # + MCP server for AI agent use
95
+ ```
96
+
97
+ ```python
98
+ from desitter import connect
99
+
100
+ client = connect(".")
101
+
102
+ client.register_claim(
103
+ id="C-001",
104
+ statement="Catalyst X increases yield.",
105
+ type="foundational",
106
+ scope="global",
107
+ falsifiability="A replicated null result would falsify this claim.",
108
+ )
109
+
110
+ claims = client.list_claims().data or []
111
+ ```
112
+
113
+ ```bash
114
+ # Inspect and audit from the CLI
115
+ ds health
116
+ ds validate
117
+ ds status
118
+
119
+ # Start the MCP server for AI agent sessions
120
+ ds-mcp
121
+ ```
122
+
123
+ If external automation needs to react to changes, it can watch `project/data/transaction_log.jsonl` directly. deSitter writes the log; other tools are free to consume it without using the CLI, Python API, or MCP server.
124
+
125
+ ---
126
+
127
+ ## Architecture
128
+
129
+ deSitter is built in layers, from the inside out. The innermost layer — the **epistemic kernel** — is pure Python with no I/O dependencies. It defines the entity model, the `EpistemicWeb` aggregate root, and all invariant rules. Nothing in the kernel touches a file, a database, or a network socket. This is what makes the core fully testable in memory and reusable without any infrastructure.
130
+
131
+ The layers above the kernel — adapters, control plane, view services, interfaces — each have a single responsibility and depend only on layers below them.
132
+
133
+ ```
134
+ ┌──────────────────────────────────────────────────────┐
135
+ │ Interface Layer │
136
+ │ cli/ — humans & scripts mcp/ — AI agents │
137
+ └─────────────────────┬────────────────────────────────┘
138
+
139
+ ┌─────────────────────▼────────────────────────────────┐
140
+ │ View Services │
141
+ │ health · status · metrics · render │
142
+ └─────────────────────┬────────────────────────────────┘
143
+
144
+ ┌─────────────────────▼────────────────────────────────┐
145
+ │ Control Plane (single gateway for all mutations) │
146
+ │ gateway · validate · check · export · automation │
147
+ └─────────────────────┬────────────────────────────────┘
148
+
149
+ ┌─────────────────────▼────────────────────────────────┐
150
+ │ Adapters │
151
+ │ json_repository · transaction_log · renderer │
152
+ └─────────────────────┬────────────────────────────────┘
153
+
154
+ ┌─────────────────────▼────────────────────────────────┐
155
+ │ Epistemic Kernel — pure Python, no I/O │
156
+ │ types · model · web · invariants · ports │
157
+ └──────────────────────────────────────────────────────┘
158
+ ```
159
+
160
+ All mutations route through a single `Gateway`. Both the CLI and the MCP server call the same gateway methods — there is no interface-specific business logic. A bug fixed at the gateway is fixed for every interface simultaneously.
161
+
162
+ See [ARCHITECTURE.md](ARCHITECTURE.md) for a full technical walkthrough: the entity model, copy-on-write mutation semantics, bidirectional invariant enforcement, every graph traversal method, the full transaction lifecycle, and a concrete end-to-end trace through the stack.
163
+
164
+ ---
165
+
166
+ ## Design Goals
167
+
168
+ | Goal | Meaning |
169
+ |------|---------|
170
+ | **Audit scaffold** | Surfaces structural facts. Never prescribes research direction or makes logical judgments |
171
+ | **Invariants at write time** | Broken references, cycles, and constraint violations are caught at mutation — not discovered later |
172
+ | **Single gateway** | All mutations flow through one boundary. No MCP-specific or CLI-specific business logic |
173
+ | **Consumer model** | deSitter records results from researcher-run analyses. It never executes code itself |
174
+ | **AI-native interface** | MCP server exposes all capabilities as typed tools. No subprocess, no parsing, full structure |
175
+ | **Human parity** | Every MCP tool has a CLI equivalent. Humans get Rich terminal output; scripts get `--json` |
176
+ | **Domain-neutral** | Works for physics, ML, medicine, social science. The vocabulary is general empirical reasoning |
177
+ | **Minimal dependencies** | Epistemic kernel is stdlib-only. `click` and `rich` for CLI. `fastmcp` is opt-in for MCP |
178
+
179
+ ---
180
+
181
+ ## Package Layout
182
+
183
+ ```
184
+ src/desitter/
185
+ ├── config.py # ProjectContext, ProjectPaths — runtime configuration contract
186
+ ├── epistemic/ # Epistemic kernel — pure Python, zero I/O
187
+ │ ├── types.py # Typed IDs, enums, Finding, Severity
188
+ │ ├── model.py # Entity dataclasses: Claim, Assumption, Prediction, …
189
+ │ ├── web.py # EpistemicWeb — aggregate root, all mutations
190
+ │ ├── invariants.py # Ten pure validator functions
191
+ │ └── ports.py # Abstract interfaces: WebRepository, WebValidator, …
192
+ ├── adapters/ # Infrastructure implementations
193
+ │ ├── json_repository.py # Implements WebRepository over project/data/*.json
194
+ │ ├── markdown_renderer.py
195
+ │ └── transaction_log.py
196
+ ├── controlplane/ # Core services
197
+ │ ├── gateway.py # Single mutation/query boundary + GatewayResult
198
+ │ ├── factory.py # Wires concrete adapters into Gateway
199
+ │ ├── validate.py
200
+ │ ├── check.py # analysis staleness, reference integrity, prose sync
201
+ │ ├── export.py
202
+ │ └── automation.py # Render-trigger policy table
203
+ ├── views/ # Read-only composed summaries
204
+ │ ├── health.py # run_health_check → HealthReport
205
+ │ ├── render.py # SHA-256 fingerprint cache + incremental render
206
+ │ ├── status.py # get_status → ProjectStatus
207
+ │ └── metrics.py
208
+ └── interfaces/ # Thin adapters — no business logic
209
+ ├── cli/
210
+ │ ├── main.py # Click command tree
211
+ │ └── formatters.py # Rich tables + JSON fallback
212
+ └── mcp/
213
+ ├── server.py # FastMCP entry point
214
+ └── tools.py # Tool handlers → gateway + view services
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Development Status
220
+
221
+ ```bash
222
+ pip install -e ".[dev]"
223
+ pytest
224
+ pytest --cov
225
+ ```
226
+
227
+ | Phase | Scope | Status |
228
+ |---|---|---|
229
+ | 1 | Epistemic kernel — `EpistemicWeb`, all entities, ten invariants | **Complete** — implemented and validated |
230
+ | 2 | Persistence, config, packaging | **Partial** — config, transaction log, and automation done; JSON repository and renderer stubbed |
231
+ | 3 | Control plane and view services — gateway, validate, health, render | In progress |
232
+ | 4 | Interface layer — MCP server and CLI | Pending |
233
+ | 5 | Human-first UX — Rich output, `ds inspect` | Pending |
234
+ | 6 | Result recording — latest recorded analysis output and provenance | Pending |
235
+ | 7 | Governance — session tracking, close gates (opt-in) | Pending |
236
+
237
+ The epistemic kernel (Phase 1) is the foundation the rest is built on. It is complete, fully tested, and stable. Layers above it are being built in the order listed.
238
+
239
+ See [TRACKER.md](TRACKER.md) for the full task-level breakdown.
240
+
241
+ ---
242
+
243
+ ## License
244
+
245
+ Apache License 2.0 — see [LICENSE](LICENSE).
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "desitter"
7
+ version = "0.0.1"
8
+ description = "A control plane for managing research epistemic webs"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ dependencies = [
12
+ "click>=8.1",
13
+ "jsonschema>=4.21",
14
+ "rich>=13.0",
15
+ ]
16
+
17
+ [project.optional-dependencies]
18
+ mcp = [
19
+ "fastmcp>=0.1",
20
+ ]
21
+ compute = [
22
+ "numpy>=1.26",
23
+ "scipy>=1.12",
24
+ ]
25
+ dev = [
26
+ "pytest>=8.0",
27
+ "pytest-cov>=5.0",
28
+ ]
29
+ all = [
30
+ "desitter[mcp,compute]",
31
+ ]
32
+
33
+ [project.scripts]
34
+ ds = "desitter.interfaces.cli.main:cli"
35
+ ds-mcp = "desitter.interfaces.mcp.server:run"
36
+
37
+ [tool.setuptools]
38
+ package-dir = {"" = "src"}
39
+
40
+ [tool.setuptools.packages.find]
41
+ where = ["src"]
42
+
43
+ [tool.pytest.ini_options]
44
+ testpaths = ["tests"]
45
+ pythonpath = ["src"]
46
+
47
+ [tool.coverage.run]
48
+ source = ["desitter"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,28 @@
1
+ """deSitter (desitter) — control plane for research epistemic webs.
2
+
3
+ The CLI and MCP server are peer interfaces over the same gateway.
4
+ Both route through: controlplane.gateway.Gateway.
5
+
6
+ Layer cake (top to bottom):
7
+ interfaces — CLI and MCP adapters
8
+ views — read-only summaries and rendering services
9
+ controlplane — orchestration boundary above the epistemic kernel
10
+ epistemic — domain kernel: EpistemicWeb, entities, invariants, ports
11
+ adapters — JSON repo, markdown renderer, transaction log
12
+
13
+ Quick start (programmatic):
14
+ import desitter as ds
15
+
16
+ client = connect()
17
+ client.register_claim(
18
+ id="C-001",
19
+ statement="Catalyst X increases yield.",
20
+ type="foundational",
21
+ scope="global",
22
+ falsifiability="A replicated null result would falsify this claim.",
23
+ )
24
+ """
25
+
26
+ __version__ = "0.1.0"
27
+
28
+ from .client import ClientResult, DeSitterClient, DeSitterClientError, connect
@@ -0,0 +1,11 @@
1
+ """Entry point for `python -m desitter`.
2
+
3
+ Delegates to the Click CLI, so:
4
+ python -m desitter <command> [options]
5
+ is equivalent to:
6
+ ds <command> [options]
7
+ """
8
+ from desitter.interfaces.cli.main import cli
9
+
10
+ if __name__ == "__main__":
11
+ cli()
@@ -0,0 +1,11 @@
1
+ """Infrastructure adapters.
2
+
3
+ Implements the ports defined in epistemic/ports.py using stdlib I/O.
4
+ All adapters are thin — no business logic lives here.
5
+
6
+ Dependency rule: adapters depend on epistemic (for ports/types), never
7
+ on controlplane/views/features. Those layers depend on adapters through the ports.
8
+
9
+ External library rule: stdlib only (json, pathlib, subprocess, hashlib).
10
+ No third-party imports at module level.
11
+ """