extra-dev: add 32 dev recipes and update 11 more, for packages that install successfully - #3809
Merged
Merged
Conversation
JasonGross
force-pushed
the
dev-packages-batch
branch
from
August 1, 2026 17:52
e6b521e to
171b333
Compare
Member
Author
|
CI says:
|
JasonGross
force-pushed
the
dev-packages-batch
branch
from
August 6, 2026 04:41
171b333 to
35f66ca
Compare
JasonGross
marked this pull request as ready for review
August 6, 2026 04:51
These eleven packages have been renamed coq-* -> rocq-* in `released`, but
`extra-dev` still only carries the old coq-* name, so nothing in this archive
tracks their master branches under the name the release uses.
Each recipe is upstream's own in-tree `rocq-<name>.opam` from the default
branch, with the `version: "dev"` line dropped (the directory name supplies
it) and a `url` block appended. No constraint is relaxed or added.
Seven of them carry an upstream-authored version-scoped conflict on the coq-*
name already. The other four -- aac-tactics, libhyps, mathcomp-real-closed
and relation-algebra -- get a blanket `conflicts: ["coq-<name>"]`, because the
coq-* dev recipe already in this archive builds the same sources and installs
to the same logpath, so the two cannot be installed together. A later commit
on this branch turns those coq-<name>.dev recipes into pure compatibility
shims (`depends: ["rocq-<name>" {= version}]`) and narrows the four blanket
conflicts to `{!= version}` accordingly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
Seven packages from DmxLarchey, released at 2.2 with `coq >= 9.2.0 < 9.3~`. coq-kruskal-trees has seven released reverse-dependencies, so it is the largest hub in the archive with no dev version at all. Recipes are upstream's in-tree opam files at the default branch, with `version:` dropped and a git `url` added. Three of them carried a stale `coq < "8.21~"` upper bound; since opam orders the version string `dev` above any numeric version, an upper bound of that shape makes a .dev recipe unselectable on a dev switch, so it is dropped. Lower bounds are untouched. The mis-cased `name:` fields (`name: "Coq-Kruskal-Trees"`) are dropped rather than corrected -- the directory already names the package. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
coq-hol-light-real-with-N and coq-hol-light-real-with-nat export HOL Light's real-number development to Rocq. Both are recent (`rocq-prover >= 9.0`, no upper bound), so the dev recipes carry upstream's constraints verbatim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
Two packages from the Peregrine extraction stack. Both sit on top of
MetaRocq, which already has a dev in extra-dev, and both are capped at
`< 9.2~` in their latest release, so nothing in this stack currently tracks
Rocq master.
The `< 9.2~` upper bounds on rocq-core/rocq-stdlib are dropped for the reason
described in the Kruskal commit; the `{= version}` bounds tying the family
together are kept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
Upstream has renamed this package from coq-pil to rocq-pil: hferee/rocq-pil ships both coq-pil.opam and rocq-pil.opam. The archive still only knows the coq-* name, and only as a release. It installs the same logpath as its coq-* twin, and upstream ships no compatibility shim package the way math-comp/analysis does, so it declares `conflicts: ["coq-pil"]`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
Ten more packages with a live release and no dev version anywhere in the
archive. Recipes come from upstream's in-tree opam file at the default
branch, except for coq-bedrock2-compiler, whose repository ships no opam file
at all -- that one is derived from the latest released recipe with the tarball
`url` replaced by a git one.
Notes on individual packages:
* rocq-listz is on gitlab.inria.fr.
* rocq-induction and strict-order-solver were missing `dev-repo:`; it is
filled in from the homepage.
* coq-ordinal's license was spelled "MIT License"; normalised to the
SPDX "MIT".
Upper bounds on coq/rocq-core/rocq-stdlib are dropped where present, as in the
earlier commits. coq-record-update already spells its bound `... | = "dev"`
and is left alone.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
… shims
Twelve packages have been renamed coq-* -> rocq-* upstream. Until now the
rocq-* dev recipe and the coq-* dev recipe both built the same sources into
the same logpath, so the rocq-* side had to declare a blanket conflict on the
coq-* side and the two could never be co-installed.
Replace each `coq-<name>.dev` with a metadata-only compatibility package,
depends: [ "rocq-<name>" { = version } ]
which is the shape `coq-mathcomp-finmap.dev`, `coq-mathcomp-bigenough.dev`
and `coq-hierarchy-builder.dev` already use in this archive. Eight of them --
the math-comp/analysis family -- are upstream's own in-tree `coq-<name>.opam`
shim verbatim, minus the `version:` line (the directory name supplies it); the
other four (aac-tactics, libhyps, pil, relation-algebra) ship no shim upstream
and are synthesised from the metadata of the rocq-* recipe. `coq-pil.dev` did
not exist at all and is new.
One small departure from the upstream text, to keep `opam lint` quiet:
`authors` is carried over to the multinomials and real-closed shims, which
omit it upstream.
The five blanket `conflicts: [ "coq-<name>" ]` added earlier in this branch
become `conflicts: [ "coq-<name>" { != version } ]`, so that they still
exclude the released coq-* builds but admit the shim. The seven that carry an
upstream-authored version-scoped conflict already had this property and are
untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
JasonGross
force-pushed
the
dev-packages-batch
branch
from
August 6, 2026 05:19
35f66ca to
3b3d471
Compare
Fourteen .dev recipes in this PR let the solver select a released prover
instead of rocq master. This is not hypothetical: in job 7709746 every
package touched here was BUILT rather than skipped on the ocaml-4.09 job,
which rocq-runtime.dev cannot satisfy (it requires ocaml >= 4.14.0). A
build there is proof that some older prover was chosen.
Three shapes of defect, all fixed by naming the prover exactly:
* a bare lower bound ("coq" {>= "8.14"}) excludes nothing old, so the
4.09 solver walks back to whatever ancient release still resolves;
* "rocq-prover" {>= "9.0"} is vacuous, because the metapackage's own
version is the letters "meta.1", which outrank every numeric version.
Worse, going through the metapackage removes all constraints on
rocq-core. Its whole content is rocq-core + rocq-stdlib, so naming
both directly is exact, not a narrowing;
* no prover dependency at all, reaching a bounded sibling only through
UNVERSIONED deps, so a released sibling can be selected and drag an
old prover back in (the four Kruskal recipes).
Where the recipe already depended on "coq", the pin is written "coq"
{= "dev"} rather than switching to rocq-core. The shim chain is
coq.dev -> coq-core {= version} -> rocq-runtime {= version}, so this pins
rocq master exactly as rocq-core {= "dev"} would, while keeping the
coqc-providing compatibility binaries these legacy build systems invoke.
A pinned rocq-core {= "dev"} also pins rocq-stdlib transitively: released
rocq-stdlib.9.0+rc1 requires rocq-core {>= "9.0" & < "9.1~"}, which dev
violates. A bare companion "rocq-stdlib" beside a dev pin is therefore
not a hole and is left alone.
Effect on CI: these packages stop building on ocaml-4.09 and become
honest per-compiler skips, which is the correct signal for a dev recipe.
Any green they produced there was about a prover this PR is not adding
support for.
Left unfixed, deliberately: three recipes carry generated/mirrored
headers (coq-record-update.dev and rocq-mathcomp-multinomials.dev from
meta.yml, rocq-libhyps.dev from the released archive recipe).
coq-record-update.dev was already safe. rocq-libhyps.dev IS edited here
despite its marker, because it mirrors a released archive recipe rather
than an upstream generated file, and a .dev recipe legitimately diverges
from the released one on exactly this axis.
Also left unfixed: twelve recipes whose prover bound can still select an
old prover but which were SKIPPED, not built, on 4.09 (one of them,
rocq-mathcomp-multinomials.dev, is also in the generated list above).
They already behave correctly; changing them would be an unmeasured edit.
The archive's seven stale core-dev tarball checksums (invalidated when
the coq/coq -> rocq-prover/rocq rename changed the directory name inside
the generated /archive/refs/tags/ tarballs) are an independent defect and
are NOT fixed here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
Every recipe this PR adds to or touches in extra-dev exists to test a
package's development branch against Rocq's development branch. Most of
them constrained the prover with a bare floor instead -- "coq" {>= "8.14"},
"rocq-core" {>= "9.0"}, and so on. A bare floor is satisfied by every
released prover as well as by dev, so when dev is unavailable the solver
walks backward instead of reporting that there is nothing to test. That
is not hypothetical: on the ocaml-4.09 job rocq-pil.dev resolved coq
8.20.dev, coq-stdpp 1.12.0 and coq-equations 1.3.1+8.20, and coq-pil.dev
then pulled that in through its shim. Five recipes failed on that job for
no reason other than having been built against a prover they do not target.
Constrain each prover dependency to {= "dev"}. On the compilers that
matter this changes nothing -- the retry plans on the 4.09 job already show
the solver choosing rocq-core dev for these recipes once the compiler is
free. What changes is that 4.09 stops manufacturing failures and reports
an honest per-compiler skip.
Two recipes needed more than a bound:
* coq-hol-light-real-with-{N,nat} asked for "rocq-prover" {>= "9.0"}.
That bound is vacuous -- opam sorts letters above digits, so the
metapackage version meta.1 satisfies it -- and core-dev carries no
rocq-prover.dev at all, only 9.3.dev. Replaced with rocq-core and
rocq-stdlib at dev.
* rocq-pil asked for coq-stdpp {>= "1.11.0"}, and every coq-stdpp in the
archive caps coq below 8.21~, which is what dragged it back to Coq
8.20. Only rocq-stdpp 1.13.0 admits a dev prover, so the dependency
moves to the rocq- twins. The logical paths (stdpp, Equations) are
unchanged by that rename.
rocq-cakeml-extraction is deliberately left loose. It pins
rocq-metarocq-erasure-plugin {>= "1.4" & < "1.5.2"}, and
rocq-metarocq-utils 1.5.1+9.2 requires rocq-core {>= "9.2~" & < "9.3~"},
so pinning its prover to dev would make it uninstallable rather than
testable. Raising that MetaRocq bound is a claim about whether
cakeml-backend master builds against MetaRocq master, which is not settled
here.
The compatibility shims -- coq-aac-tactics, coq-libhyps, coq-pil,
coq-relation-algebra and the coq-mathcomp-* family -- are untouched. They
carry no prover dependency of their own; the constraint belongs on the
rocq- twin they pin with {= version}, and that twin now has it.
This is unrelated to the archive's seven stale core-dev +rc1 checksums,
which are an independent defect and are not fixed here. These recipes
should name dev because dev is what they are for, not as a way around a
checksum.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
Two corrections to the commit before this one. coq-record-update.dev and rocq-mathcomp-multinomials.dev both open with # This file was generated from `meta.yml`, please do not edit manually. # Follow the instructions on https://github.com/coq-community/templates so their bounds belong in the upstream meta.yml, not here. Reverted. Both can still select a released prover -- coq-record-update.dev admits coq-core 8.17 through 9.2, rocq-mathcomp-multinomials.dev admits any rocq-core >= 9.0 -- and that is now a reported finding rather than a local edit. The check that missed them grepped for the dune marker ("generated by dune") and read its own silence as "no generated files", which is the same failure shape as a bound that admits everything. The rest of the revert drops constraints that were never in scope. A companion "rocq-stdlib" or "coq-stdlib" beside a dev-pinned rocq-core or coq-core cannot select a released stdlib: rocq-stdlib 9.0+rc1 requires rocq-core {>= "9.0" & < "9.1~"} and rocq-stdlib 9.2.0 requires {>= "9.1" & < "9.4~"}, and dev satisfies neither. Pinning those companions changed no solution, so they are restored to what they were. Same for the unconstrained "rocq-core" beside a dev-pinned rocq-runtime in rocq-induction, and the unconstrained "coq-core" in the coq-mathcomp-classical shim, whose prover constraint reaches it through the rocq- twin it pins with {= version}. What remains from that commit is twelve recipes, each with exactly one binding prover constraint moved to {= "dev"}, plus rocq-pil's move to the rocq- stdpp and Equations packages, which was needed because every coq-stdpp in the archive caps coq below 8.21~. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
The recipe depended on "rocq-stdlib" {= "dev"} and named no rocq-core at
all. A dev-pinned stdlib does not pin the core: rocq-stdlib.dev's own
bound is
"rocq-core" {>= "9.2" | = "dev"}
which is a disjunction, and core-dev supplies four numeric versions
satisfying its first branch -- 9.2.dev, 9.2+rc2, 9.3.dev, 9.3+rc1 -- any
of which the solver may take instead of master.
So the recipe was BOUNDED but not PINNED. That is still a real
improvement on what it replaced (a "coq" {< "8.21~"} branch admitting any
ancient coq: the floor moved from Coq 8.20 to 9.2), which is why this was
easy to miss -- the direction of travel was right and the destination was
not reached. But a green on it would have been evidence about 9.2/9.3,
not about rocq master.
The closure argument used elsewhere in this batch runs core -> stdlib: pin
rocq-core {= "dev"} and every released rocq-stdlib is excluded by its own
cap on rocq-core. It does NOT run stdlib -> core, because rocq-stdlib.dev
constrains rocq-core with a disjunction rather than an equality. Pinning
the stdlib alone therefore closes nothing, and this was the only recipe in
the changed set with that shape.
Also correcting the wording of a claim in e3a41f1, which cannot be
amended: it says "every coq-stdpp in the archive caps coq below 8.21~".
That is false for coq-stdpp 1.11.0, which caps at < "9.1~"; only 1.12.0
uses 8.21~. The conclusion it supports is unaffected -- every coq-stdpp
cap is an upper bound and dev exceeds every numeric version, so no
coq-stdpp in the archive admits a dev prover, and rocq-pil still had to
move to the rocq- twins.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
This PR's contract is "dev recipes for packages that install successfully"; coq-pil.dev and rocq-pil.dev are the only two rows that fail its own dev legs, on both compilers, and they fail for a source reason no recipe edit can reach: stdpp 1.13 repurposed multiplicity_singleton, so pil's proofs need porting first. They already exist on the needs-ports branch, which is where the split's own definition puts them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Undrafted, and narrowed to the 45 recipes whose packages actually install
against Rocq master.
This started as one 88-recipe batch. Its pipeline gave a clean per-package,
per-compiler verdict, so it is now split in two: this PR keeps the 45 that
install, and #3812 carries the 43 that do not. #3812 is stacked on this
one. The recipes are the ones from the original batch; four commits on top
tighten prover bounds that were loose enough to resolve a released prover, so
that a green here means what it says. Those edits are described under
How the recipes were written below.
CI evidence
Read off the three
opam-buildjobs of the pipeline on the original 88-recipehead (
171b3335), per package rather than per job:coq-pil,rocq-pilRead the first row as "installed", not as "installed against master": the 4.09.0
column carries no information about Rocq master at all, for the reason set out
under Read the 4.14.2 and 5.3.0 jobs below. The 15 is a three-compiler
portability result; the dev result is the 4.14.2 and 5.3.0 columns alone.
The 28 skips are
Skipping ... since not installable with the current compiler:rocq-runtime.9.0.devallowsocaml >= 4.09.0but 9.1, 9.2, 9.3 anddevall require>= 4.14.0, so the 4.09.0 job's solver can only reachrocq-core 9.0.dev, which the mathcomp-analysis family's lower boundsexclude. A skip is a pass as far as the archive gate is concerned.
The pil pair is the only qualification.
coq-pilinstalled on 4.09.0 androcq-pilon 4.09.0 and 5.3.0; their remaining jobs died fetching adependency's sources, not building anything:
That is GitLab rate-limiting the runner. No other package in this PR appears
in any job's
Packages that failed to install:line, and none appears in anyPackages that can never be installed:line — every package that did is in#3812.
The 4.09.0 job at
3b3d471was red, for a defect that predates this PRThis section describes pipeline 1457864, which ran on
3b3d471— before thefour prover-bound commits now at the head of this branch. Those commits were
written to fix exactly what it found, so the pipeline on the current head is the
test of the fix, not a repeat of this. Left in because the diagnosis is what
motivates the commits.
Job 7709746 exits 1 with five names:
All five are in this PR, and none of them failed on its own sources. There
are zero occurrences of
[ERROR] The compilation ofin the job's 615 KB log.Every one died fetching a dependency's tarball — four on
coq.8.16+rc1andone on the same
coq-stdpprate-limit as above:Only the
429will clear on a retry — but all five failures have the samecause, and it is not the tarballs. None of the five recipes constrains its
prover toward
dev:coq-kruskal-{fan,veldman}andcoq-pildeclare noprover dependency at all, and
coq-kruskal-finiteandcoq-ordinaldeclareonly a bare floor (
"coq" {>= "8.14"}and{>= "8.9"}) with no ceiling. On4.09 that lets the solver walk back far enough to reach a broken artifact —
four of them landed on
coq.8.16+rc1andcoq-pilstopped atcoq 8.20.devand died fetching
coq-stdppinstead. Classifying these by error messagescatters one defect across two buckets.
The four checksum failures are also deterministic and will recur on every
pipeline until the archive is fixed, and they are not this PR's doing. GitHub
names the top-level directory inside an auto-generated
/archive/tarball afterthe repository's current name, and
coq/coqnow redirects torocq-prover/rocq:Same tag, same commit, same files — but the archive now unpacks to
rocq-8.16-rc1/where the recorded sha512 was taken overcoq-8.16-rc1/.Both affected tags were measured, byte-identical across two fetches each:
Thirty-two recipes archive-wide are affected, across sixteen distinct
tarballs — every
core-devrecipe fetching a generatedcoq/coqarchive, notonly the
+rc1ones. 36 recipes over 19 tarballs are candidates; 32 over 16 werestill stale when measured, and the remaining 4 had already been repaired
upstream. The defect also reaches md5 recipes (the 8.5–8.10 betas), so a
sha512-shaped search undercounts it a second way:
The
/archive/<TAG>.tar.gzand/archive/refs/tags/<TAG>.tar.gzspellings arethe same generated endpoint and break identically; searching only for the latter
is what produces the appealing but wrong answer that seven recipes and two URLs
are involved.
The defect is roughly six months old, not new. Four recipes were already
repaired upstream on 2026-02-21 (
db5a6c07e,5cb9e6e56,c71643346,325bb876d, each titledfix(coq.8.N+betaM): camlp5 version and MD5). A cheapno-network tell for that piecemeal repair:
coq.8.8+beta1andcoqide.8.8+beta1share one URL but recorded different md5s, because only the first had been
fixed. So the fact that pipeline 1455710 (2026-08-01) shows zero occurrences and
1457864 shows four dates the exposure — most likely a source-cache eviction —
and not the defect.
Almost all of the 32 are latent, because a recipe has to actually be fetched to
fail: the four observed failures measure which recipes this solver happened to
reach, not the size of the defect. Released versions are structurally immune —
they use release assets, immutable uploads rather than generated archives.
This PR touches none of the 32.
Read the 4.14.2 and 5.3.0 jobs, not the 4.09.0 one
That 4.09.0 job would be weak evidence about Rocq master even if it were green.
rocq-core.devrequires OCaml >= 4.14, so on 4.09 the solver does not skip —it walks backward to whatever ancient prover a recipe's bounds still admit.
Taking the resolved
- install {coq,rocq-core} <version>line out of eachCheck if <pkg> is installablesection of job 7709746, and pairing every planwith a check for that section's
Skipping …line:Not one of the 45 packages was built against Rocq master on this job. The 17
that were built resolved
coq 8.16+rc1,8.16.dev,8.20.devorrocq-core 9.0.dev; the other 28 were never built at all. A green here means"builds against Coq 8.16", not "builds against Rocq master".
The pairing matters because a skipped section still prints a plan — the
opam install --show-action --update-invariantretry, which is allowed tochange the compiler and so routinely shows
rocq-core devfor a package thatwas never compiled. Read without that check, this job appears to test 27
packages against master. It tests none.
The same audit on 4.14.2 (7709747) and 5.3.0 (7709748) resolves
devforevery section either job has reached, with none skipped and none walked back
— 15 and 15 as of the latest sample, including the whole Kruskal family. Both
jobs are still running, so the counts are lower bounds and will rise; what does
not change with more sections is the part that matters, that no section on
either job resolved anything other than
dev. Final counts go in when the jobsare terminal. These are the two jobs that carry the evidence for this PR.
Three of them were not actually tested against master
(Also read off the terminal 88-recipe run at
171b3335, not off the livepipeline audited in the two sections above.)
Worth stating plainly, because it is the thing a
.devrecipe is for. I pulledthe resolved
rocq-coreversion out of every per-package section rather thantrusting the job name, and three packages here never had Rocq master in their
install plan on any compiler:
coq-pilandrocq-pilresolvedrocq-core 8.20.dev, androcq-cakeml-extractionresolved9.2.dev. Sevenmore resolved an older line on the 4.09.0 job only and
devon the other two,which is enough. So the honest count is 42 verified against master, 3
installed against an older Rocq.
None of the three declares an upper bound on
rocq-core— the cap istransitive, and visible in the install plans:
rocq-cakeml-extractionasks forrocq-metarocq-erasure-plugin {>= "1.4" & < "1.5.2"}, and the release thatsatisfies it is built for the 9.2 line. The pil recipes depend on the legacy
coqpackage rather thanrocq-core, and land oncoq 8.20.devnext tocoq-equations 1.3.1+8.20. A.devrecipe whose transitiveclosure caps
rocq-coreis silent about master whether it goes green or red,so these three are recipes that exist and lint but do not yet produce the
signal they are for.
Two of the three are addressed by the bound commits, one is not:
coq-pil/rocq-pilreachedcoq 8.20.devthrough their own loosecoqfloor, so the fix is local. Both are edited here (see Renames below);rocq-pilneeded the rename rather than a tightening, because every archivecoq-stdppcapscoqbelow dev. This is a prediction, not a measurement— the 42/3 count above was read off
171b3335, which predates these commits,and only the next pipeline can confirm the walk-back is gone.
rocq-cakeml-extractionis not fixed and is deliberately left alone. Itscap is transitive, through
rocq-metarocq-erasure-plugin {>= "1.4" & < "1.5.2"},whose satisfying release is built for the 9.2 line; pinning the prover to dev
here would make the recipe uninstallable rather than correct. Fixing it means
moving the dependency's bound, which is upstream of this PR. Its green is
real, and it is 9.2 evidence.
#3812 has the same section — 14 of the 43 red ones are red against 9.1, 9.0 or
8.20, not against master.
And one of them installs with a feature switched off
rocq-relation-algebra.devis green against master, but only because CI neverinstalls a depopt. The recipe declares
and upstream's
configureresponds to--enable-ssrby appendingtheories/fhrel.vto_RocqProject— a file_RocqProjectships commentedout. So the package compiles more code whenever mathcomp happens to be in the
same switch. Its install plan on 5.3.0 is ten packages ending
rocq-core dev/rocq-stdlib dev, with no mathcomp and no aac-tactics, andacross all 88 per-package sections of the pipeline no plan co-installs
relation-algebra with mathcomp — its three consumers here (
rocq-sims,coq-atbr,rocq-ctree) pull neither. Every green it has is a--disable-ssr --disable-aacgreen.In a switch that does have mathcomp installed,
--enable-ssris passed and theextra file fails on Rocq dev, identically at
1.9.0and at master (2d2af36):This is not a Rocq-dev breakage, and
fhrel.vhas at least three independentones. All of the following was executed, not inferred.
The mathcomp hedge is void, not merely narrow.
fhrel.vimports onlyboot/modules, and
boot/'s tree SHA is identical at tagmathcomp-2.6.0and at78cb0653(the commit a dev pin resolves): both8d9a278e093947a1a496bca0e86012e5bd7cdcd4. (Positive control that the diff islive:
algebra/differs by 19 files.) So this already was released-mathcompevidence. Rebuilding mathcomp 2.6.0
boot/from source against 9.4+alphaconfirms it — 25/25
.vo, 0 errors, andfhrel.vthen fails byte-identically,with the loadpath verified by probe rather than assumed.
The clashing notation is relation-algebra's own, and it is not new. Rocq's
[ ! _ ]lives intheories/Corelib/ssr/ssreflect_rw.v:628and has since312497af6a(2023-12-06). relation-algebra added a conflicting spelling atkat.v:27on 2026-01-07 (6b326b9, "Adapt to rocq-prover/rocq#21478")without a level annotation. Reproduced with the real
kat.vand no mathcompat all, and on 9.0.0, 9.1.1, 9.2+rc2 and 9.4+alpha alike; reversing the
require order fails symmetrically, so it is not an ordering artefact. Present at
both
1.8.1and1.9.0, so no version pin dodges it. One-line fix, verified:add
(at level 0, p at level 200).Behind it sits a genuine Rocq change — but a released 9.3 one. With the
notation fixed,
fhrel.v:39fails onDefinition fhrel_of of phant A & phant B := fhrel_type.withSyntax error: [def_body] expected after [ident_decl]. Reservingof(rocq #21611,
e6a2fb9b2f,git tag --contains→ V9.3+rc1) removed thessr plugin's
of/&extension ofdef_body. Version-bracketed probe onDefinition foo of nat & bool := 0.: rc=0 on 9.0.0 / 9.1.1 / 9.2+rc2, rc=1 on9.4+alpha. This will hit any contrib using the mathcomp phantom-type idiom,
and it is intentional and changelogged — worth knowing well beyond this package.
A third failure follows at
fhrel.v:288(The LHS of eq_cardT #|_| does not match any subterm of the goal), against released mathcomp 2.6.0, unresolved.Nobody has ever built this file. Upstream CI (
build-relation-algebra.yml,docker-coq-action with
opam_file:) installsdepends:but notdepopts:, soupstream builds
--disable-ssrtoo.--enable-ssrhas been broken for monthson every supported Rocq, and no CI anywhere exercises it.
--enable-aacremains simply unmeasured:coq-aac-tactics.devis green in thissame batch, so the combination is installable, and nobody has built it.
I am leaving the package here — its verdict under the closure CI actually solves
is green, and a depopt-off green is an honest result. But the general point is
now sharper than "weaker for this one": a depopt-gated green is silent about
code the recipe compiles only when the optional dependency is present, and that
silence can hide breakage that predates the version under test by months and
belongs to a third party. Same shape as a transitively-capped plan being silent
about master whatever colour it comes out.
How the set was chosen
rocq-devsees five repositories (iris-dev,coq-released,rocq-core-dev,rocq-extra-dev,default). Taking the exact set difference between thereleased package names and the names that have any dev version in any of
them —
iris-devversions aredev.<date>.<n>.<sha>, so a.devsuffix testmisses all 35 of them — leaves 322 released packages with no dev at all.
Filtering that down:
coq-Xwhoserocq-Xtwin is also releasedThe three subtractions:
coq-wasmis #3693,rocq-certirocqis #3807, andcoq-sailno longer exists upstream —rems-project/coq-sailmain ships onlyrocq-sail-stdpp.opam, which is #3800.How the recipes were written
Each is upstream's own in-tree
opamfile at the default branch, withversion:dropped andurl { src: "git+<repo>#<branch>" }appended. Of the 45here, only
coq-bedrock2-compilercomes from a repository that ships no opamfile (
mit-plv/bedrock2); it is derived from the latest released recipe withthe tarball
urlswapped for a git one.One deliberate edit, in two steps: each recipe's binding prover constraint is
pinned to
{= "dev"}.The first step was to drop upper bounds on
coq/coq-core/coq-stdlib/rocq-core/rocq-runtime/rocq-stdlib. opam orders the version stringdevabove any numeric version, so a recipe carrying< "9.2~"can never beselected on a dev switch — it would be a
.devpackage that no dev switch caninstall.
That was necessary and not sufficient, and the ocaml-4.09 job showed why:
removing the ceiling leaves the floor, and an unbounded-above floor like
coq {>= "8.14"}lets the solver walk backward to Coq 8.16 — which thenfails on an unrelated defect, the archive's stale
core-devtarball checksums. A recipe that resolves Coq 8.16 is not testing dev at all,so "no upper bound" is not the safety property;
{= "dev"}is. 25 recipes arenow pinned, listed in the commit messages.
Where the prover dependency is spelled
coqrather thanrocq-core, the boundis tightened in place rather than renamed:
coq-coreis still the packagethat ships
coq_makefile, which those recipes'build:invokes, and the shimchain
coq.dev → coq-core {= version} → rocq-runtime {= version}pins rocqmaster exactly as
rocq-core {= "dev"}would. Renaming would convert a solverproblem into a build problem.
Three recipes are the exception, and each is renamed for a stated reason:
rocq-pil.dev—coq→rocq-core,coq-stdpp→rocq-stdpp,coq-equations→rocq-equations. Here tightening in place is unsatisfiable:every
coq-stdppin the archive capscoq(1.12.0 at< "8.21~", 1.11.0 at< "9.1~") and there is nocoq-stdpp.dev, socoq {= "dev"}alongside ithas no solution — it would turn a walk-back into a package that can never be
installed, which is worse.
rocq-stdpp.1.13.0is the only stdpp admitting adev prover. This recipe builds with dune and never invokes
coq_makefile, soit does not need the compat binaries. On the 4.09 job it resolved
coq 8.20.dev,coq-stdpp 1.12.0,coq-equations 1.3.1+8.20.coq-hol-light-real-with-N.devand-with-nat.dev—rocq-prover→rocq-core+rocq-stdlib. A bound on therocq-provermetapackage isvacuous and routes around every constraint on
rocq-core: its version ismeta.1, which opam orders above any numeric version. The 4.14 job's plan forthese two shows the metapackage contributing nothing but indirection —
rocq-runtime dev,rocq-core dev,rocq-stdlib dev,rocq-prover meta.1,with no
coqorcoq-coreanywhere — so the renamed dependency set isprecisely the set that was already being installed.
One asymmetry is worth stating, since it explains why several recipes pin the
core and leave the stdlib loose: the closure runs core → stdlib and not
stdlib → core.
rocq-core {= "dev"}excludes every releasedrocq-stdlib,because each caps
rocq-core(< "9.1~",< "9.4~") anddevfails both — soa bare companion
rocq-stdlibbeside a dev-pinned core is not a hole. Thereverse does not hold:
rocq-stdlib.devconstrains the core with a disjunction,rocq-core {>= "9.2" | = "dev"}, whose numeric branch fourcore-devversionssatisfy. Pinning the stdlib alone therefore closes nothing.
13 of these greens are against released mathcomp, not mathcomp master
Worth stating explicitly, because the package names all end in
.devand invitethe opposite reading. Thirteen packages in this PR install under a dev prover
but against released mathcomp 2.6.0:
coq-androcq-× {mathcomp-analysis,mathcomp-analysis-stdlib,mathcomp-classical,mathcomp-experimental-reals,mathcomp-reals,mathcomp-reals-stdlib}, pluscoq-mathcomp-word.dev.Identically on 4.14.2 and 5.3.0.
This is not a solver preference — mathcomp
devwas never permitted. Oneceiling drives twelve of the thirteen:
devsorts above2.7~, so the release is the only candidate, and{= version}locks propagate it across the monorepo split (algebra → order, finite-group → boot;ssreflect.devneedsbootandorderat dev, acontradiction, so it too takes 2.6.0). The whole analysis family then funnels
into classical by
{= version}. The thirteenth is independent —coq-mathcomp-word.dev's owncoq-mathcomp-ssreflect {(>= "2.4" & < "2.7~")}.The control that distinguishes "not permitted" from "not preferred": in the
same plans, every mathcomp package carrying no ceiling —
finmap,bigenough,reals,analysis— resolveddev. And mathcomp 2.6.0 can sitbeside a dev prover at all because it is the first release to drop the cap:
rocq-mathcomp-boot.2.5.0hasrocq-core {>= "9.0" & < "9.2~"},2.6.0hasrocq-core {>= "9.0"}.These remain real greens for the claim this PR makes — the prover is master.
They are simply silent about mathcomp master. Widening those ceilings is
deliberately not in this PR: permitting dev would make the solver select it
(per the control above), so the next run would test analysis-at-master against
mathcomp-at-master, a configuration nothing in this dataset has ever exercised.
That change belongs in #3812, where an untested configuration is the point.
Six packages here did exercise mathcomp
dev:coq-/rocq-mathcomp-multinomials,coq-/rocq-mathcomp-real-closed,coq-graph-theory,coq-graph-theory-planar.Lower bounds on non-prover dependencies are untouched. Two recipes are
deliberately left unedited and are still unsafe:
coq-record-update.dev(
coq-core {(>= "8.17" & < "9.3") | (= "dev")}, which admits 8.17–9.2 and onthe 4.09 job selected
coq-core 8.20.dev) androcq-mathcomp-multinomials.dev(
rocq-core {>= "9.0"}). Both files carry the header "This file was generatedfrom
meta.yml, please do not edit manually", so the fix belongs upstream inthe generator, not here. Flagging rather than fixing them is the deliberate
choice; a disjunction that merely permits
devis a menu, not a pin, and thesolver is free to take the numeric branch.
Renames and conflicts
Renaming only ever goes coq- → rocq-, never the other way.
Twelve packages here have been renamed upstream —
aac-tactics,libhyps,pil,relation-algebra, and the eight mathcomp-analysis packages — and arereleased under
rocq-*whileextra-devhad onlycoq-*. Two recipes for thesame logpath cannot coexist, so the last commit gives all twelve the
arrangement this archive already uses for
coq-mathcomp-finmap,coq-mathcomp-bigenoughandcoq-hierarchy-builder:coq-X.devbecomes ametadata-only compatibility package whose whole content is
depends: ["rocq-X" {= version}], androcq-X.devdeclaresconflicts: ["coq-X" {!= version}]— which still excludes the releasedcoq-Xbuilds but admits the shim.Eight of the shims (the math-comp/analysis family) are upstream's own in-tree
coq-X.opamverbatim, minus theversion:line. The other four(aac-tactics, libhyps, pil, relation-algebra) ship none upstream and are
synthesised from the
rocq-Xmetadata;coq-pil.devdid not exist here at alland is new. Five blanket
conflicts: ["coq-X"]added earlier in the branch arenarrowed to
{!= version}by that commit; the seven whose upstream filealready carries a version-scoped conflict (
{< "1.16~"},{<= "2.4.0"}) areuntouched, since those already admit a
devshim.Also verified
Every recipe passes
opam lint --warn=-21 --check-upstream, the exact checkscripts/opam-coq-lintruns. Every git URL and branch was resolved against theforge.
Three small drive-by fixes, all flagged by lint:
dev-repo:filled in forrocq-inductionandstrict-order-solver;coq-ordinal's license normalisedfrom
"MIT License"to the SPDX"MIT"; and the mis-casedname: "Coq-Kruskal-Trees"fields dropped (the directory already names thepackage).
One correction to what this PR said before the split: it claimed every
{= version}dependency resolved to a package with a dev recipe. That waswrong —
rocq-typed-extraction{,-plugin}.devdepend onrocq-elm-extraction {= version}androcq-rust-extraction {= version},neither of which had a dev recipe anywhere, so both were unsatisfiable on all
three compilers. All four packages are in #3812, whose last commit adds the two
missing recipes.
🤖 Generated with Claude Code
https://claude.ai/code/session_01L9BGQT7XUuubV6C619DW4b