mockworld-mcp 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.
- mockworld_mcp-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +13 -0
- mockworld_mcp-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
- mockworld_mcp-0.2.0/.github/good-first-issues.md +8 -0
- mockworld_mcp-0.2.0/.github/workflows/ci.yml +30 -0
- mockworld_mcp-0.2.0/.github/workflows/release.yml +59 -0
- mockworld_mcp-0.2.0/.gitignore +225 -0
- mockworld_mcp-0.2.0/CHANGELOG.md +65 -0
- mockworld_mcp-0.2.0/CITATION.cff +16 -0
- mockworld_mcp-0.2.0/CLAUDE.md +60 -0
- mockworld_mcp-0.2.0/CONTRIBUTING.md +21 -0
- mockworld_mcp-0.2.0/LICENSE +202 -0
- mockworld_mcp-0.2.0/PKG-INFO +152 -0
- mockworld_mcp-0.2.0/README.md +126 -0
- mockworld_mcp-0.2.0/ROADMAP.md +16 -0
- mockworld_mcp-0.2.0/SPEC.md +113 -0
- mockworld_mcp-0.2.0/docs/ARCHITECTURE.md +442 -0
- mockworld_mcp-0.2.0/docs/AUTHORING.md +82 -0
- mockworld_mcp-0.2.0/docs/DELIVERY-PLAN.md +194 -0
- mockworld_mcp-0.2.0/docs/PRD.md +265 -0
- mockworld_mcp-0.2.0/docs/RELEASING.md +40 -0
- mockworld_mcp-0.2.0/docs/RESEARCH.md +230 -0
- mockworld_mcp-0.2.0/docs/TEST-PLAN.md +234 -0
- mockworld_mcp-0.2.0/examples/demos/exactly_once_under_chaos.py +93 -0
- mockworld_mcp-0.2.0/examples/registry/mocks/weather/fidelity.md +14 -0
- mockworld_mcp-0.2.0/examples/registry/mocks/weather/handlers.py +14 -0
- mockworld_mcp-0.2.0/examples/registry/mocks/weather/mock.yaml +44 -0
- mockworld_mcp-0.2.0/examples/registry/mocks/weather/seed.py +20 -0
- mockworld_mcp-0.2.0/examples/registry/registry.json +15 -0
- mockworld_mcp-0.2.0/examples/worlds/ecommerce.yaml +15 -0
- mockworld_mcp-0.2.0/pyproject.toml +59 -0
- mockworld_mcp-0.2.0/src/mockworld/__init__.py +36 -0
- mockworld_mcp-0.2.0/src/mockworld/cli.py +324 -0
- mockworld_mcp-0.2.0/src/mockworld/control.py +169 -0
- mockworld_mcp-0.2.0/src/mockworld/datagen.py +61 -0
- mockworld_mcp-0.2.0/src/mockworld/determinism.py +136 -0
- mockworld_mcp-0.2.0/src/mockworld/dispatch.py +91 -0
- mockworld_mcp-0.2.0/src/mockworld/engine.py +230 -0
- mockworld_mcp-0.2.0/src/mockworld/errors.py +196 -0
- mockworld_mcp-0.2.0/src/mockworld/faults.py +198 -0
- mockworld_mcp-0.2.0/src/mockworld/handler_ctx.py +37 -0
- mockworld_mcp-0.2.0/src/mockworld/loader.py +176 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/crm/fidelity.md +38 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/crm/handlers.py +112 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/crm/mock.yaml +106 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/crm/seed.py +39 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/email/fidelity.md +86 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/email/handlers.py +79 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/email/mock.yaml +83 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/email/seed.py +61 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/exchange/fidelity.md +47 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/exchange/handlers.py +185 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/exchange/mock.yaml +94 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/exchange/seed.py +107 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/files/fidelity.md +65 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/files/handlers.py +73 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/files/mock.yaml +92 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/files/seed.py +45 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/hello/fidelity.md +13 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/hello/handlers.py +21 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/hello/mock.yaml +53 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/hello/seed.py +17 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/payments/fidelity.md +32 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/payments/handlers.py +122 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/payments/mock.yaml +96 -0
- mockworld_mcp-0.2.0/src/mockworld/mocks/payments/seed.py +61 -0
- mockworld_mcp-0.2.0/src/mockworld/pytest_plugin.py +52 -0
- mockworld_mcp-0.2.0/src/mockworld/record.py +330 -0
- mockworld_mcp-0.2.0/src/mockworld/registry.py +212 -0
- mockworld_mcp-0.2.0/src/mockworld/scaffold.py +120 -0
- mockworld_mcp-0.2.0/src/mockworld/schema.py +198 -0
- mockworld_mcp-0.2.0/src/mockworld/server.py +224 -0
- mockworld_mcp-0.2.0/src/mockworld/session.py +65 -0
- mockworld_mcp-0.2.0/src/mockworld/snapshot.py +76 -0
- mockworld_mcp-0.2.0/src/mockworld/state.py +258 -0
- mockworld_mcp-0.2.0/src/mockworld/swarm.py +173 -0
- mockworld_mcp-0.2.0/src/mockworld/trace.py +205 -0
- mockworld_mcp-0.2.0/src/mockworld/validate.py +87 -0
- mockworld_mcp-0.2.0/src/mockworld/verify.py +62 -0
- mockworld_mcp-0.2.0/src/mockworld/world.py +158 -0
- mockworld_mcp-0.2.0/tests/conftest.py +32 -0
- mockworld_mcp-0.2.0/tests/test_demo.py +25 -0
- mockworld_mcp-0.2.0/tests/test_descriptions.py +56 -0
- mockworld_mcp-0.2.0/tests/test_determinism.py +87 -0
- mockworld_mcp-0.2.0/tests/test_dx.py +64 -0
- mockworld_mcp-0.2.0/tests/test_e2e.py +130 -0
- mockworld_mcp-0.2.0/tests/test_faults.py +102 -0
- mockworld_mcp-0.2.0/tests/test_isolation.py +73 -0
- mockworld_mcp-0.2.0/tests/test_mcp_integration.py +84 -0
- mockworld_mcp-0.2.0/tests/test_observability.py +105 -0
- mockworld_mcp-0.2.0/tests/test_record.py +87 -0
- mockworld_mcp-0.2.0/tests/test_record_har.py +71 -0
- mockworld_mcp-0.2.0/tests/test_registry.py +74 -0
- mockworld_mcp-0.2.0/tests/test_snapshot_scenario.py +66 -0
- mockworld_mcp-0.2.0/tests/test_state_snapshot.py +34 -0
- mockworld_mcp-0.2.0/tests/test_swarm.py +50 -0
- mockworld_mcp-0.2.0/tests/test_validate.py +59 -0
- mockworld_mcp-0.2.0/tests/test_verify.py +65 -0
- mockworld_mcp-0.2.0/tests/test_world.py +55 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Seeded good-first-issues for mockworld
|
|
2
|
+
|
|
3
|
+
> Filed as real GitHub issues (label: `good-first-issue`) once the org repo exists.
|
|
4
|
+
|
|
5
|
+
1. Add a mock:sms service
|
|
6
|
+
2. Document the mock definition YAML format
|
|
7
|
+
3. Add a fault-injection (rate limit) example to the README
|
|
8
|
+
4. Seed a mock:shopify community template
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
gates:
|
|
10
|
+
# The determinism (G-DET), lint (G-LINT), isolation (G-ISO), and fault
|
|
11
|
+
# (G-FLT) gates from docs/TEST-PLAN.md §8 — must be green to merge.
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.11", "3.12"]
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v5
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
run: uv python install ${{ matrix.python-version }}
|
|
22
|
+
- name: Install
|
|
23
|
+
run: uv pip install --system -e ".[dev]"
|
|
24
|
+
- name: G-LINT — every built-in mock lints clean (entropy smells, schema)
|
|
25
|
+
run: |
|
|
26
|
+
for m in payments crm exchange email files; do mockworld validate mock:$m; done
|
|
27
|
+
- name: G-DET / G-ISO / G-FLT / G-E2E — full suite
|
|
28
|
+
run: python -m pytest -q
|
|
29
|
+
- name: G-DET (cross-run) — determinism demo reproduces
|
|
30
|
+
run: mockworld demo mock:payments
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Cut a release by pushing a version tag: `git tag v0.1.0 && git push origin v0.1.0`.
|
|
4
|
+
# Builds + smoke-tests the wheel, creates a GitHub release, and publishes to PyPI
|
|
5
|
+
# via Trusted Publishing (OIDC — no API token stored). See docs/RELEASING.md for
|
|
6
|
+
# the one-time PyPI setup.
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags: ["v*"]
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: astral-sh/setup-uv@v5
|
|
20
|
+
- name: Build sdist + wheel
|
|
21
|
+
run: uv build
|
|
22
|
+
- name: Smoke-test the wheel (clean install → run)
|
|
23
|
+
run: |
|
|
24
|
+
python -m venv /tmp/v
|
|
25
|
+
/tmp/v/bin/pip install dist/*.whl
|
|
26
|
+
/tmp/v/bin/mockworld list
|
|
27
|
+
/tmp/v/bin/mockworld demo mock:payments
|
|
28
|
+
- uses: actions/upload-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: dist
|
|
31
|
+
path: dist/
|
|
32
|
+
|
|
33
|
+
github-release:
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
permissions:
|
|
37
|
+
contents: write
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/download-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: dist
|
|
42
|
+
path: dist
|
|
43
|
+
- uses: softprops/action-gh-release@v2
|
|
44
|
+
with:
|
|
45
|
+
files: dist/*
|
|
46
|
+
generate_release_notes: true
|
|
47
|
+
|
|
48
|
+
pypi-publish:
|
|
49
|
+
needs: build
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
environment: pypi
|
|
52
|
+
permissions:
|
|
53
|
+
id-token: write # Trusted Publishing
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/download-artifact@v4
|
|
56
|
+
with:
|
|
57
|
+
name: dist
|
|
58
|
+
path: dist
|
|
59
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
# project
|
|
222
|
+
*.db
|
|
223
|
+
stampede-report.html
|
|
224
|
+
.env
|
|
225
|
+
.venv/
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to mockworld are documented here. Format loosely follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/); versions follow SemVer.
|
|
5
|
+
|
|
6
|
+
## [0.2.0] — 2026-09-02
|
|
7
|
+
|
|
8
|
+
Distribution renamed to **`mockworld-mcp`** on PyPI (`import mockworld` and the
|
|
9
|
+
`mockworld` CLI are unchanged) — the plain name is reserved by an unrelated project.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **OTLP trace export** (REQ-OBS-3): `mockworld run --otlp <collector-url>` POSTs
|
|
13
|
+
target-side spans as OTLP/HTTP JSON to `<url>/v1/traces` — dependency-free, so
|
|
14
|
+
mockworld traces drop into any OpenTelemetry backend. Best-effort and
|
|
15
|
+
self-disabling if the collector is down.
|
|
16
|
+
- **MCP resources** (REQ-MCP-4): each server exposes read-only reference data —
|
|
17
|
+
`mockworld://mock` (tools + state shape + fidelity), `mockworld://faults`
|
|
18
|
+
(declared fault catalog + profiles), and `mockworld://state/<collection>`
|
|
19
|
+
(the session's current data).
|
|
20
|
+
- **Ambiguous tool-description variants** (REQ-MCP-6): a tool can declare an
|
|
21
|
+
`ambiguous_description`; `--descriptions ambiguous` serves it. The swarm is
|
|
22
|
+
clarity-sensitive, so the misuse map can A/B description quality — e.g.
|
|
23
|
+
crm delete-vs-archive misuse rises from ~33% (clear) to ~46% (ambiguous),
|
|
24
|
+
reproducibly.
|
|
25
|
+
|
|
26
|
+
## [0.1.0] — 2026-09-01
|
|
27
|
+
|
|
28
|
+
First public release — the deterministic, LLM-free MCP mock engine plus the full
|
|
29
|
+
v0.1–v0.4 feature surface.
|
|
30
|
+
|
|
31
|
+
### Engine
|
|
32
|
+
- Seeded `DeterministicContext` (clock/ids/rng/fault-dice on independent
|
|
33
|
+
substreams); byte-identical replay across runs, hosts, and both state stores.
|
|
34
|
+
- Copy-on-write per-session isolation keyed on `Mcp-Session-Id` (50+ parallel
|
|
35
|
+
sessions, zero cross-talk).
|
|
36
|
+
- Declarative `mock.yaml` schema + Python handler ABI; Memory and SQLite stores.
|
|
37
|
+
- Business-logic fault injector: probabilistic + conditional (`when:`) faults,
|
|
38
|
+
profiles (`none`/`realistic`/`hostile`), realistic vendor-shaped error bodies.
|
|
39
|
+
- Target-side trace emission as an OpenTelemetry GenAI profile.
|
|
40
|
+
|
|
41
|
+
### Surface
|
|
42
|
+
- MCP over stdio and Streamable HTTP; out-of-band control plane; stampede
|
|
43
|
+
`Target` protocol.
|
|
44
|
+
- CLI: `run`, `list`, `inspect`, `validate`, `reset`, `demo`, `new`, `add`,
|
|
45
|
+
`search`, `pack`, `record`, `swarm`, `verify`, `snapshot`.
|
|
46
|
+
|
|
47
|
+
### Built-in mocks
|
|
48
|
+
- `payments` (Stripe-shaped), `crm` (delete-vs-archive misuse map), `exchange`,
|
|
49
|
+
`email`, `files`, and `hello` (the authoring example).
|
|
50
|
+
|
|
51
|
+
### Ecosystem
|
|
52
|
+
- Registry (`add`/`search`/`pack`) with checksum + safety gate.
|
|
53
|
+
- World composition with a shared identity namespace.
|
|
54
|
+
- Record-mode: scaffold a mock from an OpenAPI spec **or** a HAR capture.
|
|
55
|
+
- Scenario snapshots (portable `.mw.json` + migration).
|
|
56
|
+
- Swarm harness → Agent Readiness Report (the misuse map).
|
|
57
|
+
- Contract-verify against an OpenAPI for fidelity-drift governance.
|
|
58
|
+
|
|
59
|
+
### Developer experience
|
|
60
|
+
- A `mockworld` pytest fixture (via the `pytest11` entry point).
|
|
61
|
+
- `mockworld new` scaffold and `docs/AUTHORING.md`.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
- Wheel build no longer double-includes built-in mock data (removed a redundant
|
|
65
|
+
`force-include`); `pip install mockworld` now ships the mocks correctly.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software or dataset, please cite it as below."
|
|
3
|
+
title: "mockworld"
|
|
4
|
+
abstract: "A synthetic internet for agents. Part of the Swarm Proof toolkit."
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Boudoukha
|
|
7
|
+
given-names: Maroua
|
|
8
|
+
repository-code: "https://github.com/swarmproof/mockworld"
|
|
9
|
+
url: "https://github.com/swarmproof/mockworld"
|
|
10
|
+
license: Apache-2.0
|
|
11
|
+
type: software
|
|
12
|
+
keywords:
|
|
13
|
+
- ai-agents
|
|
14
|
+
- agent-reliability
|
|
15
|
+
- llm
|
|
16
|
+
- mcp
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What this repo is
|
|
6
|
+
|
|
7
|
+
**mockworld** — "a synthetic internet for agents": deterministic, LLM-free fake services (fake Stripe, Gmail, exchange, CRM, S3) exposed as MCP servers so agents can be built and tested without touching production. Part of the Swarm Proof toolkit; companion to [stampede](https://github.com/swarmproof/stampede) (stampede simulates the *agents*, mockworld simulates the *world* they act on). Apache-2.0.
|
|
8
|
+
|
|
9
|
+
**Current state: v0.1 + v0.2 implemented** (on feature branches; see git). Python 3.11+, official `mcp` SDK, pydantic v2, click, httpx; packaged with hatchling. Dev loop: `uv venv && uv pip install -e ".[dev]"`, then `python -m pytest -q` (53 tests, ~1s) and `mockworld <cmd>`.
|
|
10
|
+
|
|
11
|
+
### Module map (`src/mockworld/`)
|
|
12
|
+
- `determinism.py` — the seeded entropy funnel (clock/ids/rng/fault-dice). The root of all guarantees.
|
|
13
|
+
- `state.py` — `StateStore` (Memory/SQLite) + copy-on-write `StateView`; session isolation lives here.
|
|
14
|
+
- `session.py` — per-session logical counters. `schema.py` — pydantic `mock.yaml` models. `errors.py` — error library + `Result`.
|
|
15
|
+
- `faults.py` — fault injector (probabilistic + `when:` conditional). `dispatch.py` — CRUD + handler ABI. `handler_ctx.py` — the `ctx` handed to handlers.
|
|
16
|
+
- `loader.py` — load a mock dir (+ registry-installed resolution). `engine.py` — the transport-free call path (start here to trace a request).
|
|
17
|
+
- `trace.py` — OTel-GenAI-profile spans + NDJSON sink + OTLP/HTTP JSON exporter (`--otlp`). `server.py` — MCP stdio+HTTP adapter, also exposes read-only `mockworld://` resources. `control.py` — control plane + stampede `Target`. `cli.py` — commands. `validate.py` — the entropy linter.
|
|
18
|
+
- `registry.py` (v0.2) — `add`/`search`, checksum + safety gate. `world.py` (v0.2) — compose mocks with a shared identity pool. `record.py` (v0.2) — OpenAPI → scaffold.
|
|
19
|
+
- `snapshot.py` (v0.3) — portable `.mw.json` artifacts + migration. `swarm.py` (v0.3) — persona swarm → Agent Readiness Report (misuse map). `verify.py` (v0.3) — contract-drift vs OpenAPI.
|
|
20
|
+
- `mocks/<name>/` — the five built-ins (`mock.yaml` + `handlers.py` + `seed.py` + `fidelity.md`).
|
|
21
|
+
|
|
22
|
+
CLI: `run` (stdio/http, also `run world:<file>`), `list`, `inspect`, `validate`, `reset`, `demo`, `add`, `search`, `pack`, `record`. The engine is deliberately MCP-free; server/control/CLI are thin adapters (keeps determinism/isolation tests pure).
|
|
23
|
+
|
|
24
|
+
## Document map
|
|
25
|
+
|
|
26
|
+
- `SPEC.md` — the original v1.0 spec/PRD (root-level, high-level).
|
|
27
|
+
- `docs/PRD.md` — detailed requirements; **the source of REQ-IDs** (`REQ-DET-*`, `REQ-ISO-*`, `REQ-FAULT-*`, …) that every other doc cross-references.
|
|
28
|
+
- `docs/ARCHITECTURE.md` — authoritative design: engine components, the `mock.yaml` schema, handler ABI, session isolation, the stampede integration contract (§7), and ADRs 1–7.
|
|
29
|
+
- `docs/DELIVERY-PLAN.md` — milestones (v0.1/0.2/0.3), work breakdown (epics A–I), mock build order, definition of done, launch checklist.
|
|
30
|
+
- `docs/TEST-PLAN.md` — test pyramid, E2E scenarios (Given/When/Then), and the CI gates (G-DET, G-ISO, …) that define "green to merge/release".
|
|
31
|
+
- `docs/RESEARCH.md` — competitive landscape and open questions.
|
|
32
|
+
|
|
33
|
+
Doc conventions: `⊕ Beyond original spec` marks design that extends `SPEC.md`; keep REQ-ID cross-references intact when editing; keep the "Last updated" line current on `docs/*` edits.
|
|
34
|
+
|
|
35
|
+
## Architecture (the invariants all future code must serve)
|
|
36
|
+
|
|
37
|
+
1. **Determinism is a hard contract, not a mode** (ADR-4). All entropy — clock, RNG, IDs, fault dice — flows through one seeded `DeterministicContext`. Handlers may only use `ctx.clock` / `ctx.ids` / `ctx.rng`; importing `time`, `random`, `uuid` in a handler is a lint violation. Fault dice draw from a *separate* PRNG substream so adding a tool call doesn't shift unrelated faults. `reset(seed)` must be indistinguishable from a fresh boot at that seed. **No LLM in the response path, ever — that's the moat.**
|
|
38
|
+
2. **Session isolation rides MCP** (ADR-2). Sessions are keyed on MCP's `Mcp-Session-Id` (stdio = one implicit session), implemented as copy-on-write overlays over an immutable seeded base state — 50+ parallel sessions share one base dataset with no cross-talk.
|
|
39
|
+
3. **Declarative-first, Python escape hatch** (ADR-5). A mock is a directory: `mock.yaml` (authoritative), optional `handlers.py` (ABI: `handler(ctx, params) -> Result`, pure w.r.t. injected entropy), optional `seed.py`, and `fidelity.md` documenting what it does/doesn't model. Simple CRUD needs no code.
|
|
40
|
+
4. **Fault split with stampede** (ADR-6): mockworld owns *business-logic* faults only (`card_declined`, `insufficient_funds`, `rate_limited`, latency, partial outage) as first-class objects with realistic error bodies. Transport chaos (connection kills, socket timeouts, malformed frames) belongs to stampede/Toxiproxy — never implement it here. When a `MockworldTarget` is in use, stampede suppresses its transport rate_limit in favor of mockworld's semantic 429.
|
|
41
|
+
5. **State store**: `MemoryStore` default, `SQLiteStore` for persistence/snapshots, behind one `StateStore` API (ADR-3) — both must pass a shared conformance suite.
|
|
42
|
+
6. **Consume siblings' primitives, never redefine them.** Tracing uses stampede's trace-format, which is an **OpenTelemetry GenAI profile** — mockworld emits standard `gen_ai.*` attributes plus the shared `swarmproof.*` extension (`swarmproof.span.side="target"`, `swarmproof.fault.{type,injected,source}`). No `mockworld.*` namespace. Target spans are `span.kind=SERVER`, parented to stampede's `execute_tool` CLIENT span, joined on echoed `gen_ai.tool.call.id`; `traceparent` is read from HTTP headers or MCP `_meta.traceparent` on stdio.
|
|
43
|
+
|
|
44
|
+
### The stampede contract (confirmed 2026-07-13, ARCHITECTURE §7)
|
|
45
|
+
|
|
46
|
+
mockworld implements stampede's full `Target` protocol: `discover / invoke / reset(seed) / health / isolation() → per_agent / safety_descriptor() → {sandboxed: True}`, plus a control plane (`boot / reset / set_faults / snapshot / restore / session_reset`). `reset(seed)` means state is a *pure function* of the seed. Changes to this seam must stay consistent with stampede's side of the contract.
|
|
47
|
+
|
|
48
|
+
### v0.1 mock build order (stampede-demo-driven, not SPEC order)
|
|
49
|
+
|
|
50
|
+
`payments` (marquee) → `crm` (misuse-map demo) → `exchange` → `email` → `files`. Each mock must enforce its stateful invariants (e.g. refund ≤ captured, balance conservation, soft-delete ≠ hard-delete) and declare ≥3 seeded faults — see TEST-PLAN §7 for the per-mock acceptance table.
|
|
51
|
+
|
|
52
|
+
## Testing philosophy (when code lands)
|
|
53
|
+
|
|
54
|
+
Determinism/replay tests are the load-bearing acceptance gates, not an afterthought. Merge-blocking CI gates: G-DET (byte-identical transcripts across runs/hosts/both stores, DT-1..6), G-LINT (ambient-entropy lint + `mockworld validate`), G-ISO (isolation incl. 50 parallel sessions), G-UNIT (≥90% on engine core). E2E scenarios in TEST-PLAN §4 are the release gates.
|
|
55
|
+
|
|
56
|
+
## Conventions
|
|
57
|
+
|
|
58
|
+
- Conventional Commits (`feat:`, `fix:`, `docs:`, …); branches `feat/<short-name>`; atomic commits.
|
|
59
|
+
- Scope discipline: mocks are "realistic enough to break agents correctly," never vendor-exact clones (non-goal NG2) — resist fidelity scope creep; `fidelity.md` is where coverage boundaries live.
|
|
60
|
+
- Toolkit principles: provider-agnostic, honest over impressive, watchable & reproducible (seedable outputs).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Contributing to mockworld
|
|
2
|
+
|
|
3
|
+
Thanks for helping build **mockworld** — part of the [Swarm Proof toolkit](https://github.com/swarmproof).
|
|
4
|
+
|
|
5
|
+
## Ways to contribute
|
|
6
|
+
- **Good first issues** — look for the `good-first-issue` label. A few are seeded to get you started.
|
|
7
|
+
- **Bug reports** — open an issue with a minimal reproduction.
|
|
8
|
+
- **Features & discussion** — open an issue before a large PR so we can align on direction.
|
|
9
|
+
|
|
10
|
+
## Development
|
|
11
|
+
1. Fork and clone.
|
|
12
|
+
2. Create a branch: `git checkout -b feat/<short-name>`.
|
|
13
|
+
3. Keep commits atomic and use [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`, `fix:`, `docs:`, ...).
|
|
14
|
+
4. Open a PR describing *what* changed and *why*.
|
|
15
|
+
|
|
16
|
+
## Principles (shared across the toolkit)
|
|
17
|
+
- **Provider-agnostic** — no hard dependency on a single model vendor.
|
|
18
|
+
- **Honest over impressive** — we don't overpromise guarantees; we document boundaries.
|
|
19
|
+
- **Watchable & reproducible** — outputs should be seedable and screenshot-worthy.
|
|
20
|
+
|
|
21
|
+
By contributing you agree your work is licensed under this repo's LICENSE.
|