Skip to content

chore(vale): take Vale 3.19.0, re-measured - #226

Merged
theCodeDrift merged 3 commits into
mainfrom
vale/expect-3.19.0
Sep 1, 2026
Merged

theCodeDrift merged 3 commits into
mainfrom
vale/expect-3.19.0

Conversation

@theCodeDrift

@theCodeDrift theCodeDrift commented Aug 31, 2026 •

Copy link
Copy Markdown
Member

Everything that follows from #223 pinning the Vale manifest at 3.19.0. Now rebased onto main (the manifest commit dropped by patch-id, since #223 landed) and pinned to the published platform packages.

#223's digest was genuine. I downloaded vale_3.19.0_macOS_arm64.tar.gz from upstream and it hashed to exactly the a0e5f309… the manifest pins, then re-derived every claim we make about the binary against it.

What held

Every row of VALE_FORMAT_TIERS re-probed unchanged. src/generated/vale-vocabulary.ts regenerates byte-identical apart from its version string. The corpus differential, panic shapes included, still passes. A much quieter bump than 3.17.1 → 3.18.0, where eight rows moved in three directions.

What changed, which the table cannot report by construction

.ex/.exs gained comment and @doc extraction. Measured both ways: a bare simply = 1 line fires on 3.18.0 and is silent on 3.19.0, while a # comment fires on both. They leave the unnamed plaintext fallback for the comment tier, as two new rows.

Read the direction carefully. This is a narrowing: a rule matching [*.ex] was linting identifiers, atoms and string literals, and now sees comments only. Findings disappear, nothing errors, and nothing but a re-probe would have told us. agent update gains a ledger entry so a reader who notices a suspiciously clean run has somewhere to land.

MDX JSX children are now read as Markdown. .mdx stays markup, so the tier is blind to the change, but a Vale rule now covers prose inside <Steps> or <Aside> that it previously skipped, and those children carry the element name as a text.class.<name> scope. That family is already an open prefix in our schema, so scope: text.class.Aside validates today with no change.

sequence needs nothing. The new repeat feature lives inside a token entry, not at the check's top level, and our sequence arm only constrains that tokens exists and is a list. Probed and accepted.

Two latent bugs found on the way

Both recipes wrote ".mdx is supported as of Vale v%(VALE_VERSION)s" with the version interpolated. Native MDX arrived in 3.18.0, so raising the pin would have silently turned a true sentence into a false one in published agent guidance. Both now name the release that did it.

The full suite also passed once against a stale dist/, hiding reconcile-marker.test.ts, which asserts the engine version recorded into the rules marker. A rebuild reproduced it. Exactly the trap CLAUDE.md documents.

Now verified against the published binary

The branch was a draft because the vendor contract refuses to certify claims against a binary other than the pinned one, and the earlier measurements used an upstream download while the installed package was still 3.18.0. That refusal is the guard working.

release-vale.yml has since published 3.19.0-20260901000817; all six platform packages confirmed on npm, and the vendored binary now reports vale version 3.19.0. The pinned-version assertion and the two new .ex/.exs probes pass on the artifact a user will actually install.

1086/1086 tests, typecheck, lint, and pnpm cli check clean. The 4 no-hedging warnings in route.txt are pre-existing on main.

Refs #223

Base automatically changed from vale/update-3.19.0 to main September 1, 2026 00:08
Bumps VALE_VERSION to 3.19.0 and re-derives everything that is a claim
about the binary rather than about our code.

Every row of VALE_FORMAT_TIERS was re-probed against the 3.19.0 binary
and none moved; the generated vocabulary regenerates byte-identical
apart from its version string, and the corpus differential (panic shapes
included) still holds. What moved is what a table of existing rows
cannot report by construction:

- `.ex`/`.exs` gained comment and `@doc` extraction, so they leave the
  unnamed plaintext fallback for the comment tier. Measured both ways: a
  bare non-comment line fires on 3.18.0 and is silent on 3.19.0. This is
  a NARROWING, and a silent one, so `agent update` gains a ledger entry
  telling a reader why their Elixir findings disappeared.
- `.mdx` stays `markup` and changed underneath the tier: a JSX element's
  children are read as the Markdown they are, and carry the element name
  as a `text.class.<name>` scope. That family is already an open prefix
  in the schema, so it validates today.

Also fixes a latent bug in two recipes, which wrote "`.mdx` is supported
as of Vale v%(VALE_VERSION)s" with the version interpolated. Native MDX
arrived in 3.18.0, so raising the pin would have silently turned a true
sentence into a false one. Both now name the release that did it.
Bumps the six `@taskless/vale-*` pins from 3.18.0-20260824195610 to
3.19.0-20260901000817, the stamp release-vale.yml minted on the push to
main that merged #223.

This is the commit the rest of the branch was waiting on. Everything
else here was measured against a 3.19.0 binary fetched from upstream and
verified against the manifest digest; the vendor contract could not
agree, because the installed package was still 3.18.0 and the contract
refuses to certify a claim against a binary other than the pinned one.
That refusal is the guard working, and it is why this branch was a
draft.

The whole suite now runs against the published binary rather than a
hand-placed one: the pinned-version assertion and the two new `.ex`/
`.exs` probes pass on the artifact a user will actually install.
@theCodeDrift
theCodeDrift marked this pull request as ready for review September 1, 2026 00:15
@theCodeDrift

