softschema 0.1.3__tar.gz → 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.
Files changed (64) hide show
  1. {softschema-0.1.3 → softschema-0.2.0}/AGENTS.md +4 -8
  2. softschema-0.2.0/PKG-INFO +354 -0
  3. softschema-0.2.0/README.md +326 -0
  4. {softschema-0.1.3 → softschema-0.2.0}/docs/development.md +21 -15
  5. softschema-0.2.0/docs/e2e-testing.runbook.md +209 -0
  6. softschema-0.2.0/docs/installation.md +89 -0
  7. softschema-0.2.0/docs/publishing.md +138 -0
  8. {softschema-0.1.3 → softschema-0.2.0}/docs/softschema-guide.md +152 -66
  9. {softschema-0.1.3 → softschema-0.2.0}/docs/softschema-python-design.md +104 -42
  10. softschema-0.2.0/docs/softschema-spec.md +437 -0
  11. {softschema-0.1.3 → softschema-0.2.0}/docs/softschema-typescript-design.md +17 -10
  12. {softschema-0.1.3 → softschema-0.2.0}/examples/movie_page/README.md +22 -17
  13. {softschema-0.1.3 → softschema-0.2.0}/examples/movie_page/spirited-away.md +2 -0
  14. {softschema-0.1.3 → softschema-0.2.0}/packages/python/README.md +3 -3
  15. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/__init__.py +14 -7
  16. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/canonicalize.py +42 -4
  17. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/cli.py +228 -83
  18. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/compile.py +6 -6
  19. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/errors.py +1 -1
  20. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/generate.py +31 -19
  21. softschema-0.2.0/packages/python/src/softschema/models.py +120 -0
  22. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/schema_view.py +5 -5
  23. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/soft_field.py +4 -4
  24. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/validate.py +223 -67
  25. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_cli.py +181 -14
  26. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_core.py +158 -5
  27. softschema-0.2.0/packages/python/tests/test_doc_topics_resolve.py +41 -0
  28. softschema-0.2.0/packages/python/tests/test_enforced_extras.py +99 -0
  29. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_generate.py +72 -10
  30. softschema-0.2.0/packages/python/tests/test_metadata_rules.py +42 -0
  31. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_movie_page_example.py +22 -16
  32. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_parity.py +3 -3
  33. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_schema_view.py +3 -3
  34. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_soft_field.py +3 -3
  35. {softschema-0.1.3 → softschema-0.2.0}/packages/typescript/README.md +6 -5
  36. {softschema-0.1.3 → softschema-0.2.0}/pyproject.toml +7 -5
  37. softschema-0.2.0/skills/softschema/SKILL.md +117 -0
  38. softschema-0.2.0/tests/golden/README.md +118 -0
  39. softschema-0.1.3/PKG-INFO +0 -422
  40. softschema-0.1.3/README.md +0 -394
  41. softschema-0.1.3/docs/installation.md +0 -25
  42. softschema-0.1.3/docs/publishing.md +0 -188
  43. softschema-0.1.3/docs/softschema-spec.md +0 -230
  44. softschema-0.1.3/packages/python/src/softschema/models.py +0 -79
  45. softschema-0.1.3/skills/softschema/SKILL.md +0 -82
  46. softschema-0.1.3/tests/golden/README.md +0 -68
  47. {softschema-0.1.3 → softschema-0.2.0}/.gitignore +0 -0
  48. {softschema-0.1.3 → softschema-0.2.0}/LICENSE +0 -0
  49. {softschema-0.1.3 → softschema-0.2.0}/docs/publishing-npm.md +0 -0
  50. {softschema-0.1.3 → softschema-0.2.0}/examples/__init__.py +0 -0
  51. {softschema-0.1.3 → softschema-0.2.0}/examples/movie_page/__init__.py +0 -0
  52. {softschema-0.1.3 → softschema-0.2.0}/examples/movie_page/host_integration.py +0 -0
  53. {softschema-0.1.3 → softschema-0.2.0}/examples/movie_page/model.py +0 -0
  54. {softschema-0.1.3 → softschema-0.2.0}/examples/movie_page/movie-page.schema.yaml +0 -0
  55. {softschema-0.1.3 → softschema-0.2.0}/examples/parity/__init__.py +0 -0
  56. {softschema-0.1.3 → softschema-0.2.0}/examples/parity/model.py +0 -0
  57. {softschema-0.1.3 → softschema-0.2.0}/examples/parity/parity.schema.yaml +0 -0
  58. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/py.typed +0 -0
  59. {softschema-0.1.3 → softschema-0.2.0}/packages/python/src/softschema/registry.py +0 -0
  60. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_canonicalize.py +0 -0
  61. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_errors.py +0 -0
  62. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_skill_mirror_drift.py +0 -0
  63. {softschema-0.1.3 → softschema-0.2.0}/packages/python/tests/test_warning_codes.py +0 -0
  64. {softschema-0.1.3 → softschema-0.2.0}/packages/typescript/LICENSE +0 -0
@@ -4,16 +4,16 @@ This repo teaches and implements the soft schema pattern.
4
4
 
5
5
  Start here:
6
6
 
7
- - [Softschema Guide](docs/softschema-guide.md): standalone concept and adoption guide
7
+ - [softschema Guide](docs/softschema-guide.md): standalone concept and adoption guide
8
8
  for humans and agents.
9
- - [Softschema Spec](docs/softschema-spec.md): exact language-neutral artifact format.
9
+ - [softschema Spec](docs/softschema-spec.md): exact language-neutral artifact format.
10
10
  - [Movie page example](examples/movie_page/README.md): complete Python-backed example.
11
11
 
12
12
  softschema ships two interchangeable implementations with the same CLI and library
13
13
  surface: Python/Pydantic (`softschema`, `softschema-py`) and TypeScript/Zod
14
14
  (`softschema`, `softschema-ts`). They are held to exact behavioral parity: same flags,
15
- same canonical JSON Schema sidecar, same validation results, so authoring an artifact is
16
- identical regardless of which you run.
15
+ same canonical compiled JSON Schema, same validation results, so authoring an artifact
16
+ is identical regardless of which you run.
17
17
 
18
18
  For implementer reference (only when changing a package itself):
19
19
 
@@ -63,10 +63,6 @@ Documentation rules:
63
63
  - Include the standard documentation footer in repo docs.
64
64
  Do not add it to authored softschema example artifacts.
65
65
 
66
- <!-- This document follows common-doc-guidelines.md.
67
- See github.com/jlevy/practical-prose and review guidelines before editing.
68
- -->
69
-
70
66
  <!-- BEGIN TBD INTEGRATION format=f04 surface=agents-md -->
71
67
  ## tbd
72
68
 
@@ -0,0 +1,354 @@
1
+ Metadata-Version: 2.4
2
+ Name: softschema
3
+ Version: 0.2.0
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: ruamel-yaml>=0.18
26
+ Requires-Dist: strif>=3.1.0
27
+ Description-Content-Type: text/markdown
28
+
29
+ # softschema
30
+
31
+ Soft schemas: gradual, practical validation for Markdown/YAML artifacts that mix prose
32
+ and structured data — built for humans and coding agents.
33
+
34
+ ## Quick Start
35
+
36
+ Try it anywhere, with nothing installed but [uv](https://docs.astral.sh/uv/) or Node.
37
+ Print the bundled example artifact and its compiled schema, then validate — the artifact
38
+ is fully self-describing, so no flags are needed:
39
+
40
+ ```bash
41
+ uvx softschema@latest docs example-artifact > spirited-away.md
42
+ uvx softschema@latest docs example-schema > movie-page.schema.yaml
43
+ uvx softschema@latest validate spirited-away.md
44
+ ```
45
+
46
+ (Or `npx softschema@latest ...` for the Node implementation; the two are
47
+ interchangeable.)
48
+
49
+ To set up softschema in a repository with an agent, tell the agent:
50
+
51
+ > Run `uvx softschema@latest --help` (for the Python implementation) or
52
+ > `npx softschema@latest --help` (for the Node implementation) and follow the
53
+ > instructions to set up softschema for this repo as a skill.
54
+
55
+ The help output points the agent to `skill --install`, which writes discoverable
56
+ `SKILL.md` mirrors for Codex, Claude Code, Gemini CLI, and other coding agents.
57
+
58
+ ## What Are Soft Schemas?
59
+
60
+ Soft schemas are a practice for adding structure gradually to artifacts that mix
61
+ flexible document context and machine-readable values.
62
+
63
+ The idea is quite simple, but I’ve found it non-obvious enough that coding agents do not
64
+ come up with this approach themselves.
65
+
66
+ However if given the information and tools in this repo, soft schemas are unreasonably
67
+ effective. Agents become far better at designing and building complex workflows that mix
68
+ structured and unstructured data, such as document processing, data extraction,
69
+ scientific or financial analyses, and many similar applications.
70
+
71
+ **Soft schemas** are what we call the general practice.
72
+ **softschema** is the name of this repository’s Markdown-and-YAML spec and the matching
73
+ `softschema` CLI that implements it.
74
+
75
+ ## How Do Soft Schemas Work?
76
+
77
+ The practice is very simple and language neutral.
78
+ The simplest approach is to use artifacts in a process or pipeline that are Markdown
79
+ documents with YAML frontmatter.
80
+ The YAML carries selected structured values.
81
+ The Markdown body stays readable for humans and agents and offers additional context.
82
+ There are no strict rules about duplicating content between Markdown and YAML, but you
83
+ can gradually adjust and enforce rules.
84
+
85
+ A *hard* schema imposes structure up front: define a rigid contract, then reject
86
+ anything that doesn’t fit.
87
+ That suits data that is already uniform, but it is a poor fit for documents a human or
88
+ agent writes, where most of the content is prose and only a few values need to be
89
+ machine-readable.
90
+
91
+ A *soft* schema lets you add structure gradually to the artifacts that pass between
92
+ steps of a workflow.
93
+
94
+ Structure runs along a spectrum, and each value moves along it only when it earns the
95
+ move:
96
+
97
+ ```text
98
+ plain Markdown prose
99
+ -> plain Markdown with a few YAML frontmatter values for specific fields
100
+ -> plain Markdown with more YAML fields and a bit of loose validation
101
+ -> plain Markdown with YAML frontmatter fully validated against JSON Schema (or Pydantic/Zod)
102
+ -> plain Markdown with separate structured data files or database records
103
+ ```
104
+
105
+ The structured values live in the YAML payload, the boundary a tool reads, while the
106
+ prose body stays unconstrained.
107
+ Validation rules can be easily removed or changed if greater flexibility is needed.
108
+
109
+ Promote a value into YAML when a tool reads it, validate it at the boundary when
110
+ correctness matters, and tighten enforcement over time.
111
+ Each promotion buys efficiency for some downstream consumer, so structure and efficiency
112
+ grow together, value by value.
113
+
114
+ Start with processes and data defined in Markdown with data right in the text.
115
+ Have coding agents try them.
116
+ Only add structure when it pays for itself.
117
+
118
+ ## When and Why Are Soft Schemas Useful?
119
+
120
+ You should consider using soft schemas if:
121
+
122
+ 1. You wish to have coding agents perform complex processing workflows involving both
123
+ data and documents
124
+
125
+ 2. Some aspects of the workflow involve structured data that is processed efficiently
126
+ via code and some aspects are ill-defined
127
+
128
+ 3. The boundary between structured and unstructured data might evolve as you scale and
129
+ improve the workflows
130
+
131
+ A plain text document offers flexible context for humans and agents.
132
+ Structured records are far better when code or agents need to read values consistently
133
+ and efficiently.
134
+
135
+ Balancing these needs is often difficult and the source of significant complexity.
136
+
137
+ Some engineers see the goal of productionizing an agent workflow as the process of
138
+ converting it to reusable code or structured forms, like relational database schemas.
139
+
140
+ But the reality is that *prematurely structuring data* before you understand the
141
+ structures that best serve a workflow involving code and agents has a cost.
142
+ At the same time, *poorly defined structure* has costs in consistency and efficiency.
143
+
144
+ What is actually needed is **gradual addition of structure** and **flexible addition of
145
+ textual context** at any time.
146
+
147
+ Soft schemas are simple habits and conventions to make the boundary between structured
148
+ and unstructured data easier to adjust in either direction as a workflow’s needs for
149
+ flexibility, consistency, and efficiency evolve (code vs LLM calls).
150
+ Keeping prose and structured values in one artifact is more convenient and
151
+ context-efficient. A reader (human or agent) has only one place to look, and information
152
+ can stay as loose prose until a downstream consumer needs it in more formal schemas.
153
+
154
+ ## The Artifact Shape
155
+
156
+ The default shape is Markdown with YAML frontmatter.
157
+ The `softschema:` block is the self-description quartet: `contract` names the payload
158
+ contract, `schema` points at the compiled JSON Schema (relative to the document),
159
+ `envelope` names the payload key, and `status` sets validation strictness:
160
+
161
+ ```markdown
162
+ ---
163
+ title: Spirited Away (2001)
164
+ softschema:
165
+ contract: example.movies:MoviePage/v1
166
+ schema: movie-page.schema.yaml
167
+ envelope: movie
168
+ status: enforced
169
+ movie:
170
+ title: Spirited Away
171
+ release_year: 2001
172
+ runtime_minutes: 125
173
+ mpaa_rating: PG
174
+ directors:
175
+ - Hayao Miyazaki
176
+ genres: [Animation, Adventure, Family]
177
+ ratings:
178
+ imdb:
179
+ score: 8.6
180
+ total_votes: 850000
181
+ ---
182
+ # Spirited Away (2001)
183
+
184
+ *Spirited Away* is Hayao Miyazaki's animated fantasy about ten-year-old Chihiro, who
185
+ slips into a spirit world and takes a job in a bathhouse for the gods to free her
186
+ parents from the witch Yubaba.
187
+ It won the 2003 Academy Award for Best Animated Feature.
188
+ ```
189
+
190
+ The YAML payload is authoritative; a consumer reads it.
191
+ The Markdown body overlaps with it but is for human readers: the prose adds context like
192
+ the film’s Academy Award (which no structured field carries), and the full example’s
193
+ body mirrors some YAML fields as tables for the reader’s convenience.
194
+
195
+ Only the `softschema` block and the declared envelope key (`movie:` above) are
196
+ softschema’s concern.
197
+ Additional top-level frontmatter keys, such as the `title:` above (or `description:`,
198
+ `tags:`, or any other host-specific metadata), are a separate concern: softschema
199
+ neither forbids nor interprets them, so an artifact can coexist with whatever
200
+ frontmatter conventions a static-site generator, doc indexer, or other tool already
201
+ expects. Because the artifact declares `envelope: movie`, validation still needs no
202
+ flags.
203
+
204
+ Every key after `contract` is optional; a minimal artifact carries `contract` alone and
205
+ binds its schema some other way (a `--schema` flag, or a host registry in library use).
206
+ Contract IDs follow an enforced shape, `[namespace:]Name[/version]` — for example
207
+ `example.movies:MoviePage/v1` or `com.acme.docs:IncidentReview/1.0` — naming a payload
208
+ contract, not a class or import path.
209
+
210
+ ## Validate
211
+
212
+ A self-describing artifact validates with no flags; flags override the document when you
213
+ need to point a run elsewhere:
214
+
215
+ ```bash
216
+ softschema validate doc.md # uses the document's bindings
217
+ softschema validate doc.md --schema candidate.schema.yaml # try a different schema
218
+ softschema validate doc.md --envelope incident # designate the payload key
219
+ ```
220
+
221
+ `validate` reports structural (JSON Schema) and semantic (Pydantic/Zod model) results
222
+ separately as deterministic JSON. Semantic validation loads a model with
223
+ `--model module:Class` (Python) or `--model path:export` (Zod) — note that `--model`
224
+ imports and executes local code, so use it only with trusted models; a compiled schema
225
+ via `--schema` executes nothing and is the safe path for untrusted input.
226
+
227
+ ## Install
228
+
229
+ Two supported ways to consume softschema; pick by use:
230
+
231
+ - **Pin it as a dependency** for projects, CI gates, and library use (reproducible,
232
+ fast, offline, and the only way to `import` it):
233
+
234
+ ```bash
235
+ uv add --dev softschema==0.2.0 # Python
236
+ npm install -D softschema@0.2.0 # Node (or: bun add -d)
237
+ ```
238
+
239
+ - **Zero-install** for one-off checks and agent bootstrap:
240
+
241
+ ```bash
242
+ uvx softschema@latest --help
243
+ npx softschema@latest --help
244
+ ```
245
+
246
+ The rule of thumb: if softschema runs more than once, or in CI, or you import it — pin
247
+ it. For a quick check or an agent bootstrapping with nothing installed, use a
248
+ zero-install runner.
249
+ See [Installation](docs/installation.md) for details, including the supply-chain
250
+ cool-off that makes `@latest` safe to recommend.
251
+
252
+ ## Use as a Library
253
+
254
+ Both packages expose the same surface (idiomatic per language).
255
+ Register contracts at startup and validate at file boundaries:
256
+
257
+ ```python
258
+ from pathlib import Path
259
+ from softschema import Contract, Contracts, validate_artifact
260
+
261
+ registry = Contracts()
262
+ registry.register(Contract(id="mycorp.docs:IncidentReview/v1", model=IncidentReview,
263
+ envelope_key="incident"))
264
+ result = validate_artifact(Path("incident.md"),
265
+ contract_id="mycorp.docs:IncidentReview/v1",
266
+ registry=registry)
267
+ ```
268
+
269
+ ```ts
270
+ import { validateArtifact } from "softschema";
271
+
272
+ const result = validateArtifact("incident.md", contract);
273
+ ```
274
+
275
+ A host registry’s bindings outrank the document’s own (`softschema.schema`/`envelope`),
276
+ so a document cannot silently redirect a host’s validation; a contract registered
277
+ without a schema path lets self-describing documents bind themselves.
278
+ See the [softschema Guide](docs/softschema-guide.md) for the full playbooks.
279
+
280
+ ## Use as an Agent Skill
281
+
282
+ Both packages ship the same [`SKILL.md`](https://agentskills.io) following the open
283
+ Agent Skills standard discovered by Claude Code, Codex, Gemini CLI, Cursor, Copilot, and
284
+ ~20 other coding agents.
285
+ Pointing an agent at the CLI is enough to bootstrap its understanding of the soft-schema
286
+ approach: the `--help` epilog routes it to `skill --install`, a brief, and the bundled
287
+ docs.
288
+
289
+ ```bash
290
+ # Python:
291
+ uvx softschema@latest --help # entry point with skill setup pointers
292
+ uvx softschema@latest skill --install # install repo-local skill mirrors
293
+ uvx softschema@latest skill --brief # compact operating brief
294
+ uvx softschema@latest docs guide # full mental model and adoption path
295
+
296
+ # TypeScript (same commands, same bundled docs/skill):
297
+ npx softschema@latest --help
298
+ npx softschema@latest skill --install
299
+ npx softschema@latest skill --brief
300
+ npx softschema@latest docs guide
301
+ ```
302
+
303
+ Self-install the skill into a project so any agent working in the repo finds it natively
304
+ (either package writes the identical mirrors):
305
+
306
+ ```bash
307
+ uvx softschema@latest skill --install
308
+ # or: npx softschema@latest skill --install
309
+ # writes:
310
+ # .agents/skills/softschema/SKILL.md (Codex, Gemini CLI, cross-agent installers)
311
+ # .claude/skills/softschema/SKILL.md (Claude Code mirror)
312
+ ```
313
+
314
+ Both mirrors carry a `DO NOT EDIT` marker.
315
+ Re-run `skill --install` to refresh after upgrading the CLI.
316
+
317
+ ## Two Synchronized Implementations
318
+
319
+ softschema ships **two complete, fully supported implementations** with the same CLI and
320
+ library surface:
321
+
322
+ - **Python / Pydantic**: [`softschema`](docs/softschema-python-design.md) on PyPI (run
323
+ as `softschema` or `softschema-py`).
324
+ - **TypeScript / Zod**: [`softschema`](docs/softschema-typescript-design.md) on npm (run
325
+ as `softschema` or `softschema-ts`).
326
+
327
+ The two are held to **exact behavioral parity**: equivalent CLI inputs, outputs, and
328
+ flags; equivalent library APIs; the same canonical compiled JSON Schema
329
+ (content-identical, with an equal `schema_sha256` fingerprint); and the same
330
+ engine-neutral validation results.
331
+ Every behavior change lands in a shared golden-test corpus first, then in both packages,
332
+ and CI fails if their outputs or compiled schemas drift.
333
+ They release together under the same version number on PyPI and npm.
334
+
335
+ ## Further Reading
336
+
337
+ - [softschema Guide](docs/softschema-guide.md): the full mental model and adoption
338
+ playbooks.
339
+ - [softschema Spec](docs/softschema-spec.md): the exact artifact format and validation
340
+ rules.
341
+ - [Movie Page Example](examples/movie_page/README.md): the complete example backing the
342
+ snippets above.
343
+ - [Installation](docs/installation.md): pinned vs zero-install, uv and Node setup.
344
+
345
+ ## Development and Contributing
346
+
347
+ Repo setup, common commands, CI checks, the parity process, and the release workflow
348
+ live in [Development](docs/development.md).
349
+ The Python and TypeScript implementations must be kept in exact sync: any behavior
350
+ change goes through the shared golden corpus first and then lands in both packages.
351
+
352
+ <!-- This document follows common-doc-guidelines.md.
353
+ See github.com/jlevy/practical-prose and review guidelines before editing.
354
+ -->