@geonosis/release 2.3.0 → 2.4.2

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,200 @@
1
+ # @geonosis/release
2
+
3
+ ## 2.4.2
4
+
5
+ ## 2.4.1
6
+
7
+ ## 2.4.0
8
+
9
+ ### Minor Changes
10
+
11
+ - 4962ed6: Every publishable package names `CHANGELOG.md` in `files`, not only the five floors. Measured on the 2.4.0 tarballs before they shipped: **0 of the 22 group packages carried one**, so `geonosis update`'s `BY HAND` block printed nothing for a group bump — the third consecutive release, in the cut where a consumer would have read the sweep, the holder and the Stop-hook fixes. `tooling/floor-changelog-shipped.test.ts` now holds the whole workspace rather than the floors, so a package cannot fall out of the convention silently.
12
+
13
+ The doctor's `exams` check asks one question per EXAM instead of one per package. `@geonosis/db` ships three (`sessionConformance`, `entityConformance`, `singletonConformance`), and importing any one of them anywhere used to answer OK for the whole package — so a consumer running the session exam alone read green while two floors' behaviour was never exercised. That is this check's own docstring failing inside the check written to state it.
14
+
15
+ The plugin-drift line knows a release candidate. A tree whose `overrides`/`resolutions` point a kit package at a `file:`, `link:`, `portal:` or `.tgz` spec is installed from a candidate the registry has never seen, so `claude plugin update` cannot reach that version at all — the WARN was unavoidable and unactionable for the whole life of every RC, in the window a consumer reads the doctor hardest. It now says the packages are a candidate and that the question becomes real when that version publishes.
16
+
17
+ `smoke run` refuses a STALE recording instead of rendering a verdict over it. The 2.4.0 sweep headlined `FAIL … the release broke 1 of their gates` and printed `STALE` as its last line, fifteen lines below: both true, and the FAIL was a consumer frozen two releases back crossing a break declared in the one before, while the tree they actually have had migrated past it and was green. A stale recording cannot answer whether THIS release breaks them — only what it does to a tree nobody has — so it leads the block, names the command that re-takes it, and exits 2, the code for a run that could not be made.
18
+
19
+ ## 2.3.1
20
+
21
+ ## 2.3.0
22
+
23
+ ### Minor Changes
24
+
25
+ - 3dac9a7: **`exams`, the doctor's eleventh check (#293).** A floor bump that breaks search is invisible to a
26
+ tier that never runs the search exam. A verify tier declares COMMANDS, not globs, so "the exam runs
27
+ in the fast tier" is not checkable — but whether a test file importing the exam exists at all is.
28
+ For every `@geonosis/*` package a manifest declares, the check reads the exams that package ships
29
+ (every export ending in `Conformance`, off the installed floor rather than a list held here) and
30
+ WARNs, naming them, when no test file imports one. The adoption sweep's consumer row now carries an
31
+ `EXAMS` line listing the exams the recording's own test files run.
32
+ - 3dac9a7: **A recording is the ref's tree, and it carries history (#299, #307).** The walk now stops at ANY
33
+ directory holding its own `.git` — an agent's worktree, a vendored checkout — and records what it
34
+ skipped; `.claude/` was the first patch and this is the rule that needs no directory name. And the
35
+ recording gets a shallow clone of the ref through `file://` rather than a copy of the object store,
36
+ so a consumer's own tier step that reads git (`git diff --name-only origin/main..HEAD`) answers
37
+ inside it instead of exiting 2 at both versions and reading as "already failing at their versions".
38
+ A tree with no history to record says so in the record, by name.
39
+ - 3dac9a7: **`geonosis-release changelog` (#99).** Every publishable package's `CHANGELOG.md`, and every
40
+ `## <version>` heading with nothing under it — a reader told a version shipped and told nothing
41
+ else. A release check rather than a verify step: the empties in a tree are history, and a fixed
42
+ publish group makes them by construction. Measured on this workspace: 61 of 238 headings over 27
43
+ files.
44
+ - 3dac9a7: **One `--since`, and a report a machine can read (#97).** `--since` names a plan number, a day and
45
+ a git ref in three commands, and all three took any string: `plan check --since garbage` exempted
46
+ nothing and printed the verdict it would have printed with no flag, `stats --since notadate` put
47
+ every recorded day outside the window and printed `0 turns` as a pass rate. One reader now declares
48
+ which kind each means and refuses an unreadable value by name. `geonosis-ratchet`,
49
+ `geonosis-verify-arch` and `geonosis-lint-parity` take `--json`: the same report, on stdout,
50
+ whatever the verdict — `--json` with an explicit `--format` is refused rather than resolved.
51
+
52
+ ### Patch Changes
53
+
54
+ - 3dac9a7: **One documented spelling (#90).** Every README of a package the metapackage fronts now names
55
+ `geonosis <tool>` — the door that pins the whole toolchain at one version — beside the bare bin, and
56
+ a `tooling/` test holds it. `#230`'s stamp test lands with it: every flag `docs/orchestration.md`'s
57
+ adoption loop names has to carry the version it first ships in, because the loop once told a
58
+ consumer to run a flag the published version did not have.
59
+ - a8ab653: The floor API-shape guard compares against the last PUBLISHED version rather than the one the manifest holds after `changeset version`, and reads the changelog entry the cut wrote beside any pending changesets. A guard that reads only pending changesets is blind at the cut — the moment it is the last thing between a changed shape and a publish.
60
+
61
+ ## 2.2.0
62
+
63
+ ### Minor Changes
64
+
65
+ - d15a654: **A floor adoption is measured (#280).** The user's rule — a floor is adopted the day it deletes
66
+ more than it adds — had no instrument: during.day's four db floors came out +222/−225 and its
67
+ workflows floor +1807/−1493, and both numbers were read by nobody until they were asked for. A
68
+ consumer declares `adoption.seams: [globs]` in `geonosis.json` (default none, and a repo that
69
+ declares none gets no figure rather than a figure about everything). `geonosis update` then reports
70
+ lines deleted against lines added over those globs, `git diff --numstat` between the commit the bump
71
+ started from and the working tree, in the verdict and in the bump report. `geonosis-ratchet` gains
72
+ `adoptionSeamLines`, the lines those globs still hold — a number the ratchet already refuses to let
73
+ grow. A snapshot records the same figure for its consumer and `geonosis-release adoption` carries it
74
+ per consumer (MEASURED: a consumer's `.geonosis/` is an excluded directory, so their own bump report
75
+ never reaches a recording — the figure is taken where the tree is read).
76
+ - d15a654: **The smoke runs a consumer's TESTS (#272).** It read their typecheck, their lint and their doctor
77
+ and never their suites, so a floor change that kept their types and their linter green while their
78
+ own tests went red printed "nothing this release changed reddened their tree". `test` is a fourth
79
+ phase: read off their `test` script, nameable as `--test <cmd>` and as
80
+ `release.smoke.snapshots[].commands.test`, compared against the baseline with the same "already
81
+ failing at their versions" logic. The phase list has one source both the runner and the config
82
+ reader read.
83
+
84
+ ### Patch Changes
85
+
86
+ - 45f3d79: **A recording reads the consumer's tree, never the worktrees under `.claude/`.** The snapshot walked `.claude/worktrees/<agent>/…` inside a consumer's root and read a stopped agent's branch as part of main — the adoption sweep then called the group INCOHERENT (2.0.0 and 2.1.0 in "one tree") for manifests that were never on main. `.claude` joins the excluded directories.
87
+ - d15a654: **An envelope writer refuses a root it has been told is not its (#241).** A suite ran one over the
88
+ SHARED repo root mid-run: parallel suites made the comparison racy, and the file it left behind is
89
+ one the next run reads as real. Every one of the seven writer copies now refuses to write when
90
+ `GEONOSIS_ENVELOPES_FORBIDDEN_ROOT` names the root it was pointed at, saying so and pointing at a
91
+ scratch root instead. The kit's own vitest config sets it to the repo root, so a test that writes an
92
+ envelope there names itself — which is how the offender that filed this row was found again.
93
+
94
+ ## 2.1.0
95
+
96
+ ### Minor Changes
97
+
98
+ - a200ec5: **The smoke reads every DECLARED consumer, and refuses the one it could have read (D-061).** 2.0.0 was read against one consumer of two: `dielime` was declared, its tree was on the disk, and every sweep skipped it with a sentence nobody was blocked by — its first smoke ran an hour after publish and was red. `smoke run` with no `--snapshot` now refuses (exit 2) a declared name with no recording whose tree this machine has, naming the `smoke snapshot` command to run; the paths of never-recorded trees are read from an uncommitted `.geonosis/consumer-trees.local.json`, and `--absent <name>` excuses one out loud while keeping its three phases in the envelope's denominator. `smoke snapshot` records the source tree's commit (read-only `git rev-parse`, or the sentence saying why there is none), and a sweep over a recording whose tree has moved since prints `STALE <name>: recorded at <c1>, the tree is at <c2>` and carries it in the envelope's findings — a report, not a failure. A declared snapshot may carry `commands: { doctor?, lint?, typecheck? }`, so a consumer whose gates are not the three script names of those names (dielime has no root `typecheck`) is read on its real ones; the recording keeps what it saw. The printed report is one block per declared consumer, in declaration order.
99
+ - e419bb4: **`geonosis-release adoption` — the distance every declared consumer is at (D-061).** dielime on 1.2.0 and during.day's group split across 1.1.0 and 1.4.0 were both read by hand off their manifests on publish morning; no instrument reported either, so nothing carried them into a release review. The sweep reads the recordings the smoke already keeps — never a consumer's disk — and prints, per declared consumer: `MATCH`, `BEHIND <name> <declared> → <current>`, `INCOHERENT` (a group published as one number declared at two versions in one tree), and `FLOOR UNDECLARED` (informational — a floor is opted into). The current numbers come off this workspace, or off npm with `--registry`, through the same HTTP reader `published --group` uses. Exit 0 always: it is a scoreboard, not a gate. The envelope `release-adoption.json` counts every declared consumer as read or excused, and `geonosis-ledger handoff` quotes it in one line — read from the file, never by running the sweep.
100
+
101
+ ### Patch Changes
102
+
103
+ - f252d95: **A harness says when the install edited the tree it was measuring (#216).** Measured on pnpm 11.5.1 and 11.8.0 against a `min-release-age=7` in `~/.npmrc`: installing a package younger than that APPENDS a `minimumReleaseAgeExclude:` block to the tree's `pnpm-workspace.yaml`, and pinning the manager version does not stop it — 11.5.1 rewrites it exactly as 11.8.0 does. The smoke now compares `.npmrc`, `bunfig.toml` and `pnpm-workspace.yaml` across its `run/` install and carries a finding naming the file, so a run over a tree that is no longer byte-for-byte the consumer's says so instead of reporting on it silently. `update --prove` writes `packageManager` into the scratch manifest — the manager and version that ran, so a rerun of that directory gets the same one — and carries one proof per manager that every config file the fixture wrote came back byte-identical.
104
+
105
+ ## 2.0.0
106
+
107
+ ### Minor Changes
108
+
109
+ - 3258f5f: **`geonosis-release published --group` — the release is the group resolving from npm, not the publish exiting zero (#147).** Every `package.json` in the tree against the version the registry answers, no sampling, `considered` naming its own denominator and the manifests it excused. `--wait <seconds>` polls through the few minutes in which a freshly published name still 404s. Exit 0 the whole group, 1 a gap named per package, 2 the registry could not be asked — which is not "not published". The registry is read over HTTP and never through `npm view` or `bun pm view`: the manager's manifest cache is what read one release behind and aborted a consumer's bump.
110
+ - 7de7bf6: **`geonosis-release smoke baseline` / `smoke run`** — the release candidate installed into a consumer's tree before it is published. Every workspace package is packed with `pnpm pack` (the TARBALL is what a consumer installs, and a release that "shipped no declarations" shipped them in the tree and not in the tarball), a COPY of the snapshot's manifests is pointed at those tarballs, the copy is installed with the snapshot's own manager — bun and pnpm, both measured here, a third refused by name — and the snapshot's own typecheck, lint and doctor are run. `baseline` records what those three answered at the versions that consumer is on; `run` fails only on what THIS release broke, quoting their compiler's and their doctor's own lines, and reports what was already red as not this release's doing. A tarball whose manifest promises `types` it does not carry is a finding by itself. Exit 0 nothing new, 1 a new failure, 2 the run could not be made — an install that failed, a snapshot that is not there, a missing baseline (a run that took its own answer as the standard would certify anything), or a phase the baseline cannot be compared to. The three commands are an envelope: considered 3, read + refused + excused, per snapshot. Four of C4's five escapes are planted through the real bin and caught (TS7016, a widened kind, a kind dropped on the read path, a doctor exit flip); the fifth is the migrations gate's own and is cited, not re-planted.
111
+ - 7de7bf6: **`geonosis-release smoke snapshot <name> --from <their tree>`** — the tree a release has to be read against, copied read-only into `.geonosis/consumer-snapshots/<name>/`. Installed packages, build output and the git history stay behind; the manager is read off the lockfile (`bun.lock`/`bun.lockb` → bun, `pnpm-lock.yaml` → pnpm) and a manager the pack → rewrite → install path has never been measured under is refused BY NAME rather than treated as one of those two. The versions every manifest declares and the command each phase will run — a script of theirs, a binary their install puts there, or a sentence saying there is nothing to run — are recorded beside the copy. D-048 is enforced by the tool, not by a comment: it asks git, in the tree it is about to write into, whether those bytes could be committed, and refuses if they could. Measured 2026-09-01: during.day 4,406 files / 79 MB / 5.6 s, all three phases resolved; dielime 13,659 files / 511 MB / 26 s, `typecheck` a sentence because that tree has no such script.
112
+ - 15663aa: **A smoke that installs the WHOLE release candidate.** `pnpm pack` resolves a `workspace:^` sibling
113
+ to a published range, so a snapshot pointed only at the tarballs it declares still fetched the
114
+ release's inner edges from the registry — and a floor package whose first release this is could not
115
+ be installed at all (`@geonosis/search@0.1.0`'s dependencies, measured 2026-09-02). Every packed
116
+ name is now pinned to its own tarball for the whole tree: for pnpm in `pnpm-workspace.yaml`
117
+ (pnpm 11.8.0 ignores `pnpm.overrides` in `package.json` — measured), for bun in `overrides` on the
118
+ root manifest (bun 1.4.0 — measured). A consumer's own overrides are kept; one this run pins is
119
+ dropped from their block first, because a duplicate YAML key is not a merge.
120
+ - 7de7bf6: **The smoke is a step of the release protocol, and the repo names the consumers it expects.** `geonosis.json` → `release.smoke.snapshots` (`{ name, install? }`) and `release.smoke.exclude`; a key it does not read is refused by name with the shape. `smoke run` with no `--snapshot` sweeps every snapshot the repo names, `--rc-dir` defaulting to the workspace it is run in. A tree that is not on this machine is a SKIP with the sentence saying what could not be asked — a laptop without the consumer trees must not fail — and its three commands stay in the envelope's denominator as excused, so a sweep that asked nothing cannot be read as a sweep that asked everything. A sweep over zero consumers is refused outright. `docs/releasing.md` carries the step, with the measurements behind it.
121
+ - 415c466: **The smoke reaches the doctor the way the consumer does (#218).** Its doctor phase ran only where a manifest installed `@geonosis/doctor` DIRECTLY — and during.day had correctly dropped that root devDependency on this kit's own advice (#177: the door already brings it, and a second declaration is a version that can disagree). The snapshot said "nothing to run" and a cut would have measured typecheck and lint only. A tree that installs `@geonosis/cli` (or the `geonosis` metapackage) now runs `geonosis doctor`; "nothing to run" is recorded only when neither the package nor a door is installed, and the sentence names both.
122
+
123
+ ### Patch Changes
124
+
125
+ - 5c25a6d: **`geonosis-release schema` read past a quoted table name.** The cross-domain wall's lookbehind
126
+ excluded a preceding `"`, so `ALTER TABLE "invoices"` — the spelling drizzle-kit emits, and the one
127
+ the kit's own first domain ships — was clean while the bare `ALTER TABLE invoices` was a finding.
128
+ Found by declaring `release.schema` over `@geonosis/search`'s migrations; a qualified `other.name`
129
+ is still not a reference to `name`.
130
+
131
+ ## 1.4.0
132
+
133
+ ### Patch Changes
134
+
135
+ - 113fdb2: **`geonosis-release migrations` writes its envelope.** `.geonosis/envelopes/release-migrations.json` says how many added files the run considered against how many it read, with the marker-excused files in `excused` and the ones it could not read at all in `refused`; narrowing verbs, unbelievable markers and squawk findings are FINDINGS, because those files were read — that is why there are findings. The two halves are taken from different lists on purpose: `read`/`excused` off each file's own state, `refused` off `unreadable`, so a file that reached one list and not the other breaks the arithmetic and the run renders no verdict rather than a wrong one. The bin harness now stages `package.json` beside `dist/`, as a published package always has, so the envelope names a real version instead of `unknown`.
136
+
137
+ ## 1.3.0
138
+
139
+ ### Minor Changes
140
+
141
+ - 0a7673c: **`release.migrations[]` was discoverable only by reading `dist/` (#75).** A consumer reverse-
142
+ engineered the entry shape out of a bundled chunk file, because every refusal here named the key it
143
+ rejected and never the ones it would have accepted. Each now ends with
144
+ `expected { dir, dialect, phases?, squawk? }`, an unknown key inside an entry or inside the `release`
145
+ block is refused BY NAME rather than ignored, and `geonosis-release --print-config-shape` prints the
146
+ whole shape without a config present.
147
+
148
+ **`squawk-cli` is an optional peer, not a hard dependency (#73).** It ships platform binaries, and
149
+ as a dependency of this package it grew dielime's lockfile by 395 lines for a Postgres linter that
150
+ repo never configured. Nothing installs it for you now: a `release.migrations` naming only `sqlite`
151
+ never calls it and is unaffected; a `postgres` or `mikro-orm-ts` dialect with it absent exits 2 with
152
+ the exact install line, `pnpm add -D squawk-cli@2.63.0`. `npm pack` carries a manifest with no
153
+ runtime dependency at all, and a test holds the install line to the version the manifest asks for.
154
+
155
+ ## 1.2.0
156
+
157
+ ### Patch Changes
158
+
159
+ - 0268ee7: `migrations` accounts for every file the diff added — by name and state (clean, excused, refused,
160
+ squawk findings, unreadable) — and the summary says N of N. The FAIL report listed only the files
161
+ with findings, so a clean fourth migration (dielime's `do $$ … $$` block, which squawk passes) was
162
+ never mentioned and three-of-four read exactly like four-of-four (#69). A file this reader cannot
163
+ read is named and the loop goes on; it was a hard stop that left every other migration in the range
164
+ unread with the count at zero (#70). Exit 2 stays for an unreadable file — after everything else was
165
+ read and reported.
166
+ - eb94097: `migrations` reads the working tree and the index as well as the commits since `--since`: the same
167
+ `DROP COLUMN` was refused when committed and read `OK … (0 read)` when staged or untracked — silent
168
+ in the one window, a local gate before the commit, in which a narrowing is still free to fix; there
169
+ is no state in which "this DROP COLUMN is fine because it is not committed yet" is true
170
+ (during.day, #68). A run that found no migration file anywhere now says `NONE … nothing was read`
171
+ rather than OK.
172
+
173
+ ## 1.1.0
174
+
175
+ ### Minor Changes
176
+
177
+ - 8982fad: The across-releases rule: `-- contract-migration: <reason> since:<ref>` excuses a narrowing only
178
+ when `git merge-base --is-ancestor <ref> <since>` holds. A marker with no reason, no `since:`, an
179
+ unknown ref, or a ref inside this very diff is refused with the line saying which — and the
180
+ narrowing it was written over is still reported.
181
+ - 39ac31b: `geonosis-release plan` validates the contract as data — upload → park → prove → promote, in that
182
+ order and no other, with `proof.mustAssertVersion` on unless somebody signs for turning it off.
183
+ `geonosis-release prove` runs one release over a runner the consumer supplies (JSON on stdio) and
184
+ refuses a smoke that answered a version other than the one it overrode to, a smoke that failed, and
185
+ a promote of a version nothing proved. With no runner it plants all three into its own stub.
186
+ - 749239a: `geonosis-release deployed --check` compares `.geonosis/deployed.json` — what a pipeline reported
187
+ after promote — against the wrangler configs and secret names the tree declares. Drift either way
188
+ is exit 1; the file being absent is exit 2, never a pass. `@geonosis/doctor` gains a seventh line,
189
+ `deployed`, over the same file, reading it rather than importing the release package.
190
+ - 2ebded4: `geonosis-release migrations --since <ref>`: the expand-only gate, dialect-routed by
191
+ `geonosis.json → release.migrations[]`. `sqlite` reads the five narrowing verbs; `postgres` runs the
192
+ pinned `squawk-cli` and surfaces its exit code and output verbatim; `mikro-orm-ts` extracts the SQL
193
+ out of `addSql(…)` in `up()` and reads it both ways. A squawk that cannot run is exit 2, never 0.
194
+
195
+ ### Patch Changes
196
+
197
+ - 9f8207b: The `geonosis-release` shim refuses, with exit 2, when `dist/` is older than the `src/` beside it —
198
+ the guard every other bin in the kit already carries. The published package ships no `src/`, so
199
+ there the check is skipped. The plugin's wall probes are back-dated so that planting one cannot
200
+ make an unrelated package's build look stale to a suite running its bin at the same moment.
@@ -17,11 +17,25 @@ const newest = (dir) =>
17
17
  }, 0)
18
18
  : 0
19
19
  const src = join(here, '..', 'src')
20
- if (existsSync(src) && newest(src) > newest(join(here, '..', 'dist'))) {
21
- process.stderr.write(
22
- 'geonosis-release: dist is older than srcrun pnpm build before trusting this bin.\n',
23
- )
24
- process.exit(2)
20
+ const dist = join(here, '..', 'dist')
21
+ // `newest` answers 0 for a directory that is NOT THERE and for one that is merely old, so the
22
+ // two conditions were one comparison and one sentence and the staleness sentence was printed
23
+ // over trees that had never been built at all, blocking a turn in a fresh git worktree, which
24
+ // has no dist because dist is not committed (#357). Only the second is evidence of a mistake.
25
+ if (existsSync(src)) {
26
+ const built = newest(dist)
27
+ if (built === 0) {
28
+ process.stderr.write(
29
+ 'geonosis-release: this tree has never been built — run pnpm build. No dist here at all, which is what a fresh clone or a linked git worktree starts with; nothing is stale.\n',
30
+ )
31
+ process.exit(2)
32
+ }
33
+ if (newest(src) > built) {
34
+ process.stderr.write(
35
+ 'geonosis-release: dist is older than src — run pnpm build before trusting this bin.\n',
36
+ )
37
+ process.exit(2)
38
+ }
25
39
  }
26
40
 
27
41
  await import('../dist/release-cli.js')
@@ -2378,10 +2378,18 @@ var entryBlock = (entry) => {
2378
2378
  const head = entry.why.startsWith("--absent") ? EXCUSED : "SKIP ";
2379
2379
  return `${head} smoke ${entry.name}: ${entry.why}
2380
2380
  `;
2381
+ }
2382
+ if (entry.note !== void 0 && "stale" in entry.note) {
2383
+ return `${entry.note.stale}
2384
+ this release was NOT read against the tree they have \u2014 what follows is about the RECORDED one, and says nothing about whether this release breaks them. Re-take it: geonosis-release smoke snapshot ${entry.name} --from <their tree> --replace
2385
+ ${formatSmoke(entry.comparison)}`;
2381
2386
  }
2382
2387
  return `${formatSmoke(entry.comparison)}${entry.note === void 0 ? "" : `${noteLine(entry.note)}
2383
2388
  `}`;
2384
2389
  };
2390
+ var staleIn = (sweep) => sweep.entries.flatMap(
2391
+ (one) => "comparison" in one && one.note !== void 0 && "stale" in one.note ? [one.name] : []
2392
+ );
2385
2393
  var formatSweep = (sweep) => sweep.entries.map(entryBlock).join("");
2386
2394
  var sweepEnvelope = (sweep, durationMs) => {
2387
2395
  const excused = [];
@@ -2634,6 +2642,7 @@ export {
2634
2642
  CONSUMER_TREES_FILE,
2635
2643
  sweepSmoke,
2636
2644
  comparisonsIn,
2645
+ staleIn,
2637
2646
  formatSweep,
2638
2647
  sweepEnvelope,
2639
2648
  formatSmoke,
package/dist/index.js CHANGED
@@ -74,7 +74,7 @@ import {
74
74
  statementsOf,
75
75
  sweepEnvelope,
76
76
  sweepSmoke
77
- } from "./chunk-7H7SV5EP.js";
77
+ } from "./chunk-CACOG4I5.js";
78
78
  export {
79
79
  ADOPTION_NEXT,
80
80
  ADOPTION_TOOL,
@@ -36,10 +36,11 @@ import {
36
36
  runSchema,
37
37
  runSnapshot,
38
38
  schemaEnvelope,
39
+ staleIn,
39
40
  sweepEnvelope,
40
41
  sweepSmoke,
41
42
  writeEnvelope
42
- } from "./chunk-7H7SV5EP.js";
43
+ } from "./chunk-CACOG4I5.js";
43
44
 
44
45
  // src/release-cli.ts
45
46
  import { existsSync } from "fs";
@@ -468,6 +469,16 @@ var smokeRun = (parsed, root, cwd) => {
468
469
  `);
469
470
  const comparisons = comparisonsIn(swept);
470
471
  if (comparisons.some((one) => one.refused.length > 0)) return 2;
472
+ const stale = staleIn(swept);
473
+ if (stale.length > 0) {
474
+ if (!parsed.json) {
475
+ process.stdout.write(
476
+ `smoke NOT MEASURED \u2014 ${stale.join(", ")} was read against a recording that no longer describes it. Re-take the snapshot and run again.
477
+ `
478
+ );
479
+ }
480
+ return 2;
481
+ }
471
482
  return comparisons.every((one) => one.ok) ? 0 : 1;
472
483
  };
473
484
  var smoke = (parsed, cwd) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geonosis/release",
3
- "version": "2.3.0",
3
+ "version": "2.4.2",
4
4
  "types": "./dist/index.d.ts",
5
5
  "description": "The release contract with its proofs: an expand-only migration gate over three dialects, a smoke that must name the version that answered it, and declared ≠ deployed.",
6
6
  "keywords": [
@@ -32,6 +32,7 @@
32
32
  }
33
33
  },
34
34
  "files": [
35
+ "CHANGELOG.md",
35
36
  "bin",
36
37
  "dist"
37
38
  ],
@@ -45,7 +46,7 @@
45
46
  },
46
47
  "devDependencies": {
47
48
  "squawk-cli": "2.63.0",
48
- "@geonosis/ratchet": "2.3.0"
49
+ "@geonosis/ratchet": "2.4.2"
49
50
  },
50
51
  "engines": {
51
52
  "node": ">=22"