softschema 0.2.1__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.
Files changed (62) hide show
  1. {softschema-0.2.1 → softschema-0.3.0}/AGENTS.md +5 -5
  2. {softschema-0.2.1 → softschema-0.3.0}/PKG-INFO +29 -28
  3. {softschema-0.2.1 → softschema-0.3.0}/README.md +28 -27
  4. {softschema-0.2.1 → softschema-0.3.0}/docs/development.md +9 -8
  5. {softschema-0.2.1 → softschema-0.3.0}/docs/e2e-testing.runbook.md +10 -10
  6. {softschema-0.2.1 → softschema-0.3.0}/docs/installation.md +27 -25
  7. {softschema-0.2.1 → softschema-0.3.0}/docs/publishing.md +16 -11
  8. {softschema-0.2.1 → softschema-0.3.0}/docs/softschema-guide.md +11 -9
  9. {softschema-0.2.1 → softschema-0.3.0}/docs/softschema-python-design.md +32 -20
  10. {softschema-0.2.1 → softschema-0.3.0}/docs/softschema-spec.md +50 -13
  11. {softschema-0.2.1 → softschema-0.3.0}/docs/softschema-typescript-design.md +18 -30
  12. {softschema-0.2.1 → softschema-0.3.0}/examples/movie_page/movie-page.schema.yaml +26 -3
  13. {softschema-0.2.1 → softschema-0.3.0}/examples/parity/parity.schema.yaml +30 -3
  14. softschema-0.3.0/packages/python/README.md +48 -0
  15. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/__init__.py +1 -7
  16. softschema-0.3.0/packages/python/src/softschema/_portable.py +144 -0
  17. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/canonicalize.py +64 -20
  18. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/cli.py +132 -64
  19. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/compile.py +74 -24
  20. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/errors.py +51 -1
  21. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/models.py +6 -1
  22. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/registry.py +2 -1
  23. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/schema_view.py +41 -31
  24. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/soft_field.py +16 -4
  25. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/validate.py +195 -31
  26. softschema-0.3.0/packages/python/tests/test_canonicalize.py +81 -0
  27. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_cli.py +115 -14
  28. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_core.py +190 -11
  29. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_doc_topics_resolve.py +15 -1
  30. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_enforced_extras.py +31 -1
  31. softschema-0.3.0/packages/python/tests/test_errors.py +88 -0
  32. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_parity.py +25 -5
  33. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_schema_view.py +29 -1
  34. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_skill_mirror_drift.py +6 -5
  35. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_soft_field.py +22 -1
  36. {softschema-0.2.1 → softschema-0.3.0}/packages/typescript/README.md +6 -6
  37. {softschema-0.2.1 → softschema-0.3.0}/pyproject.toml +9 -6
  38. {softschema-0.2.1 → softschema-0.3.0}/skills/softschema/SKILL.md +8 -8
  39. softschema-0.3.0/tests/golden/README.md +67 -0
  40. softschema-0.3.0/tests/vectors/README.md +28 -0
  41. softschema-0.2.1/packages/python/README.md +0 -31
  42. softschema-0.2.1/packages/python/tests/test_canonicalize.py +0 -53
  43. softschema-0.2.1/packages/python/tests/test_errors.py +0 -51
  44. softschema-0.2.1/tests/golden/README.md +0 -118
  45. {softschema-0.2.1 → softschema-0.3.0}/.gitignore +0 -0
  46. {softschema-0.2.1 → softschema-0.3.0}/LICENSE +0 -0
  47. {softschema-0.2.1 → softschema-0.3.0}/docs/publishing-npm.md +0 -0
  48. {softschema-0.2.1 → softschema-0.3.0}/examples/__init__.py +0 -0
  49. {softschema-0.2.1 → softschema-0.3.0}/examples/movie_page/README.md +0 -0
  50. {softschema-0.2.1 → softschema-0.3.0}/examples/movie_page/__init__.py +0 -0
  51. {softschema-0.2.1 → softschema-0.3.0}/examples/movie_page/host_integration.py +0 -0
  52. {softschema-0.2.1 → softschema-0.3.0}/examples/movie_page/model.py +0 -0
  53. {softschema-0.2.1 → softschema-0.3.0}/examples/movie_page/spirited-away.md +0 -0
  54. {softschema-0.2.1 → softschema-0.3.0}/examples/parity/__init__.py +0 -0
  55. {softschema-0.2.1 → softschema-0.3.0}/examples/parity/model.py +0 -0
  56. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/generate.py +0 -0
  57. {softschema-0.2.1 → softschema-0.3.0}/packages/python/src/softschema/py.typed +0 -0
  58. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_generate.py +0 -0
  59. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_metadata_rules.py +0 -0
  60. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_movie_page_example.py +0 -0
  61. {softschema-0.2.1 → softschema-0.3.0}/packages/python/tests/test_warning_codes.py +0 -0
  62. {softschema-0.2.1 → softschema-0.3.0}/packages/typescript/LICENSE +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 are held to exact behavioral parity: same flags,
15
- same canonical compiled JSON Schema, same validation results, so authoring an artifact
16
- is identical regardless of which you run.
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=f04 surface=agents-md -->
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 translate their requests into tbd
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.2.1
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 `skill --install`, which writes discoverable
56
- `SKILL.md` mirrors for Codex, Claude Code, Gemini CLI, and other coding agents.
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
- - **Pin it as a dependency** for projects, CI gates, and library use (reproducible,
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==0.2.1 # Python
236
- npm install -D softschema@0.2.1 # Node (or: bun add -d)
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—pin 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. See [Installation](docs/installation.md) for details, including the supply-chain
249
- cool-off that makes `@latest` safe to recommend.
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 discovered by Claude Code, Codex, Gemini CLI, Cursor, Copilot, and
283
- ~20 other coding agents.
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 # install repo-local skill mirrors
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 are held to **exact behavioral parity**: equivalent CLI inputs, outputs, and
327
- flags; equivalent library APIs; the same canonical compiled JSON Schema
328
- (content-identical, with an equal `schema_sha256` fingerprint); and the same
329
- engine-neutral validation results.
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 `skill --install`, which writes discoverable
28
- `SKILL.md` mirrors for Codex, Claude Code, Gemini CLI, and other coding agents.
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
- - **Pin it as a dependency** for projects, CI gates, and library use (reproducible,
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==0.2.1 # Python
208
- npm install -D softschema@0.2.1 # Node (or: bun add -d)
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—pin 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. See [Installation](docs/installation.md) for details, including the supply-chain
221
- cool-off that makes `@latest` safe to recommend.
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 discovered by Claude Code, Codex, Gemini CLI, Cursor, Copilot, and
255
- ~20 other coding agents.
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 # install repo-local skill mirrors
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 are held to **exact behavioral parity**: equivalent CLI inputs, outputs, and
299
- flags; equivalent library APIs; the same canonical compiled JSON Schema
300
- (content-identical, with an equal `schema_sha256` fingerprint); and the same
301
- engine-neutral validation results.
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`), held to **exact behavioral parity**: equivalent CLI
178
- inputs/outputs/flags and library APIs, the same canonical compiled JSON Schema
179
- (content-identical, equal `schema_sha256`), and the same engine-neutral validation
180
- results. Only idiomatic surface differs (snake_case camelCase, Pydantic ↔ Zod).
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. **Golden first.** Write or update the shared scenario in `tests/golden/scenarios/`
185
- (neutral, runs on both) or `tests/golden/scenarios-{py,ts}/` (per-language
186
- invocation, identical output) **before** touching code.
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
- | Byte-identical neutral CLI output | the shared golden corpus (run twice via `SOFTSCHEMA_IMPL`) |
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 byte parity | `cross-impl` job |
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 (142 as of 0.2.0)
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 (160 tests as of 0.2.0)
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 # 46 scenarios as of 0.2.0
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**, on both implementations, and byte-compare.
132
- Before a release, substitute the local builds for `uvx softschema@latest` /
133
- `npx softschema@latest` (the published forms are verified in Phase 5):
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
- Once the release ages past the cool-off, the unpinned `@latest` forms in the README
216
- resolve to it with no override.
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
- | | Pin as a dependency | Zero-install (`uvx` / `npx`) |
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` | Only if you pin the runner (`uvx softschema@0.2.1`) |
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—pin
17
- it as a dependency.
18
- For a quick one-off or an agent bootstrapping with nothing installed,
19
- use a zero-install runner**, pinned where the result must be repeatable.
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
- ## Pin as a Dependency
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==0.2.1 # project dev dependency; run via `uv run 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@0.2.1 # or: pnpm add -D / bun add -d
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 # Python implementation, ephemeral
41
- npx softschema@latest --help # Node implementation, ephemeral
40
+ uvx softschema@latest --help # Python implementation, ephemeral
41
+ npx -y softschema@latest --help # Node implementation, ephemeral
42
42
  ```
43
43
 
44
- Use `uvx softschema@0.2.1` / `npx -y softschema@0.2.1` when a repeated ad-hoc run must
45
- resolve the same version every time.
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 agent to `skill --install`, which writes
56
- `.agents/skills/softschema/SKILL.md` and `.claude/skills/softschema/SKILL.md` from the
57
- repository root.
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` is the recommended form for the agent-bootstrap path, including under a
77
- release-age cool-off.
78
- A gate such as npm’s `--before` / `NPM_CONFIG_BEFORE`, pnpm’s `minimumReleaseAge`, or
79
- uv’s `--exclude-newer` resolves `@latest` to the newest release old enough to pass, so
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
- - **Docs and the skill use `@latest`, not a pinned version.** README, the skill, and
23
- other human- and agent-facing material invoke `uvx softschema@latest` /
24
- `npx softschema@latest`, so there is no per-release pin to bump.
25
- This is safe here because the repo’s supply-chain policy enforces a 14-day cool-off
26
- (`UV_EXCLUDE_NEWER` / `--exclude-newer-package`; see
27
- `tbd guidelines supply-chain-hardening`), so `@latest` resolves to the newest release
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
- Bump any docs that pin the version (`installation.md`, the guide, README) in the same
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 ship here, at exact behavioral parity: see
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==0.2.0
487
+ uv add --dev softschema
488
488
 
489
489
  # Node
490
- npm i -D softschema@0.2.0
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 v0.2 shape is:
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 pattern at exact behavioral
692
- parity, Python/Pydantic and TypeScript/Zod.
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 deterministic JSON Schema YAML file with
704
- canonical-JSON hashing for drift checks.
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.