Copy link
Copy Markdown
Member Author

@claude /review

@claude

claude Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Claude finished @theCodeDrift's task in 4m 30s —— View job


Review complete

Review mode: incremental — read 0 prior review thread(s) before reviewing. .prior-review.json contained no review threads, reviews, or resolved/open comments (only the @claude /review trigger itself), so this is the first review of this PR.

Todo list

  • Read .prior-review.json (empty of prior review data — first review)
  • Fetch PR diff and metadata with gh pr diff / gh pr view
  • Run correctness angles (line-by-line, removed-behavior, cross-file)
  • Run cleanup angles (reuse, simplification, efficiency, altitude, conventions)
  • Verify candidate findings
  • Post inline comments for confirmed/plausible issues
  • Post final top-level summary

Assessment

This PR is almost entirely a re-measurement/re-pin: VALE_VERSION and the six @taskless/vale-* platform packages move from 3.18.0 to 3.19.0, VALE_FORMAT_TIERS gains two new comment-tier rows (.ex, .exs), the generated vocabulary and test fixtures follow, and several agent recipe files get corrected/expanded prose. I traced the cross-file consistency carefully (capabilities.ts → formats.ts, schemas/vale-rule.ts, vale-vendor-contract.test.ts, reconcile-marker.test.ts, the three agent/*.txt recipes) and the substantive claims check out:

  • .ex/.exs as comment tier is exercised automatically by the existing it.each([...VALE_COMMENT_EXTENSIONS]) suite once added to the table; the only manual addition needed was # in the comment() helper's HASH set, which the diff does correctly.
  • The text.class.<name> scope claim for MDX component children matches the already-open SCOPE_PREFIXES grammar in schemas/vale-rule.ts (isScopeOperand accepts any tail) — no schema change was needed, and none was made.
  • The two recipe edits that hardcode v3.18.0 instead of interpolating %(VALE_VERSION)s are deliberate and correct — they're describing when MDX support historically arrived (3.18.0), not the currently pinned version, so interpolating the current version there would have been the "latent bug" the PR description calls out.
  • update.txt's "Five things follow" count matches the five top-level bullets (Elixir, rewriter fix, Markdown-as-language, sg run --lang aliases, matching-semantics).

[New] One inline finding: packages/cli/src/rules/capabilities.ts:199 — the illustrative build-stamp in the VALE_VERSION docblock (3.18.0-20260824195610) is one version behind both the constant on the next line ("3.19.0") and this PR's own package pin (3.19.0-20260901000817). The diff touches this exact line and had the opportunity to fix it; it looks like a recurring one-version-behind pattern rather than something newly introduced. Doc-only, no behavioral impact.

Nothing else surfaced across correctness, removed-behavior, cross-file, reuse, simplification, efficiency, altitude, or CLAUDE.md-conventions passes — the diff is small, each changed fact is cross-referenced against a measured source (the vendor contract tests), and no test coverage or invariant was narrowed without a corresponding ledger/changeset entry.

Comment thread packages/cli/src/rules/capabilities.ts Outdated
Review feedback on #226.

The `VALE_VERSION` docblock illustrated the npm build stamp with a
literal, and this diff moved it from 3.17.1-... to 3.18.0-... while the
constant below it went to 3.19.0 and the package pins went to
3.19.0-20260901000817. So it shipped one release behind, which is the
second time: the prior state had the same off-by-one.

Twice makes it a class rather than an instance, so the literal is gone
and the docblock names the shape, `<valeVersion>-<yyyymmddhhmmss>`, and
where it is minted. A stamp that has to be hand-carried on every bump is
worse than no example, because it reads as the current pin and is not
one. `packages/cli/package.json` holds the real values, where a reader
sees all six at once and cannot be handed a stale one.
@theCodeDrift

Copy link
Copy Markdown
Member Author

Re: @claude[bot] — "Claude finished @theCodeDrift's task in 4m 30s … Review complete"
#226 (comment)

The one inline finding is fixed in c6f5927, and the part worth acting on was the observation attached to it rather than the instance.

Bumping the stamp to 3.19.0-20260901000817 would have moved the problem forward one release. Noting that the prior state had the same off-by-one is what turns it into a class: a literal that must be hand-carried on every bump is worse than no example, because it reads as the current pin and is not one. The docblock now names the shape and where it is minted; packages/cli/package.json holds the real values. I swept packages/cli/src for other hand-carried stamps and the only other hit is reconcile-marker.ts:34, which illustrates the nightly format for a string-comparison explanation and never claims to be a pin, so it stays.

Also useful to have the three deliberate-looking things confirmed independently rather than taken from the description: that the hardcoded v3.18.0 in the recipes is describing when MDX support arrived rather than the current pin, that .ex/.exs get exercised automatically by the existing it.each([...VALE_COMMENT_EXTENSIONS]) once in the table, and that text.class.<name> already validates against the open SCOPE_PREFIXES grammar with no schema change.

Still green after the fix: 1086/1086 tests, typecheck, lint, and pnpm cli check clean.

— AI Coding Agent

@theCodeDrift
theCodeDrift merged commit c0a1d3f into main Sep 1, 2026
3 checks passed
@theCodeDrift
theCodeDrift deleted the vale/expect-3.19.0 branch September 1, 2026 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant