Skip to content

Commit 544602f

Browse files
dmealingclaude
andcommitted
docs(releasing): add pre-1.0 versioning policy (bump on API/default axis, not 'output changed')
Codifies the caret-rule litmus + a PATCH/MINOR/MAJOR rule table so output-changing bugfixes ship as PATCH (as already practiced) and MINOR is reserved for public-API breaks, default/shape changes, and wire-contract changes. Adds the required 'Generated-output change' changelog convention. Follow-up: #232 (gen-state engine version stamp). From the versioning-cadence review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeGSV3StPCcJGZNNJ4ZfAb
1 parent 050a3ab commit 544602f

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

docs/RELEASING.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,49 @@ Publish in tier order so a dependent never lands before its dependency. **`forge
7070
5. **npm versions are immutable.** You can never re-publish a version, and unpublish is a
7171
restricted 72-hour escape hatch. That's why we go RC-first.
7272

73+
## Versioning policy (pre-1.0)
74+
75+
**The version number's only mechanical meaning today is npm's caret rule.** For
76+
`0.y.z`, `^0.19.3` resolves `>=0.19.3 <0.20.0`, so: **PATCH is auto-adopted by every
77+
consumer on a routine `npm update`; MINOR requires a deliberate bump of their range.**
78+
That — not semver §8 — is the contract you are versioning against pre-1.0.
79+
80+
**Litmus test.** Can a consumer on `^prev` run `npm update && meta gen` and (1) still
81+
typecheck their owned generators + hand-written imports, and (2) get output that is
82+
byte-identical *or only corrects previously-wrong output*? **Yes to both → PATCH.
83+
Otherwise → MINOR.**
84+
85+
Do NOT reach for MINOR merely because "generated output changed." Scaffold-and-own
86+
(ADR-0034) does not firewall consumers from engine-output changes — the copied
87+
generators are thin compositions; the `render*` primitives + defaults live in the
88+
package and re-propagate on the next `meta gen`. So the axis is **API/default vs.
89+
bytes**, not "did output change."
90+
91+
| Change class | Example | Pre-1.0 | Post-1.0 |
92+
|---|---|---|---|
93+
| Public API **additive** (new export / optional param / CLI flag) | new `render*` primitive | PATCH (MINOR if it headlines a feature release) | MINOR |
94+
| Public API **breaking** (required param, removed/renamed export, changed CLI semantics) | `relativeModuleSpecifier` +required param | **MINOR** | MAJOR |
95+
| Output change = **pure bugfix** (wrong output corrected; correct output byte-identical) | 0.19.3 payload naming, 0.19.4 TPH stamping | **PATCH** | PATCH |
96+
| Output change alters **shape/default of *correct* output** (renamed generated export, changed default, dropped artifact) | `extStyle` `"none"→"js"` default flip | **MINOR** + a "Generated-output change" changelog flag + an opt-out where feasible | MAJOR if consumer code referencing the output breaks; else MINOR |
97+
| New **opt-in** codegen feature, default output byte-identical | new generator defaulting off | PATCH (MINOR if it adds registry vocabulary — cross-port conformance surface) | MINOR |
98+
| Wire-contract / conformance behavior change of already-valid deployments | FR-036 enforcement | **MINOR**, loud notice (pre-1.0 MINOR *is* the breaking slot) | MAJOR |
99+
| Wire behavior fixed to match the documented/conformance contract | 0.19.1 `@min` clamp | PATCH | PATCH |
100+
| Docs / tests / fixtures only (no product file in a port) | 0.19.4 npm scope | **No release for that registry** (per-registry scoping) | same |
101+
102+
**The `extStyle` 0.20.0 case, for calibration:** it was correctly MINOR — but for the
103+
*API break* (`relativeModuleSpecifier` gained a required param — a public export) **and**
104+
the *default flip* (churns every existing project's diff on regen), NOT because "output
105+
changed." Had it kept `"none"` as the default and only scaffolded `"js"` for new
106+
projects, PATCH would have been defensible.
107+
108+
**Changelog convention (required for output-changing releases).** Every entry in
109+
classes (bugfix-output) and (shape/default-output) must carry the phrase
110+
**"Generated-output change — regenerate to pick it up; three-way merge preserves hand
111+
edits."** The real risk of the (correct) PATCH cadence is a consumer seeing an
112+
unexplained `meta gen` diff after `npm update`; the changelog flag + the planned
113+
gen-state engine-version stamp (see the tracking issue) are how you keep every such
114+
diff explained.
115+
73116
## Prerequisites
74117

75118
- The JS/TS **workspace root is the repo root** (`/package.json`), globbing

0 commit comments

Comments
 (0)