softschema 0.2.2__tar.gz → 0.3.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.
- {softschema-0.2.2 → softschema-0.3.0}/AGENTS.md +5 -5
- {softschema-0.2.2 → softschema-0.3.0}/PKG-INFO +29 -28
- {softschema-0.2.2 → softschema-0.3.0}/README.md +28 -27
- {softschema-0.2.2 → softschema-0.3.0}/docs/development.md +9 -8
- {softschema-0.2.2 → softschema-0.3.0}/docs/e2e-testing.runbook.md +10 -10
- {softschema-0.2.2 → softschema-0.3.0}/docs/installation.md +27 -25
- {softschema-0.2.2 → softschema-0.3.0}/docs/publishing.md +16 -11
- {softschema-0.2.2 → softschema-0.3.0}/docs/softschema-guide.md +11 -9
- {softschema-0.2.2 → softschema-0.3.0}/docs/softschema-python-design.md +32 -20
- {softschema-0.2.2 → softschema-0.3.0}/docs/softschema-spec.md +49 -24
- {softschema-0.2.2 → softschema-0.3.0}/docs/softschema-typescript-design.md +18 -30
- {softschema-0.2.2 → softschema-0.3.0}/examples/movie_page/movie-page.schema.yaml +26 -3
- {softschema-0.2.2 → softschema-0.3.0}/examples/parity/parity.schema.yaml +30 -3
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/__init__.py +1 -7
- softschema-0.3.0/packages/python/src/softschema/_portable.py +144 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/canonicalize.py +64 -20
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/cli.py +81 -45
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/compile.py +74 -24
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/models.py +5 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/registry.py +2 -1
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/schema_view.py +41 -31
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/soft_field.py +16 -4
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/validate.py +194 -30
- softschema-0.3.0/packages/python/tests/test_canonicalize.py +81 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_cli.py +76 -14
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_core.py +190 -11
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_doc_topics_resolve.py +15 -1
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_enforced_extras.py +31 -1
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_parity.py +25 -5
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_schema_view.py +29 -1
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_skill_mirror_drift.py +6 -5
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_soft_field.py +22 -1
- {softschema-0.2.2 → softschema-0.3.0}/packages/typescript/README.md +6 -6
- {softschema-0.2.2 → softschema-0.3.0}/skills/softschema/SKILL.md +8 -8
- softschema-0.3.0/tests/golden/README.md +67 -0
- softschema-0.3.0/tests/vectors/README.md +28 -0
- softschema-0.2.2/packages/python/tests/test_canonicalize.py +0 -53
- softschema-0.2.2/tests/golden/README.md +0 -124
- {softschema-0.2.2 → softschema-0.3.0}/.gitignore +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/LICENSE +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/docs/publishing-npm.md +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/__init__.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/movie_page/README.md +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/movie_page/__init__.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/movie_page/host_integration.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/movie_page/model.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/movie_page/spirited-away.md +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/parity/__init__.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/examples/parity/model.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/README.md +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/errors.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/generate.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/src/softschema/py.typed +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_errors.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_generate.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_metadata_rules.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_movie_page_example.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/python/tests/test_warning_codes.py +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/packages/typescript/LICENSE +0 -0
- {softschema-0.2.2 → softschema-0.3.0}/pyproject.toml +0 -0
|
@@ -11,9 +11,9 @@ Start here:
|
|
|
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
|
-
(`softschema`, `softschema-ts`). They
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
(`softschema`, `softschema-ts`). They share commands, exit classes, structured result
|
|
15
|
+
meaning, and canonical compiled JSON Schema, so authoring an artifact is identical
|
|
16
|
+
regardless of which you run.
|
|
17
17
|
|
|
18
18
|
For implementer reference (only when changing a package itself):
|
|
19
19
|
|
|
@@ -63,12 +63,12 @@ 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
|
-
<!-- BEGIN TBD INTEGRATION format=
|
|
66
|
+
<!-- BEGIN TBD INTEGRATION format=f06 surface=agents-md -->
|
|
67
67
|
## tbd
|
|
68
68
|
|
|
69
69
|
This repository uses **tbd** for git-native issue tracking (beads), spec-driven
|
|
70
70
|
planning, and on-demand engineering guidelines.
|
|
71
|
-
As the agent, you operate tbd on the user’s behalf
|
|
71
|
+
As the agent, you operate tbd on the user’s behalf: translate their requests into tbd
|
|
72
72
|
actions rather than telling them to run commands.
|
|
73
73
|
|
|
74
74
|
- Run `tbd prime` to load current project state and the full tbd workflow.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: softschema
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Soft schema conventions and validation tools for Markdown/YAML artifacts
|
|
5
5
|
Project-URL: Homepage, https://github.com/jlevy/softschema
|
|
6
6
|
Project-URL: Repository, https://github.com/jlevy/softschema
|
|
@@ -43,17 +43,17 @@ uvx softschema@latest docs example-schema > movie-page.schema.yaml
|
|
|
43
43
|
uvx softschema@latest validate spirited-away.md
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
(Or `npx softschema@latest ...` for the Node implementation; the two are
|
|
46
|
+
(Or `npx -y softschema@latest ...` for the Node implementation; the two are
|
|
47
47
|
interchangeable.)
|
|
48
48
|
|
|
49
49
|
To set up softschema in a repository with an agent, tell the agent:
|
|
50
50
|
|
|
51
51
|
> Run `uvx softschema@latest --help` (for the Python implementation) or
|
|
52
|
-
> `npx softschema@latest --help` (for the Node implementation) and follow the
|
|
52
|
+
> `npx -y softschema@latest --help` (for the Node implementation) and follow the
|
|
53
53
|
> instructions to set up softschema for this repo as a skill.
|
|
54
54
|
|
|
55
|
-
The help output points the agent to
|
|
56
|
-
|
|
55
|
+
The help output points the agent to the explicit install command, which writes the
|
|
56
|
+
portable Agent Skills location and the Claude Code discovery mirror.
|
|
57
57
|
|
|
58
58
|
## What Are Soft Schemas?
|
|
59
59
|
|
|
@@ -228,25 +228,27 @@ via `--schema` executes nothing and is the safe path for untrusted input.
|
|
|
228
228
|
|
|
229
229
|
Two supported ways to consume softschema; pick by use:
|
|
230
230
|
|
|
231
|
-
- **
|
|
232
|
-
fast, offline, and the only way to `import` it):
|
|
231
|
+
- **Install it as a dependency** for projects, CI gates, and library use (reproducible
|
|
232
|
+
through the project lockfile, fast, offline, and the only way to `import` it):
|
|
233
233
|
|
|
234
234
|
```bash
|
|
235
|
-
uv add --dev softschema
|
|
236
|
-
npm install -D softschema@
|
|
235
|
+
uv add --dev softschema # Python
|
|
236
|
+
npm install -D softschema@latest # Node (or: bun add -d)
|
|
237
237
|
```
|
|
238
238
|
|
|
239
239
|
- **Zero-install** for one-off checks and agent bootstrap:
|
|
240
240
|
|
|
241
241
|
```bash
|
|
242
242
|
uvx softschema@latest --help
|
|
243
|
-
npx softschema@latest --help
|
|
243
|
+
npx -y softschema@latest --help
|
|
244
244
|
```
|
|
245
245
|
|
|
246
|
-
The rule of thumb: if softschema runs more than once, or in CI, or you import it—
|
|
246
|
+
The rule of thumb: if softschema runs more than once, or in CI, or you import it—install
|
|
247
|
+
it in the project and commit the lockfile.
|
|
247
248
|
For a quick check or an agent bootstrapping with nothing installed, use a zero-install
|
|
248
|
-
runner.
|
|
249
|
-
|
|
249
|
+
runner.
|
|
250
|
+
See [Installation](docs/installation.md) for details and the project supply-chain
|
|
251
|
+
policy.
|
|
250
252
|
|
|
251
253
|
## Use as a Library
|
|
252
254
|
|
|
@@ -279,8 +281,9 @@ See the [softschema Guide](docs/softschema-guide.md) for the full playbooks.
|
|
|
279
281
|
## Use as an Agent Skill
|
|
280
282
|
|
|
281
283
|
Both packages ship the same [`SKILL.md`](https://agentskills.io) following the open
|
|
282
|
-
Agent Skills standard
|
|
283
|
-
|
|
284
|
+
Agent Skills standard.
|
|
285
|
+
The portable mirror works with agents that discover `.agents`; the optional Claude
|
|
286
|
+
mirror supports Claude Code’s discovery path.
|
|
284
287
|
Pointing an agent at the CLI is enough to bootstrap its understanding of the soft-schema
|
|
285
288
|
approach: the `--help` epilog routes it to `skill --install`, a brief, and the bundled
|
|
286
289
|
docs.
|
|
@@ -288,23 +291,23 @@ docs.
|
|
|
288
291
|
```bash
|
|
289
292
|
# Python:
|
|
290
293
|
uvx softschema@latest --help # entry point with skill setup pointers
|
|
291
|
-
uvx softschema@latest skill --install
|
|
294
|
+
uvx softschema@latest skill --install --scope project --agent portable --agent claude
|
|
292
295
|
uvx softschema@latest skill --brief # compact operating brief
|
|
293
296
|
uvx softschema@latest docs guide # full mental model and adoption path
|
|
294
297
|
|
|
295
298
|
# TypeScript (same commands, same bundled docs/skill):
|
|
296
|
-
npx softschema@latest --help
|
|
297
|
-
npx softschema@latest skill --install
|
|
298
|
-
npx softschema@latest skill --brief
|
|
299
|
-
npx softschema@latest docs guide
|
|
299
|
+
npx -y softschema@latest --help
|
|
300
|
+
npx -y softschema@latest skill --install --scope project --agent portable --agent claude
|
|
301
|
+
npx -y softschema@latest skill --brief
|
|
302
|
+
npx -y softschema@latest docs guide
|
|
300
303
|
```
|
|
301
304
|
|
|
302
305
|
Self-install the skill into a project so any agent working in the repo finds it natively
|
|
303
306
|
(either package writes the identical mirrors):
|
|
304
307
|
|
|
305
308
|
```bash
|
|
306
|
-
uvx softschema@latest skill --install
|
|
307
|
-
# or: npx softschema@latest skill --install
|
|
309
|
+
uvx softschema@latest skill --install --scope project --agent portable --agent claude
|
|
310
|
+
# or: npx -y softschema@latest skill --install --scope project --agent portable --agent claude
|
|
308
311
|
# writes:
|
|
309
312
|
# .agents/skills/softschema/SKILL.md (Codex, Gemini CLI, cross-agent installers)
|
|
310
313
|
# .claude/skills/softschema/SKILL.md (Claude Code mirror)
|
|
@@ -323,12 +326,10 @@ library surface:
|
|
|
323
326
|
- **TypeScript / Zod**: [`softschema`](docs/softschema-typescript-design.md) on npm (run
|
|
324
327
|
as `softschema` or `softschema-ts`).
|
|
325
328
|
|
|
326
|
-
The two
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
Every behavior change lands in a shared golden-test corpus first, then in both packages,
|
|
331
|
-
and CI fails if their outputs or compiled schemas drift.
|
|
329
|
+
The two share the same commands, exit classes, structured result meaning, canonical
|
|
330
|
+
compiled JSON Schema, and `schema_sha256` fingerprint.
|
|
331
|
+
Human-readable presentation and model-native errors may differ where the runtime does;
|
|
332
|
+
shared vectors and broad CLI journeys keep the portable contract aligned.
|
|
332
333
|
They release together under the same version number on PyPI and npm.
|
|
333
334
|
|
|
334
335
|
## Further Reading
|
|
@@ -15,17 +15,17 @@ uvx softschema@latest docs example-schema > movie-page.schema.yaml
|
|
|
15
15
|
uvx softschema@latest validate spirited-away.md
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
(Or `npx softschema@latest ...` for the Node implementation; the two are
|
|
18
|
+
(Or `npx -y softschema@latest ...` for the Node implementation; the two are
|
|
19
19
|
interchangeable.)
|
|
20
20
|
|
|
21
21
|
To set up softschema in a repository with an agent, tell the agent:
|
|
22
22
|
|
|
23
23
|
> Run `uvx softschema@latest --help` (for the Python implementation) or
|
|
24
|
-
> `npx softschema@latest --help` (for the Node implementation) and follow the
|
|
24
|
+
> `npx -y softschema@latest --help` (for the Node implementation) and follow the
|
|
25
25
|
> instructions to set up softschema for this repo as a skill.
|
|
26
26
|
|
|
27
|
-
The help output points the agent to
|
|
28
|
-
|
|
27
|
+
The help output points the agent to the explicit install command, which writes the
|
|
28
|
+
portable Agent Skills location and the Claude Code discovery mirror.
|
|
29
29
|
|
|
30
30
|
## What Are Soft Schemas?
|
|
31
31
|
|
|
@@ -200,25 +200,27 @@ via `--schema` executes nothing and is the safe path for untrusted input.
|
|
|
200
200
|
|
|
201
201
|
Two supported ways to consume softschema; pick by use:
|
|
202
202
|
|
|
203
|
-
- **
|
|
204
|
-
fast, offline, and the only way to `import` it):
|
|
203
|
+
- **Install it as a dependency** for projects, CI gates, and library use (reproducible
|
|
204
|
+
through the project lockfile, fast, offline, and the only way to `import` it):
|
|
205
205
|
|
|
206
206
|
```bash
|
|
207
|
-
uv add --dev softschema
|
|
208
|
-
npm install -D softschema@
|
|
207
|
+
uv add --dev softschema # Python
|
|
208
|
+
npm install -D softschema@latest # Node (or: bun add -d)
|
|
209
209
|
```
|
|
210
210
|
|
|
211
211
|
- **Zero-install** for one-off checks and agent bootstrap:
|
|
212
212
|
|
|
213
213
|
```bash
|
|
214
214
|
uvx softschema@latest --help
|
|
215
|
-
npx softschema@latest --help
|
|
215
|
+
npx -y softschema@latest --help
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
-
The rule of thumb: if softschema runs more than once, or in CI, or you import it—
|
|
218
|
+
The rule of thumb: if softschema runs more than once, or in CI, or you import it—install
|
|
219
|
+
it in the project and commit the lockfile.
|
|
219
220
|
For a quick check or an agent bootstrapping with nothing installed, use a zero-install
|
|
220
|
-
runner.
|
|
221
|
-
|
|
221
|
+
runner.
|
|
222
|
+
See [Installation](docs/installation.md) for details and the project supply-chain
|
|
223
|
+
policy.
|
|
222
224
|
|
|
223
225
|
## Use as a Library
|
|
224
226
|
|
|
@@ -251,8 +253,9 @@ See the [softschema Guide](docs/softschema-guide.md) for the full playbooks.
|
|
|
251
253
|
## Use as an Agent Skill
|
|
252
254
|
|
|
253
255
|
Both packages ship the same [`SKILL.md`](https://agentskills.io) following the open
|
|
254
|
-
Agent Skills standard
|
|
255
|
-
|
|
256
|
+
Agent Skills standard.
|
|
257
|
+
The portable mirror works with agents that discover `.agents`; the optional Claude
|
|
258
|
+
mirror supports Claude Code’s discovery path.
|
|
256
259
|
Pointing an agent at the CLI is enough to bootstrap its understanding of the soft-schema
|
|
257
260
|
approach: the `--help` epilog routes it to `skill --install`, a brief, and the bundled
|
|
258
261
|
docs.
|
|
@@ -260,23 +263,23 @@ docs.
|
|
|
260
263
|
```bash
|
|
261
264
|
# Python:
|
|
262
265
|
uvx softschema@latest --help # entry point with skill setup pointers
|
|
263
|
-
uvx softschema@latest skill --install
|
|
266
|
+
uvx softschema@latest skill --install --scope project --agent portable --agent claude
|
|
264
267
|
uvx softschema@latest skill --brief # compact operating brief
|
|
265
268
|
uvx softschema@latest docs guide # full mental model and adoption path
|
|
266
269
|
|
|
267
270
|
# TypeScript (same commands, same bundled docs/skill):
|
|
268
|
-
npx softschema@latest --help
|
|
269
|
-
npx softschema@latest skill --install
|
|
270
|
-
npx softschema@latest skill --brief
|
|
271
|
-
npx softschema@latest docs guide
|
|
271
|
+
npx -y softschema@latest --help
|
|
272
|
+
npx -y softschema@latest skill --install --scope project --agent portable --agent claude
|
|
273
|
+
npx -y softschema@latest skill --brief
|
|
274
|
+
npx -y softschema@latest docs guide
|
|
272
275
|
```
|
|
273
276
|
|
|
274
277
|
Self-install the skill into a project so any agent working in the repo finds it natively
|
|
275
278
|
(either package writes the identical mirrors):
|
|
276
279
|
|
|
277
280
|
```bash
|
|
278
|
-
uvx softschema@latest skill --install
|
|
279
|
-
# or: npx softschema@latest skill --install
|
|
281
|
+
uvx softschema@latest skill --install --scope project --agent portable --agent claude
|
|
282
|
+
# or: npx -y softschema@latest skill --install --scope project --agent portable --agent claude
|
|
280
283
|
# writes:
|
|
281
284
|
# .agents/skills/softschema/SKILL.md (Codex, Gemini CLI, cross-agent installers)
|
|
282
285
|
# .claude/skills/softschema/SKILL.md (Claude Code mirror)
|
|
@@ -295,12 +298,10 @@ library surface:
|
|
|
295
298
|
- **TypeScript / Zod**: [`softschema`](docs/softschema-typescript-design.md) on npm (run
|
|
296
299
|
as `softschema` or `softschema-ts`).
|
|
297
300
|
|
|
298
|
-
The two
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
Every behavior change lands in a shared golden-test corpus first, then in both packages,
|
|
303
|
-
and CI fails if their outputs or compiled schemas drift.
|
|
301
|
+
The two share the same commands, exit classes, structured result meaning, canonical
|
|
302
|
+
compiled JSON Schema, and `schema_sha256` fingerprint.
|
|
303
|
+
Human-readable presentation and model-native errors may differ where the runtime does;
|
|
304
|
+
shared vectors and broad CLI journeys keep the portable contract aligned.
|
|
304
305
|
They release together under the same version number on PyPI and npm.
|
|
305
306
|
|
|
306
307
|
## Further Reading
|
|
@@ -174,16 +174,17 @@ your repository.
|
|
|
174
174
|
## Keeping Python and TypeScript in Parity
|
|
175
175
|
|
|
176
176
|
softschema ships two implementations, Python/Pydantic (`softschema`) and TypeScript/Zod
|
|
177
|
-
(`softschema`, `softschema-ts`),
|
|
178
|
-
|
|
179
|
-
(
|
|
180
|
-
|
|
177
|
+
(`softschema`, `softschema-ts`), with the same commands, exit classes, structured result
|
|
178
|
+
meaning, canonical compiled JSON Schema, and `schema_sha256`. Only idiomatic surface
|
|
179
|
+
details differ (snake_case ↔ camelCase, Pydantic ↔ Zod), and cross-runtime JSON output
|
|
180
|
+
is compared structurally rather than as presentation bytes.
|
|
181
181
|
|
|
182
182
|
When you change any behavior, follow this loop so the two never drift:
|
|
183
183
|
|
|
184
|
-
1. **
|
|
185
|
-
|
|
186
|
-
|
|
184
|
+
1. **Choose one primary owner first.** Use a shared YAML vector for a portable library
|
|
185
|
+
rule, an adapter unit test for runtime-specific integration, or a golden journey for
|
|
186
|
+
public CLI output and exit behavior.
|
|
187
|
+
Do not add the same case at every layer.
|
|
187
188
|
2. **Implement in Python**, then `uv run pytest` and
|
|
188
189
|
`SOFTSCHEMA_IMPL=py bash tests/golden/run.sh`.
|
|
189
190
|
3. **Port to TypeScript**, then `bun test` (in `packages/typescript`) and
|
|
@@ -198,7 +199,7 @@ The parity invariants, and where each is enforced:
|
|
|
198
199
|
| --- | --- |
|
|
199
200
|
| Canonical schema (equal `schema_sha256`) | `compile` and the KitchenSink conformance test (`packages/typescript/test/conformance.test.ts`) and `examples/parity/` |
|
|
200
201
|
| Engine-neutral structural errors | shared message templates (`errors`), the golden corpus |
|
|
201
|
-
|
|
|
202
|
+
| Structurally equal JSON and exact stable human output | the shared golden corpus (run twice via `SOFTSCHEMA_IMPL`) |
|
|
202
203
|
| Equal flag/command surface | per-impl and neutral golden scenarios |
|
|
203
204
|
| Bundled docs/skill resolve from the package | the standalone test (`packages/typescript/test/standalone.test.ts`) |
|
|
204
205
|
| Skill mirrors never go stale | the mirror drift test (`tests/test_skill_mirror_drift.py`) |
|
|
@@ -35,7 +35,7 @@ The automated half of the story runs on every push and PR
|
|
|
35
35
|
| TS typecheck, biome, unit tests + coverage gate | `typescript` job |
|
|
36
36
|
| TS build + publint (publishable layout) | `typescript` job |
|
|
37
37
|
| Golden corpus on py, ts (Node), ts-bun | `golden` + `typescript` jobs |
|
|
38
|
-
| Python-vs-TypeScript
|
|
38
|
+
| Python-vs-TypeScript semantic parity | `cross-impl` job |
|
|
39
39
|
| Tag ↔ `package.json` version match | `publish.yml` guard |
|
|
40
40
|
|
|
41
41
|
**Not** covered by CI—the reason this runbook exists:
|
|
@@ -55,16 +55,16 @@ Mirror CI from the repo root, in this order (later phases depend on the builds):
|
|
|
55
55
|
```bash
|
|
56
56
|
make install # uv sync + npm install (lefthook) + bun install
|
|
57
57
|
make lint-check # codespell, ruff, basedpyright, doc footers
|
|
58
|
-
uv run pytest # Python unit tests
|
|
58
|
+
uv run pytest # Python unit tests
|
|
59
59
|
uv build # wheel + sdist into dist/ (used by Phase 2)
|
|
60
60
|
|
|
61
61
|
cd packages/typescript
|
|
62
|
-
bun run check # biome + tsc + bun test with coverage gate
|
|
62
|
+
bun run check # biome + tsc + bun test with coverage gate
|
|
63
63
|
bun run build # copy-resources + bunup → dist/ (required by the ts golden runs)
|
|
64
64
|
bun run publint
|
|
65
65
|
cd ../..
|
|
66
66
|
|
|
67
|
-
SOFTSCHEMA_IMPL=py bash tests/golden/run.sh
|
|
67
|
+
SOFTSCHEMA_IMPL=py bash tests/golden/run.sh
|
|
68
68
|
SOFTSCHEMA_IMPL=ts bash tests/golden/run.sh # 44
|
|
69
69
|
SOFTSCHEMA_IMPL=ts-bun bash tests/golden/run.sh # 46
|
|
70
70
|
bash tests/golden/cross-impl-diff.sh # "cross-impl parity OK"
|
|
@@ -128,9 +128,9 @@ If a local supply-chain cool-off blocks the `npm install` of dependencies, add
|
|
|
128
128
|
## Phase 3: The Quickstart, As Written
|
|
129
129
|
|
|
130
130
|
The README Quick Start is the contract with a first-time user; run it verbatim from an
|
|
131
|
-
**empty directory
|
|
132
|
-
Before a release, substitute the local builds for
|
|
133
|
-
|
|
131
|
+
**empty directory** on both implementations.
|
|
132
|
+
Before a release, substitute the local builds for the zero-install `@latest` commands
|
|
133
|
+
shown in the README (the published forms are verified in Phase 5):
|
|
134
134
|
|
|
135
135
|
```bash
|
|
136
136
|
repo=$(pwd) # the softschema checkout
|
|
@@ -166,7 +166,7 @@ from Phase 2 or 3:
|
|
|
166
166
|
|
|
167
167
|
```bash
|
|
168
168
|
cd "$(mktemp -d)" && git init -q .
|
|
169
|
-
softschema skill --install
|
|
169
|
+
softschema skill --install --scope project --agent portable --agent claude
|
|
170
170
|
ls .agents/skills/softschema/SKILL.md .claude/skills/softschema/SKILL.md
|
|
171
171
|
```
|
|
172
172
|
|
|
@@ -212,8 +212,8 @@ uvx softschema@X.Y.Z docs example-schema > movie-page.schema.yaml
|
|
|
212
212
|
uvx softschema@X.Y.Z validate spirited-away.md
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
The README, bundled skill, CLI help, and installation guide use `@latest`, so published
|
|
216
|
+
release verification requires no follow-up documentation pin change.
|
|
217
217
|
|
|
218
218
|
## Recording Results
|
|
219
219
|
|
|
@@ -6,55 +6,61 @@ Pick the runtime you already have; both validate against the same canonical sche
|
|
|
6
6
|
|
|
7
7
|
## Two Ways to Consume It
|
|
8
8
|
|
|
9
|
-
| |
|
|
9
|
+
| | Install as a dependency | Zero-install (`uvx` / `npx`) |
|
|
10
10
|
| --- | --- | --- |
|
|
11
11
|
| **For** | Projects, CI gates, library use | One-off checks, agent bootstrap |
|
|
12
|
-
| **Reproducible** | Yes—the version is locked in `uv.lock` / `package-lock.json` |
|
|
12
|
+
| **Reproducible** | Yes—the version is locked in `uv.lock` / `package-lock.json` | No—`@latest` resolves at invocation time |
|
|
13
13
|
| **Fast / offline** | Yes—the binary is already on disk | Cold-start fetch; needs the network |
|
|
14
14
|
| **Library import** | Yes—the only way | No |
|
|
15
15
|
|
|
16
|
-
The rule of thumb: **if softschema runs more than once, or in CI, or you import it—
|
|
17
|
-
it as a dependency.
|
|
18
|
-
For a quick one-off or an agent bootstrapping with nothing installed,
|
|
19
|
-
|
|
16
|
+
The rule of thumb: **if softschema runs more than once, or in CI, or you import it—add
|
|
17
|
+
it as a project dependency and commit the lockfile.
|
|
18
|
+
For a quick one-off or an agent bootstrapping with nothing installed, use a zero-install
|
|
19
|
+
runner**.
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Install as a Dependency
|
|
22
22
|
|
|
23
23
|
Python (a dev dependency, or a persistent user tool):
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
uv add --dev softschema
|
|
26
|
+
uv add --dev softschema # project dev dependency; run via `uv run softschema`
|
|
27
27
|
uv tool install softschema # persistent CLI on your PATH
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Node (>= 22.12):
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npm install -D softschema@
|
|
33
|
+
npm install -D softschema@latest # or: pnpm add -D / bun add -d
|
|
34
34
|
npx softschema --help # resolves the local pinned copy
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## Zero-Install
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
uvx softschema@latest --help
|
|
41
|
-
npx softschema@latest --help
|
|
40
|
+
uvx softschema@latest --help # Python implementation, ephemeral
|
|
41
|
+
npx -y softschema@latest --help # Node implementation, ephemeral
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
These commands resolve the latest published release.
|
|
45
|
+
Use the project-dependency path above when a workflow must be repeatable.
|
|
46
46
|
|
|
47
47
|
## Quick Start for Agents
|
|
48
48
|
|
|
49
49
|
To set up softschema in a repository with an agent, tell the agent:
|
|
50
50
|
|
|
51
51
|
> Run `uvx softschema@latest --help` (for the Python implementation) or
|
|
52
|
-
> `npx softschema@latest --help` (for the Node implementation) and follow the
|
|
52
|
+
> `npx -y softschema@latest --help` (for the Node implementation) and follow the
|
|
53
53
|
> instructions to set up softschema for this repo as a skill.
|
|
54
54
|
|
|
55
|
-
The help output points the
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
The help output points to the explicit project install:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
softschema skill --install --scope project --agent portable --agent claude
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This writes `.agents/skills/softschema/SKILL.md` and
|
|
62
|
+
`.claude/skills/softschema/SKILL.md` from the repository root.
|
|
63
|
+
Use one `--agent` when only one mirror is wanted; use `--dry-run` to preview.
|
|
58
64
|
|
|
59
65
|
## Installing uv
|
|
60
66
|
|
|
@@ -73,14 +79,10 @@ brew install uv
|
|
|
73
79
|
|
|
74
80
|
## Supply-chain Cool-off
|
|
75
81
|
|
|
76
|
-
`@latest`
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
you get the freshest vetted version without pinning.
|
|
81
|
-
A just-published version installs only once it ages past the cutoff.
|
|
82
|
-
Consumer projects should still pin their own dependency—a project’s reproducibility is
|
|
83
|
-
the project’s responsibility, not the publisher’s cool-off.
|
|
82
|
+
Zero-install commands use `@latest` for low-friction one-off checks and agent bootstrap.
|
|
83
|
+
They are intentionally not reproducible.
|
|
84
|
+
Projects and CI should install softschema as a dependency, commit the normal lockfile,
|
|
85
|
+
and apply a release-age cool-off when updating it.
|
|
84
86
|
See [supply-chain-hardening](https://github.com/jlevy/supply-chain-hardening) for the
|
|
85
87
|
rationale.
|
|
86
88
|
|
|
@@ -19,15 +19,12 @@ No API tokens are stored in the repo.
|
|
|
19
19
|
to `X.Y.Z` in the same commit that prepares the release, so the npm version matches
|
|
20
20
|
the Git tag the Python build derives.
|
|
21
21
|
CI verifies this match before publishing and fails the release on a mismatch.
|
|
22
|
-
- **
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
that has already cleared the cool-off window rather than a just-published one.
|
|
29
|
-
- The committed skill mirrors under `.agents/` and `.claude/` are regenerated by
|
|
30
|
-
`softschema skill --install`; a drift test keeps them in sync with the source.
|
|
22
|
+
- **Zero-install examples use `@latest`.** This keeps the README, installation guide,
|
|
23
|
+
shipped skill, and CLI help stable across releases.
|
|
24
|
+
Repeatable project and CI use belongs in a lockfile-backed dependency instead.
|
|
25
|
+
- The committed skill mirrors under `.agents/` and `.claude/` are regenerated with the
|
|
26
|
+
explicit project-scope install command; a drift test keeps them in sync with the
|
|
27
|
+
source.
|
|
31
28
|
- Patch bumps (`0.1.Z`) cover docs-only changes and small additive features.
|
|
32
29
|
Reserve minor bumps (`0.Y.0`) for changes that meaningfully shift the API or spec.
|
|
33
30
|
|
|
@@ -79,8 +76,7 @@ For each release of version `X.Y.Z`:
|
|
|
79
76
|
2. **Set both package versions to `X.Y.Z`.** Edit `packages/typescript/package.json`
|
|
80
77
|
`"version"` to `X.Y.Z` (the Python version is derived from the tag, so it needs no
|
|
81
78
|
file edit). The two must match or the npm publish step aborts.
|
|
82
|
-
|
|
83
|
-
commit.
|
|
79
|
+
Public zero-install examples remain on `@latest` and require no release edit.
|
|
84
80
|
|
|
85
81
|
3. **Run the full validation pass** from the
|
|
86
82
|
[end-to-end testing runbook](e2e-testing.runbook.md): the local automated sweep
|
|
@@ -148,6 +144,15 @@ For each release of version `X.Y.Z`:
|
|
|
148
144
|
and pass `--refresh` so uv does not serve a cached index that predates the publish
|
|
149
145
|
(see runbook Phase 5).
|
|
150
146
|
|
|
147
|
+
Allow for publish propagation: PyPI updates its JSON API
|
|
148
|
+
(`pypi.org/pypi/softschema/json`) before the **simple index** uv resolves against
|
|
149
|
+
(`pypi.org/simple/softschema/`), so the first `uvx` run right after the workflow
|
|
150
|
+
turns green can fail with `no version of softschema==X.Y.Z` even though the release
|
|
151
|
+
is live. `--refresh` clears uv’s own cache but not PyPI’s CDN edge, so if that
|
|
152
|
+
happens, wait for the simple index to list the new `.whl`/`.tar.gz` and retry
|
|
153
|
+
(usually a few seconds).
|
|
154
|
+
npm propagates quickly and rarely shows this gap.
|
|
155
|
+
|
|
151
156
|
<!-- This document follows common-doc-guidelines.md.
|
|
152
157
|
See github.com/jlevy/practical-prose and review guidelines before editing.
|
|
153
158
|
-->
|
|
@@ -7,7 +7,7 @@ pattern.
|
|
|
7
7
|
|
|
8
8
|
For the exact file format and validation rules, see
|
|
9
9
|
[softschema Spec](softschema-spec.md).
|
|
10
|
-
Two interchangeable implementations
|
|
10
|
+
Two interchangeable implementations share one portable contract: see
|
|
11
11
|
[Python Package Design](softschema-python-design.md) and
|
|
12
12
|
[TypeScript Package Design](softschema-typescript-design.md).
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ Two interchangeable implementations ship here, at exact behavioral parity: see
|
|
|
16
16
|
To set up softschema in a repository with an agent, tell the agent:
|
|
17
17
|
|
|
18
18
|
> Run `uvx softschema@latest --help` (for the Python implementation) or
|
|
19
|
-
> `npx softschema@latest --help` (for the Node implementation) and follow the
|
|
19
|
+
> `npx -y softschema@latest --help` (for the Node implementation) and follow the
|
|
20
20
|
> instructions to set up softschema for this repo as a skill.
|
|
21
21
|
|
|
22
22
|
The help output points the agent to the repo-local skill install command and the bundled
|
|
@@ -484,10 +484,10 @@ Pin softschema as a dev dependency so CI uses a known version:
|
|
|
484
484
|
|
|
485
485
|
```bash
|
|
486
486
|
# Python
|
|
487
|
-
uv add --dev softschema
|
|
487
|
+
uv add --dev softschema
|
|
488
488
|
|
|
489
489
|
# Node
|
|
490
|
-
npm i -D softschema@
|
|
490
|
+
npm i -D softschema@latest
|
|
491
491
|
```
|
|
492
492
|
|
|
493
493
|
Two checks belong in CI:
|
|
@@ -525,7 +525,7 @@ integration” section of [docs/development.md](development.md).
|
|
|
525
525
|
|
|
526
526
|
Take an artifact that doesn’t fit the canonical shape and bring it in line.
|
|
527
527
|
|
|
528
|
-
The canonical
|
|
528
|
+
The canonical shape is:
|
|
529
529
|
|
|
530
530
|
- A `softschema:` block (the self-description quartet: `contract`, `schema`, `envelope`,
|
|
531
531
|
`status`) plus a designated envelope key at the top level.
|
|
@@ -688,8 +688,8 @@ A few patterns help agents do the right thing:
|
|
|
688
688
|
|
|
689
689
|
## Relationship to the Packages
|
|
690
690
|
|
|
691
|
-
Two interchangeable packages implement the language-neutral
|
|
692
|
-
|
|
691
|
+
Two interchangeable packages implement the same language-neutral contract with
|
|
692
|
+
Python/Pydantic and TypeScript/Zod.
|
|
693
693
|
The Python public surface:
|
|
694
694
|
|
|
695
695
|
- `Contract`: maps a contract ID to a Pydantic model and optional compiled JSON Schema.
|
|
@@ -700,8 +700,10 @@ The Python public surface:
|
|
|
700
700
|
- `validate_values(values, model=..., schema=...)`: validates a values dict produced by
|
|
701
701
|
any consumer (frontmatter, body-form runtime, structured-output adapter, hand-written
|
|
702
702
|
fixture).
|
|
703
|
-
- `compile_model(model_cls, out_path)`: emits a
|
|
704
|
-
|
|
703
|
+
- `compile_model(model_cls, out_path, contract_id=..., schema_id=...)`: emits a
|
|
704
|
+
deterministic JSON Schema YAML file.
|
|
705
|
+
The required contract ID names the payload; the optional schema ID is a separate JSON
|
|
706
|
+
Schema resource URI.
|
|
705
707
|
|
|
706
708
|
The TypeScript package mirrors this surface (`validateArtifact`, `validateValues`,
|
|
707
709
|
`compileSchema`) with Zod models; both CLIs expose the same commands.
|