Skip to content

docs(openspec): publish per-platform Vale binary packages - #72

Draft
thecodedrift wants to merge 5 commits into
mainfrom
openspec/add-vale-binary-packages
Draft

docs(openspec): publish per-platform Vale binary packages#72
thecodedrift wants to merge 5 commits into
mainfrom
openspec/add-vale-binary-packages

Conversation

@thecodedrift

@thecodedrift thecodedrift commented Jul 28, 2026

Copy link
Copy Markdown
Member

Draft — not ready for review. Spec only; no implementation yet. Opened to keep the work on the remote.

Publishes the Vale binary as per-platform npm packages from this repo, so a first-class engine isn't a host prerequisite.

The only existing npm distribution, @vvago/vale, is third-party and downloads at postinstall. That script runs during a consumer's install under a policy we don't set — pnpm 10 blocks dependency build scripts by default — producing no binary and no error. The objection is mechanism, not provenance: it would stand if the Vale project published it. Binary-in-tarball is integrity-hashed, lockfile-pinned, resolves offline, and needs no lifecycle script. So packages/vale-<platform>/ carries the binary with os/cpu declared and no bin, no code, no scripts — ast-grep's packaging without ast-grep's installation, whose hardlink step already fails here under pnpm dlx.

Versioning is an all-prerelease timestamp, <valeVersion>-<yyyymmddhhmmss>, with a plain <valeVersion> never published. That keeps the Vale version legible, means a packaging fix is a new timestamp on the same base rather than a spent version, and — because a prerelease only satisfies a range naming the same major.minor.patch — makes ^3.15.2 provably unable to resolve. Exact pinning stops being a convention someone can drift from.

Binaries are not committed; seven platforms at 10–20 MB each would live in git history permanently, so a published tarball is not reproducible from a plain clone. SHA256 checksums are committed and reviewed, and the pipeline refuses a mismatch, keeping "what can merge to main" as the trust boundary. The workflow runs in two phases — detect upstream on a schedule and open a PR with the new version and checksums, then publish on merge — so nobody has to notice a Vale release and nothing publishes on bytes nobody signed off on. Safe to automate because publishing is inert: the CLI pins a literal exact version, so a new package reaches nobody until that pin is deliberately bumped.

Also carries two CLAUDE.md fixes, unrelated to Vale but too small to spend PRs on:

  • The PR-reference table documented only TSKL-, reading as though it's the only bare identifier the Linear integration resolves. It isn't — OSS-23 linked and moved to In Review on PR creation for ref(cli): resolve ast-grep without an install-time step #69.
  • A warning to check for a shallow clone before rebasing or force-pushing. git clone --depth=N implies --single-branch, which breaks --force-with-lease on every branch (it fails stale info, so people fall back to a bare --force) and, more quietly, makes git rebase main correct only while the merge base sits inside the shallow window.

stack: openspec-archived will be red until the change is implemented and archived. That is expected: archiving now would delete the spec before anything is built against it.

Where this sits

Each change is independently landable: one OpenSpec change, one PR, archived on merge. The archive gate requires it — a tip PR must leave openspec/changes/ empty — so nothing here is stacked and none of these depend on a shared branch.

PR Change Prerequisites
#70 knowledge prompt export none
#72 (this PR) Vale binary packages none
#73 partition rules by engine none
#71 Vale engine + engine-selection topic #73 (executes the vale/ directory it scaffolds) and #72 (needs a binary to resolve)

Only #71 has prerequisites. The other three can land in any order.

#70 and #71 are coupled by exactly one line: whichever lands second adds the engine-selection topic to TOPICS. Ordering between them doesn't matter.

Downstream, the generator's decision router (TSKL-279) needs a published release containing #70 and #71. It consumes a normal release — no prerelease, no path dependency — so it waits without blocking anything here.

Fixes OSS-22

thecodedrift and others added 5 commits July 29, 2026 12:04
Vale is a load-bearing engine, so its binary has to arrive the way
ast-grep's does. findSgBinary already resolves a platform package from
our own module context and execs beside it — there is simply no Vale
package to resolve. The one that exists downloads at postinstall,
which runs under the consumer's package-manager policy; pnpm 10 blocks
it by default, yielding no binary and no error.

So: per-platform packages published from this repo, binary in the
tarball, no bin, no code, no scripts — ast-grep's packaging without
ast-grep's installation, whose hardlink step already failed here under
pnpm dlx.

Versioned <valeVersion>-<yyyymmddhhmmss>, all-prerelease. The Vale
version stays legible, a packaging fix is a new timestamp on the same
base, and a caret range provably cannot resolve — exact pinning is
enforced by semver rather than convention.

Binaries are fetched at release time, never committed, and verified
against reviewed checksums. The workflow detects upstream releases
unattended but opens a PR rather than publishing, so nothing ships on
bytes nobody signed off on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDv57zHq7abms3RReSQw6q
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDv57zHq7abms3RReSQw6q
The reference table only documented TSKL-, which reads as though it's
the only bare identifier the integration understands. It isn't — OSS-23
linked and moved to In Review on PR creation for #69.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDv57zHq7abms3RReSQw6q
A `git clone --depth=N` implies --single-branch, which leaves the clone
with only main tracked. Three visible symptoms — force-with-lease fails
"stale info" on every branch, `push -u` can't store an upstream, and
`gh pr create` needs --head — but the one that matters is quiet: rebase
is only correct while the merge base is inside the shallow window, so
as main advances it can reconstruct the wrong base without saying so.

The force-with-lease breakage is worth calling out on its own, since
its failure mode is people reaching for a bare --force instead.

Both fixes are local settings; nothing is committed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDv57zHq7abms3RReSQw6q
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDv57zHq7abms3RReSQw6q
@thecodedrift
thecodedrift force-pushed the openspec/add-vale-binary-packages branch from ca0aab9 to fae0817 Compare July 29, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changeset PR intentionally ships no release note (bypasses the changeset requirement)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant