gstack/ship
Carrington Dennis 665f979d57 fix(ship): version-bump skipped subdirectory manifests and wrote npm-invalid versions
Two ways `gstack-version-bump` left a release half-done, both silent.

1. It only ever looked at ./package.json. A repo whose only Node package lives
   in a subdirectory (web/, app/, frontend/) has no root manifest, so classify
   reported pkgExists:false and every bump wrote VERSION alone -- leaving the
   manifest to be edited by hand, which is the exact drift this tool exists to
   prevent, in the one layout where it silently did nothing. The path now
   resolves --package-json-path -> .gstack/package-json-path -> ./package.json,
   so a subdirectory package is covered by a one-line pin.

2. VERSION is 4-digit MAJOR.MINOR.PATCH.MICRO and npm's semver is 3-component:
   npm rejects the fourth. Mirroring VERSION 1:1 into an npm-managed manifest
   writes a version npm will not install. When a package-lock.json sits beside
   the manifest -- proof npm actually manages it -- the MICRO is now dropped
   (0.1.26.0 -> 0.1.26) and the lockfile's two version fields are mirrored too
   (root and packages[""], which npm keeps in step and nothing else in a release
   does, so a lockfile left behind drifts one field per bump until someone runs
   npm). Pure JSON edit, no npm spawn, no dependency-tree churn.

   Without a lockfile nothing validates the field, so the historical 1:1 mirror
   is preserved -- gstack's own package.json carries 1.60.1.0 and keeps doing so.

classifyState needed an expectedPkg parameter for (2): it defaults to VERSION,
but for an npm-managed manifest it is the 3-component truncation. Otherwise a
correctly-synced 0.1.27 reads as drift against 0.1.27.0 forever and every
classify returns DRIFT.

Step 12 of the ship skill documents the new behaviour; the three ship-skill
golden fixtures are updated to match the regenerated hosts.

7 new tests covering both sides, including the negatives: the pin, the override,
both lockfile fields, the correctly-synced-is-not-drift case, repair, and the
no-lockfile 4-digit path that must not change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 11:45:30 -04:00
..
sections v1.58.1.0 feat: hermetic local E2E + Conductor prose AskUserQuestion (#2004) 2026-06-14 11:40:57 -07:00
SKILL.md fix(ship): version-bump skipped subdirectory manifests and wrote npm-invalid versions 2026-08-12 11:45:30 -04:00
SKILL.md.tmpl fix(ship): version-bump skipped subdirectory manifests and wrote npm-invalid versions 2026-08-12 11:45:30 -04:00