CANP-WP-0002 T07: semver precedence and strict packaging
Two defects from the original review of the seed. Prerelease ordering was worse than first recorded. parse_semver returned (major, minor, patch, raw_string), so 1.0.0-rc1 and 1.0.0 tied on the numeric fields and then compared as strings — "1.0.0-rc1" > "1.0.0". A release candidate therefore shadowed its own release for `newest` and for `>=`, not just for the no-version case. parse_semver now returns a SemVer section 11 precedence key: numeric fields, a release/prerelease rank, then dot-separated prerelease identifiers with numeric ones compared numerically. Build metadata is ignored. Beyond ordering, prereleases are excluded from `any`, `newest` and `>=` entirely; only an exact pin selects one, so publishing a release candidate never changes what existing consumers resolve to. A package holding only prereleases now says so rather than reporting a bare not-found. Packaging copied the whole source directory, so a stray .git, virtualenv or scratch file landed in the catalog and registry. Section 2 already required otherwise — tools MUST ignore unknown non-reserved files unless a manifest field references them — so this is conformance rather than a new rule. What is new is that omissions are reported instead of silent: not packaged (not a reserved path, not referenced by the manifest): .git/, .venv/, notes.txt LICENSE joins the reserved paths. Strict packaging would otherwise drop a package's license text while faithfully copying its `license` field, which contradicts section 14's instruction to surface licensing on publish and install. Spec: 2 (LICENSE, packaging obligation, reporting), 17.1 new, 10.3 note. Reference CLI: parse_semver rewritten with is_prerelease; select_version and pick_version updated; copy_package and report_skipped replace copy_immutable. Tests 65 -> 78. examples/pqrst-estimate carries a LICENSE and a license field, exercising the new reserved path. Also fixes a leaked loop variable in package_members that would have reported a bad `template` path as an `evals` error. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM Assistant: claude-code Assistant-Model: opus Assistant-Process: 388925@bnt-lap001 Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
This commit is contained in:
parent
e885eb7b05
commit
95a8bb31d2
8 changed files with 306 additions and 34 deletions
|
|
@ -53,12 +53,24 @@ my-prompt/
|
|||
| `prompt.yaml` | Required package manifest |
|
||||
| `prompt.md` | Default prompt template unless overridden by `template` |
|
||||
| `README.md` | Optional human documentation |
|
||||
| `LICENSE` | Optional license text |
|
||||
| `examples/` | Optional examples/fixtures |
|
||||
| `evals/` | Optional evaluation specifications |
|
||||
| `assets/` | Optional supporting text/data artifacts |
|
||||
|
||||
Tools MUST ignore unknown non-reserved files unless a manifest field explicitly references them.
|
||||
|
||||
This governs packaging as well as reading: a tool that copies a package into a
|
||||
catalog or registry MUST copy the reserved paths and the files a manifest
|
||||
field references, and nothing else. A working directory's `.git`, virtualenv or
|
||||
scratch files are not part of the package and MUST NOT be published with it. A
|
||||
tool that omits files SHOULD say which, so that an author is never silently
|
||||
surprised by what did not ship.
|
||||
|
||||
`LICENSE` is reserved because § 14 asks tools to surface licensing on publish
|
||||
and install, and because dropping the license text while faithfully copying the
|
||||
`license` field would misrepresent the package.
|
||||
|
||||
## 3. Manifest
|
||||
|
||||
The canonical manifest is UTF-8 YAML named `prompt.yaml`.
|
||||
|
|
@ -680,6 +692,9 @@ reported as ambiguous rather than chosen.
|
|||
| `newest` | the newest available version |
|
||||
| `>= 1.2.0` | the newest available version that is at least `1.2.0` |
|
||||
|
||||
Prereleases are excluded from `any`, `newest` and `>=` (§ 17.1); name one
|
||||
exactly to select it.
|
||||
|
||||
**An exact pin is the expected form.** The other three are explicit opt-ins,
|
||||
visible in the manifest, so that looseness is always something an author wrote
|
||||
rather than something absence implied.
|
||||
|
|
@ -887,6 +902,17 @@ both is not in a conflict — it is holding two things whose names happen to
|
|||
coincide. Only a repeat publication *within one registry* violates
|
||||
immutability.
|
||||
|
||||
### 17.1 Precedence and prereleases
|
||||
|
||||
Where versions are compared, precedence follows Semantic Versioning: numeric
|
||||
fields first, and a prerelease version ranks **below** its own release, so
|
||||
`1.0.0-rc1` precedes `1.0.0`. Build metadata does not affect precedence.
|
||||
|
||||
A prerelease is **not selected** by `any`, `newest`, or a `>=` lower bound
|
||||
(§ 10.3). Only an exact pin selects one. Publishing a release candidate
|
||||
therefore never changes what existing consumers resolve to — which is the
|
||||
point of marking it a candidate.
|
||||
|
||||
Suggested versioning guidance:
|
||||
|
||||
- PATCH: wording/metadata correction with intended behavior unchanged;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue