softschema 0.1.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 (39) hide show
  1. softschema-0.1.1/.gitignore +225 -0
  2. softschema-0.1.1/AGENTS.md +77 -0
  3. softschema-0.1.1/LICENSE +21 -0
  4. softschema-0.1.1/PKG-INFO +230 -0
  5. softschema-0.1.1/README.md +203 -0
  6. softschema-0.1.1/docs/development.md +134 -0
  7. softschema-0.1.1/docs/installation.md +25 -0
  8. softschema-0.1.1/docs/publishing.md +23 -0
  9. softschema-0.1.1/docs/softschema-guide.md +626 -0
  10. softschema-0.1.1/docs/softschema-python-design.md +329 -0
  11. softschema-0.1.1/docs/softschema-spec.md +216 -0
  12. softschema-0.1.1/examples/__init__.py +1 -0
  13. softschema-0.1.1/examples/movie_page/README.md +74 -0
  14. softschema-0.1.1/examples/movie_page/__init__.py +5 -0
  15. softschema-0.1.1/examples/movie_page/host_integration.py +41 -0
  16. softschema-0.1.1/examples/movie_page/model.py +77 -0
  17. softschema-0.1.1/examples/movie_page/movie-page.schema.yaml +162 -0
  18. softschema-0.1.1/examples/movie_page/spirited-away.md +72 -0
  19. softschema-0.1.1/packages/python/README.md +31 -0
  20. softschema-0.1.1/packages/python/src/softschema/__init__.py +72 -0
  21. softschema-0.1.1/packages/python/src/softschema/cli.py +450 -0
  22. softschema-0.1.1/packages/python/src/softschema/compile.py +120 -0
  23. softschema-0.1.1/packages/python/src/softschema/generate.py +216 -0
  24. softschema-0.1.1/packages/python/src/softschema/models.py +99 -0
  25. softschema-0.1.1/packages/python/src/softschema/py.typed +1 -0
  26. softschema-0.1.1/packages/python/src/softschema/registry.py +26 -0
  27. softschema-0.1.1/packages/python/src/softschema/schema_view.py +242 -0
  28. softschema-0.1.1/packages/python/src/softschema/sfield.py +90 -0
  29. softschema-0.1.1/packages/python/src/softschema/validate.py +557 -0
  30. softschema-0.1.1/packages/python/tests/test_cli.py +308 -0
  31. softschema-0.1.1/packages/python/tests/test_core.py +328 -0
  32. softschema-0.1.1/packages/python/tests/test_generate.py +154 -0
  33. softschema-0.1.1/packages/python/tests/test_movie_page_example.py +91 -0
  34. softschema-0.1.1/packages/python/tests/test_schema_view.py +102 -0
  35. softschema-0.1.1/packages/python/tests/test_sfield.py +96 -0
  36. softschema-0.1.1/packages/python/tests/test_warning_codes.py +135 -0
  37. softschema-0.1.1/packages/typescript/README.md +26 -0
  38. softschema-0.1.1/pyproject.toml +160 -0
  39. softschema-0.1.1/skills/softschema/SKILL.md +59 -0
@@ -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
+ # Local scratch space
213
+ tmp/
214
+ trash/
215
+ attic/
216
+ *.bak
217
+ *.orig
218
+
219
+ # Marimo
220
+ marimo/_static/
221
+ marimo/_lsp/
222
+ __marimo__/
223
+
224
+ # Streamlit
225
+ .streamlit/secrets.toml
@@ -0,0 +1,77 @@
1
+ # Agent Instructions
2
+
3
+ This repo teaches and implements the soft schema pattern.
4
+
5
+ Start here:
6
+
7
+ - [Softschema Guide](docs/softschema-guide.md): standalone concept and adoption guide
8
+ for humans and agents.
9
+ - [Softschema Spec](docs/softschema-spec.md): exact language-neutral artifact format.
10
+ - [Movie page example](examples/movie_page/README.md): complete Python-backed example.
11
+
12
+ For implementer reference (only when changing the Python package itself):
13
+
14
+ - [Python Package Design](docs/softschema-python-design.md): module layout, CLI surface,
15
+ validation layers, and ADR-style decisions.
16
+ Skip when only authoring or validating artifacts.
17
+
18
+ Key rules:
19
+
20
+ - Treat YAML/frontmatter as the authoritative structured data.
21
+ - Do not parse Markdown body prose or tables for consumed values.
22
+ - Use `softschema.contract`, not `schema`, in authored artifact metadata.
23
+ - Contract IDs name artifact payload contracts, not a specific Python class.
24
+ - Keep examples public and practical; do not introduce private business context,
25
+ internal project names, or proprietary domains.
26
+ - Use `uv` for Python workflows.
27
+
28
+ Common commands:
29
+
30
+ ```bash
31
+ uv sync --all-extras
32
+ uv run python devtools/lint.py --check
33
+ uv run pytest
34
+ uv build
35
+ uv run softschema docs --list
36
+ uv run softschema docs --list --json
37
+ uv run softschema skill --brief
38
+ ```
39
+
40
+ When adding a schema, start by identifying the values downstream consumers actually
41
+ need. Promote those values into YAML, validate them at the boundary, and leave the rest
42
+ as readable Markdown unless it is truly consumed as data.
43
+
44
+ Documentation rules:
45
+
46
+ - Follow `common-doc-guidelines.md` (github.com/jlevy/practical-prose): clear structure,
47
+ concise language, present-state descriptions, and enough context for a low-context
48
+ reader.
49
+ - Keep the README as a short subset of `docs/softschema-guide.md`.
50
+ - Put exact artifact-format rules in `docs/softschema-spec.md`.
51
+ - Keep examples as copyable source files under `examples/`; the CLI may print them, but
52
+ should not scaffold or mutate projects in the first release.
53
+ - Include the standard documentation footer in repo docs.
54
+ Do not add it to authored softschema example artifacts.
55
+
56
+ <!-- This document follows common-doc-guidelines.md.
57
+ See github.com/jlevy/practical-prose and review guidelines before editing.
58
+ -->
59
+
60
+ <!-- BEGIN TBD INTEGRATION format=f04 surface=agents-md -->
61
+ ## tbd
62
+
63
+ This repository uses **tbd** for git-native issue tracking (beads), spec-driven
64
+ planning, and on-demand engineering guidelines.
65
+ As the agent, you operate tbd on the user’s behalf — translate their requests into tbd
66
+ actions rather than telling them to run commands.
67
+
68
+ - Run `tbd prime` to load current project state and the full tbd workflow.
69
+ - Run `tbd skill` for the complete reusable tbd skill instructions.
70
+ - Run `tbd shortcut --list` and `tbd guidelines --list` for on-demand resources.
71
+ - Track all work as beads: `tbd create`, `tbd ready`, `tbd close`, and `tbd sync`.
72
+
73
+ <!-- END TBD INTEGRATION -->
74
+
75
+ <!-- This document follows common-doc-guidelines.md.
76
+ See github.com/jlevy/practical-prose and review guidelines before editing.
77
+ -->
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Joshua Levy
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,230 @@
1
+ Metadata-Version: 2.4
2
+ Name: softschema
3
+ Version: 0.1.1
4
+ Summary: Soft schema conventions and validation tools for Markdown/YAML artifacts
5
+ Project-URL: Homepage, https://github.com/jlevy/softschema
6
+ Project-URL: Repository, https://github.com/jlevy/softschema
7
+ Project-URL: Issues, https://github.com/jlevy/softschema/issues
8
+ Author: Joshua Levy
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: <4.0,>=3.11
22
+ Requires-Dist: frontmatter-format>=0.3.0
23
+ Requires-Dist: jsonschema>=4.20
24
+ Requires-Dist: pydantic>=2
25
+ Requires-Dist: pyyaml
26
+ Description-Content-Type: text/markdown
27
+
28
+ # softschema
29
+
30
+ Soft schemas are a practice for adding structure gradually to artifacts that mix human
31
+ context and machine-readable values.
32
+
33
+ They are useful when a document is valuable as context for humans and agents and also
34
+ needs a few values that downstream code or agents can read reliably.
35
+ Keeping prose and structured values in one artifact is more context-efficient and more
36
+ flexible than splitting them: a reader (human or agent) has only one place to look, and
37
+ each value can stay as loose prose until a downstream consumer needs it formal.
38
+
39
+ The practice is language-neutral.
40
+ This repo ships a spec and an implementation in Python.
41
+
42
+ It’s generally easiest to do this with Markdown and YAML frontmatter.
43
+ The YAML carries the structured values.
44
+ The Markdown body stays readable for humans and agents and offers additional context.
45
+
46
+ **Soft schemas** name the general practice; **softschema** names both this repository’s
47
+ Markdown-and-YAML spec and the matching `softschema` CLI that implements it.
48
+ The CLI is a Python package usable as a command-line tool or library for formatting,
49
+ compilation, validation, and other common workflows.
50
+
51
+ ## Core Idea
52
+
53
+ A *hard* schema imposes structure up front: define a rigid contract, then reject
54
+ anything that doesn’t fit.
55
+ That suits data that is already uniform, but it is a poor fit for documents a human or
56
+ agent writes, where most of the content is prose and only a few values need to be
57
+ machine-readable.
58
+
59
+ A soft schema adds structure gradually instead.
60
+ Structure runs along a spectrum, and each value moves along it only when it earns the
61
+ move:
62
+
63
+ ```text
64
+ prose
65
+ -> expected sections and vocabulary
66
+ -> YAML/frontmatter values for consumed fields
67
+ -> schema validation at boundaries
68
+ -> pure data or deterministic code when the shape is stable
69
+ ```
70
+
71
+ Promote a value into YAML when a tool reads it, validate it at the boundary when
72
+ correctness matters, and tighten enforcement over time.
73
+ Each promotion buys efficiency for some downstream consumer, so structure and efficiency
74
+ grow together, value by value.
75
+ Everything else stays readable Markdown.
76
+ The structured values live in the YAML payload, the boundary a tool reads, while the
77
+ prose body stays unconstrained.
78
+ Structure has real costs in authoring effort and rigidity, and adding it before a
79
+ consumer needs it costs more than leaving it loose: a contract with consumers is harder
80
+ to loosen than prose is to tighten.
81
+ So add structure where it pays for itself.
82
+ This fits the file artifacts that pass between steps of an agent process, where each
83
+ artifact mixes the context a step produces with the few values the next step consumes.
84
+ It works especially well in pipelines built for coding agents, which can call the
85
+ `softschema` CLI to test and validate the code, docs, and data they produce, alongside
86
+ the linters, tests, and type checkers they already run.
87
+
88
+ ## Artifact Shape
89
+
90
+ The default shape is Markdown with YAML frontmatter.
91
+ Use `softschema.contract` to name the contract for the enclosed payload:
92
+
93
+ ```markdown
94
+ ---
95
+ softschema:
96
+ contract: example.movies:MoviePage/v1
97
+ status: enforced
98
+ movie:
99
+ title: Spirited Away
100
+ release_year: 2001
101
+ runtime_minutes: 125
102
+ mpaa_rating: PG
103
+ directors:
104
+ - Hayao Miyazaki
105
+ genres:
106
+ - Animation
107
+ - Adventure
108
+ - Family
109
+ synopsis: >
110
+ Ten-year-old Chihiro and her parents stumble into a mysterious abandoned town
111
+ that turns out to be a spirit world...
112
+ cast:
113
+ - actor: Rumi Hiiragi
114
+ character: Chihiro / Sen
115
+ - actor: Miyu Irino
116
+ character: Haku
117
+ ratings:
118
+ rotten_tomatoes:
119
+ critics_percent: 96
120
+ audience_percent: 96
121
+ critic_review_count: 225
122
+ imdb:
123
+ score: 8.6
124
+ total_votes: 850000
125
+ ---
126
+ # Spirited Away (2001)
127
+
128
+ Hayao Miyazaki’s animated fantasy follows ten-year-old Chihiro into a spirit world, where
129
+ she works in a bathhouse for the gods to free her parents from a witch’s curse. It won the
130
+ 2003 Academy Award for Best Animated Feature.
131
+
132
+ Critics and audiences both score it 96% on Rotten Tomatoes; IMDb users rate it 8.6/10.
133
+ ```
134
+
135
+ The YAML payload is authoritative.
136
+ The Markdown body overlaps with it but need not match it field for field: here the prose
137
+ adds the film’s Oscar win and leaves out the cast and genres, while a consumer reads
138
+ only the YAML.
139
+
140
+ The example illustrates the structural variety a softschema artifact can carry:
141
+ constrained integers (`release_year`, `runtime_minutes`), an enum (`mpaa_rating`
142
+ restricted to `G`, `PG`, `PG-13`, `R`, `NC-17`, `NR`), lists of strings (`directors`,
143
+ `genres`), a list of structured records (`cast`), and nested objects (`ratings`). The
144
+ full artifact, model, and generated JSON Schema live under
145
+ [examples/movie_page/](examples/movie_page/README.md).
146
+
147
+ ## Contract IDs
148
+
149
+ Recommended style:
150
+
151
+ ```text
152
+ namespace:UpperCamelCaseName/version
153
+ ```
154
+
155
+ Examples:
156
+
157
+ - `example.movies:MoviePage/v1`
158
+ - `example.docs:IncidentReview/v1`
159
+ - `com.acme.docs:IncidentReview/1.0`
160
+
161
+ The ID names an artifact payload contract, not a required class or import path.
162
+
163
+ ## Try the Python Package
164
+
165
+ Install dependencies:
166
+
167
+ ```bash
168
+ uv sync --all-extras
169
+ ```
170
+
171
+ Validate the example:
172
+
173
+ ```bash
174
+ uv run softschema validate examples/movie_page/spirited-away.md \
175
+ --model examples.movie_page.model:MoviePage \
176
+ --schema examples/movie_page/movie-page.schema.yaml
177
+ ```
178
+
179
+ `validate` reads `softschema.contract`, `softschema.status`, and the single top-level
180
+ envelope key from the YAML by default.
181
+ Use `--contract`, `--status`, or `--envelope` only to override or disambiguate.
182
+
183
+ Read the bundled docs from the CLI:
184
+
185
+ ```bash
186
+ uv run softschema docs --list
187
+ uv run softschema docs --list --json
188
+ uv run softschema docs guide
189
+ uv run softschema docs example-artifact
190
+ uv run softschema skill --brief
191
+ ```
192
+
193
+ The examples are plain files under `examples/`. The CLI can print them so an agent or
194
+ human can copy from them, but it does not scaffold or mutate another project.
195
+
196
+ Compile the example schema sidecar:
197
+
198
+ ```bash
199
+ uv run softschema compile examples.movie_page.model:MoviePage \
200
+ --contract example.movies:MoviePage/v1 \
201
+ --out examples/movie_page/movie-page.schema.yaml
202
+ ```
203
+
204
+ ## Repository Layout
205
+
206
+ ```text
207
+ docs/ guide, spec, Python package design, and workflow docs
208
+ examples/movie_page/ complete example with model, host integration, artifact, schema
209
+ packages/python/ Python implementation and tests
210
+ packages/typescript/ future TypeScript/Zod notes only
211
+ skills/softschema/ agent-facing usage guidance
212
+ ```
213
+
214
+ The root `pyproject.toml` builds the Python package from
215
+ `packages/python/src/softschema`. This keeps the first release simple while leaving room
216
+ for a future TypeScript package.
217
+
218
+ ## Docs
219
+
220
+ - [Softschema Guide](docs/softschema-guide.md)
221
+ - [Softschema Spec](docs/softschema-spec.md)
222
+ - [Python Package Design](docs/softschema-python-design.md)
223
+ - [Installing uv and Python](docs/installation.md)
224
+ - [Development](docs/development.md)
225
+ - [Publishing](docs/publishing.md)
226
+ - [Movie Page Example](examples/movie_page/README.md)
227
+
228
+ <!-- This document follows common-doc-guidelines.md.
229
+ See github.com/jlevy/practical-prose and review guidelines before editing.
230
+ -->