build checks.x86_64-linux.formatter

  1. 0.01 s $ /nix/store/vzx1mi9c0xfadmsm9dhd83d005cb1qs9-coreutils-9.8/bin/timeout --kill-after=15s 1800s /nix/store/99b1z08awpxj8b6mzggn59gp1shljnff-nix-2.34.5/bin/nix --extra-experimental-features nix-command --extra-experimental-features flakes --log-format raw-with-logs build --no-link git+https://github.com/sellout/flaky?ref=docs&rev=4a8309e741979c6a4858f9996b66b238a7abb8c0#checks.x86_64-linux.formatter --print-build-logs
  2. 0.07 s warning: ignoring untrusted flake configuration setting 'allow-import-from-derivation'.
  3. 0.07 s Pass '--accept-flake-config' to trust it
  4. 0.07 s warning: ignoring untrusted flake configuration setting 'extra-experimental-features'.
  5. 0.07 s Pass '--accept-flake-config' to trust it
  6. 0.07 s warning: ignoring untrusted flake configuration setting 'extra-substituters'.
  7. 0.07 s Pass '--accept-flake-config' to trust it
  8. 0.07 s warning: ignoring untrusted flake configuration setting 'extra-trusted-public-keys'.
  9. 0.07 s Pass '--accept-flake-config' to trust it
  10. 0.07 s warning: ignoring untrusted flake configuration setting 'sandbox'.
  11. 0.07 s Pass '--accept-flake-config' to trust it
  12. 0.07 s warning: ignoring untrusted flake configuration setting 'use-registries'.
  13. 0.07 s Pass '--accept-flake-config' to trust it
  14. 0.68 s treefmt v2.4.0traversed 66 files
  15. 0.68 s emitted 52 files for processing
  16. 0.68 s formatted 52 files (4 changed) in 340ms
  17. 0.70 s M docs/CONTRIBUTING.md
  18. 0.70 s M docs/CONTRIBUTING/haskell.md
  19. 0.70 s M docs/haskell-release-process.md
  20. 0.70 s M docs/haskell-strict-PVP.md
  21. 0.70 s diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
  22. 0.70 s index 2b499f5..5465a5d 100644
  23. 0.70 s --- a/docs/CONTRIBUTING.md
  24. 0.70 s +++ b/docs/CONTRIBUTING.md
  25. 0.70 s @@ -25,10 +25,10 @@ All contributions are welcome, we love improvements to docs and tests.
  26. 0.70 s ### terminology
  27. 0.70 s
  28. 0.70 s | generic | Haskell | Nix | Rust | versioned |
  29. 0.70 s -|------------|---------------|------------|-----------|-----------|
  30. 0.70 s -| repository | | | | ✔ |
  31. 0.70 s +| ---------- | ------------- | ---------- | --------- | --------- |
  32. 0.70 s +| repository | | | | ✔ |
  33. 0.70 s | project | Cabal project | flake | workspace | |
  34. 0.70 s -| package | Cabal package | derivation | crate | ✔ |
  35. 0.70 s +| package | Cabal package | derivation | crate | ✔ |
  36. 0.70 s | component | Cabal stanza | | | |
  37. 0.70 s
  38. 0.70 s There is usually one project per repository, but sometimes a project may be split across multiple repositories. It’s unlikely that more than one project would be in the same repository.
  39. 0.70 s diff --git a/docs/CONTRIBUTING/haskell.md b/docs/CONTRIBUTING/haskell.md
  40. 0.70 s index 963d786..4592132 100644
  41. 0.70 s --- a/docs/CONTRIBUTING/haskell.md
  42. 0.70 s +++ b/docs/CONTRIBUTING/haskell.md
  43. 0.70 s @@ -50,7 +50,7 @@ Documentation is very important, but it shouldn’t detract from good naming. Th
  44. 0.70 s
  45. 0.70 s Documentation is written using [Haddock](https://haskell-haddock.readthedocs.io/), and it’s helpful to add Doctest examples, as described in the “testing” section below.
  46. 0.70 s
  47. 0.70 s -__NB__: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
  48. 0.70 s +**NB**: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
  49. 0.70 s
  50. 0.70 s #### guidelines
  51. 0.70 s
  52. 0.70 s @@ -93,7 +93,7 @@ name foo
  53. 0.70 s library
  54. 0.70 s ```
  55. 0.70 s
  56. 0.70 s -``` cabal
  57. 0.70 s +```cabal
  58. 0.70 s name: foo-hedgehog
  59. 0.70 s
  60. 0.70 s library
  61. 0.70 s diff --git a/docs/haskell-release-process.md b/docs/haskell-release-process.md
  62. 0.70 s index c761703..e08874f 100644
  63. 0.70 s --- a/docs/haskell-release-process.md
  64. 0.70 s +++ b/docs/haskell-release-process.md
  65. 0.70 s @@ -20,7 +20,7 @@ Don’t lump documentation & testing improvements into a breaking change just be
  66. 0.70 s
  67. 0.70 s ### format the PR title as a CHANGELOG entry
  68. 0.70 s
  69. 0.70 s -__TODO__: How does this work when there are multiple packages?
  70. 0.70 s +**TODO**: How does this work when there are multiple packages?
  71. 0.70 s
  72. 0.70 s ## release updates
  73. 0.70 s
  74. 0.70 s @@ -37,7 +37,6 @@ In as far as the release is automated, the changes should be made in the merge c
  75. 0.70 s
  76. 0.70 s [^1]: This is delicate, because the CI build matrix doesn’t do a good job of solving for other versions of local packages.
  77. 0.70 s
  78. 0.70 s -
  79. 0.70 s ## Hackage info
  80. 0.70 s
  81. 0.70 s Hackage allows you to optionally tag a release as “preferred” or ”deprecated”.
  82. 0.70 s diff --git a/docs/haskell-strict-PVP.md b/docs/haskell-strict-PVP.md
  83. 0.70 s index 094ce19..7893e61 100644
  84. 0.70 s --- a/docs/haskell-strict-PVP.md
  85. 0.70 s +++ b/docs/haskell-strict-PVP.md
  86. 0.70 s @@ -2,15 +2,15 @@
  87. 0.70 s
  88. 0.70 s This is a versioning system that’s compatible with [the Haskell Package Versioning Policy](https://pvp.haskell.org/), but tries to prevent more issues with dependencies.
  89. 0.70 s
  90. 0.70 s -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
  91. 0.70 s +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
  92. 0.70 s
  93. 0.70 s # terminology
  94. 0.70 s
  95. 0.70 s -- __bump__: this aligns with SemVer’s requirements, which are stricter than PVP here. “bumping” a component in a version means _incrementing_ that component while resetting all less-significant components to zero. (PVP doesn’t require resetting the less-significant components, but it’s certainly allowed and generally followed in practice.) __NB__: Because not all versions may be released, or may be unavailable for some reason, in practice it may appear as if the weaker requirements of PVP were followed (components increased instead of strictly incremented, and less significant components not reset).
  96. 0.70 s +- **bump**: this aligns with SemVer’s requirements, which are stricter than PVP here. “bumping” a component in a version means _incrementing_ that component while resetting all less-significant components to zero. (PVP doesn’t require resetting the less-significant components, but it’s certainly allowed and generally followed in practice.) **NB**: Because not all versions may be released, or may be unavailable for some reason, in practice it may appear as if the weaker requirements of PVP were followed (components increased instead of strictly incremented, and less significant components not reset).
  97. 0.70 s
  98. 0.70 s -- __change__: Some versioning documents talk about changing declarations, but any change to a type is an incompatible change, so we can see changes as simply a removal followed by an addition (with a conflicting name).
  99. 0.70 s +- **change**: Some versioning documents talk about changing declarations, but any change to a type is an incompatible change, so we can see changes as simply a removal followed by an addition (with a conflicting name).
  100. 0.70 s
  101. 0.70 s -- __fine-grained API tracking__: This is a term I’m coining (maybe there’s prior art) for actually looking at the full transitive API of a module (roughly, the interface file, but with some additions), and analyzing each individual change. It allows you to have narrower version bumps than is implied by dependency versions. __FIXME__: This needs a specification too (e.g., modified definitions aren’t apparent from an interface file, or, if they are, it’s not machine checkable whether they’re breaking changes – there should be a way to annotate these changes with how they affect the API, and if any annotations are missing, they can be inferred to be no more significant than the version bump)
  102. 0.70 s +- **fine-grained API tracking**: This is a term I’m coining (maybe there’s prior art) for actually looking at the full transitive API of a module (roughly, the interface file, but with some additions), and analyzing each individual change. It allows you to have narrower version bumps than is implied by dependency versions. **FIXME**: This needs a specification too (e.g., modified definitions aren’t apparent from an interface file, or, if they are, it’s not machine checkable whether they’re breaking changes – there should be a way to annotate these changes with how they affect the API, and if any annotations are missing, they can be inferred to be no more significant than the version bump)
  103. 0.70 s
  104. 0.70 s # summary of differences from PVP (non-normative)
  105. 0.70 s
  106. 0.70 s @@ -19,14 +19,14 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S
  107. 0.70 s - Strict PVP defines a “patch” level, corresponding to the `D` component (PVP references but never defines a “patch” level);
  108. 0.70 s - removing any instance or adding an orphan instance requires an `A` bump instead of an increase in `A.B`;
  109. 0.70 s - incompatible license changes require an `A` bump (PVP has nothing to say on licensing);
  110. 0.70 s -- adding a module moved from another package only __MAY__ bump the major version (it’s “SHOULD” in PVP);
  111. 0.70 s +- adding a module moved from another package only **MAY** bump the major version (it’s “SHOULD” in PVP);
  112. 0.70 s - deprecation only increments `D`, not `A.B` (compatible, because this is only a “SHOULD” in PVP);
  113. 0.70 s
  114. 0.70 s # specification
  115. 0.70 s
  116. 0.71 s -A package that follows Strict PVP __SHOULD__ declare that it does so (__FIXME__: We need a machine-checkable place to specify this declaration). This allows dependencies of the package to make additional assumptions based on the package version.
  117. 0.71 s +A package that follows Strict PVP **SHOULD** declare that it does so (**FIXME**: We need a machine-checkable place to specify this declaration). This allows dependencies of the package to make additional assumptions based on the package version.
  118. 0.71 s
  119. 0.71 s -A package that follows Strict PVP __MAY__ use fine-grained API tracking of its dependencies to use less significant version bumps than may be implied by the dependency versions.
  120. 0.71 s +A package that follows Strict PVP **MAY** use fine-grained API tracking of its dependencies to use less significant version bumps than may be implied by the dependency versions.
  121. 0.71 s
  122. 0.71 s ## version numbers
  123. 0.71 s
  124. 0.71 s @@ -44,7 +44,7 @@ The package version (PVP) always has four components, `A.B.C.D`. The first three
  125. 0.71 s
  126. 0.71 s Here is a breakdown of some of the constraints:
  127. 0.71 s
  128. 0.71 s -__FIXME__: Be clearer about “adding” and “removing”, etc. being about _the API_ – adding definitions that aren’t exported has no impact on the API.
  129. 0.71 s +**FIXME**: Be clearer about “adding” and “removing”, etc. being about _the API_ – adding definitions that aren’t exported has no impact on the API.
  130. 0.71 s
  131. 0.71 s ### sensitivity to additions to the API
  132. 0.71 s
  133. 0.71 s @@ -58,7 +58,7 @@ If your imports are [package-qualified](https://downloads.haskell.org/ghc/latest
  134. 0.71 s
  135. 0.71 s #### all non-package-local imports must be either qualified or have explicit import lists
  136. 0.71 s
  137. 0.71 s -__TODO__: Determine if `Prelude` really is [an exception to this rule](https://wiki.haskell.org/Import_modules_properly#Exception_from_the_rule) – is it true that `Prelude` is fixed going forward?
  138. 0.71 s +**TODO**: Determine if `Prelude` really is [an exception to this rule](https://wiki.haskell.org/Import_modules_properly#Exception_from_the_rule) – is it true that `Prelude` is fixed going forward?
  139. 0.71 s
  140. 0.71 s #### restriction of multiple imports with the same qualifier
  141. 0.71 s
  142. 0.71 s @@ -72,7 +72,7 @@ Because of the transitivity of instances, orphans make you sensitive to your dep
  143. 0.71 s
  144. 0.71 s > _suggestion_: Cross-reference orphans in the Cabal package files. Collect the class names and relevant types for any orphans you define. Add a comment above the relevant dependencies in the Cabal package file listing which classes and types come from each.
  145. 0.71 s
  146. 0.71 s -__NB__: Alternatively, adding _any_ instance[^1] could be considered a transitively-breaking change. Then orphans wouldn’t need to trigger API sensitivity. On the one hand, that seems easier to manage and orphans are often unavoidable. However, it seems odd to penalize definers of non-orphan instances because of orphans, and relegating orphans to their own packages mitigates API sensitivity better than it mitigates transitively-breaking changes.
  147. 0.71 s +**NB**: Alternatively, adding _any_ instance[^1] could be considered a transitively-breaking change. Then orphans wouldn’t need to trigger API sensitivity. On the one hand, that seems easier to manage and orphans are often unavoidable. However, it seems odd to penalize definers of non-orphan instances because of orphans, and relegating orphans to their own packages mitigates API sensitivity better than it mitigates transitively-breaking changes.
  148. 0.71 s
  149. 0.71 s [^1]: Adding an instance at the same time as its class or a relevant type would always be a minor change, since there’s no way for an orphan to exist before that point.
  150. 0.71 s
  151. 0.71 s @@ -135,13 +135,13 @@ This can happen due to syntactic changes that don’t otherwise affect the API (
  152. 0.71 s
  153. 0.71 s #### removing support for a compiler version
  154. 0.71 s
  155. 0.71 s -__TODO__: Can this be constrained at all? For example., can changing from supporting GHC 9.10.1(+) to 9.10.2(+) be considered a patch change?
  156. 0.71 s +**TODO**: Can this be constrained at all? For example., can changing from supporting GHC 9.10.1(+) to 9.10.2(+) be considered a patch change?
  157. 0.71 s
  158. 0.71 s #### restricting an existing dependency’s version range in any way
  159. 0.71 s
  160. 0.71 s Consumers have to contend not only with our version bounds, but also with those of other libraries. It’s possible that some dependency overlapped in a very narrow way, and even just restricting a particular patch version of a dependency could make it impossible to find a dependency solution.
  161. 0.71 s
  162. 0.71 s -__TODO__: Determine if this is actually a lesser change. For example, can we get the solver to always fall back to a previous version (even if deprecated) if this version’s dependencies don’t intersect? If so, this is a patch change.
  163. 0.71 s +**TODO**: Determine if this is actually a lesser change. For example, can we get the solver to always fall back to a previous version (even if deprecated) if this version’s dependencies don’t intersect? If so, this is a patch change.
  164. 0.71 s
  165. 0.71 s #### removing a module
  166. 0.71 s
  167. 0.71 s @@ -149,7 +149,7 @@ __TODO__: Determine if this is actually a lesser change. For example, can we get
  168. 0.71 s
  169. 0.71 s A new dependency may make it impossible to find a solution in the face of other packages’ dependency ranges.
  170. 0.71 s
  171. 0.71 s -__TODO__: This may be similar to the previous case – will the solver go back to an older (even if deprecated) version that doesn’t have the new dependency?
  172. 0.71 s +**TODO**: This may be similar to the previous case – will the solver go back to an older (even if deprecated) version that doesn’t have the new dependency?
  173. 0.71 s
  174. 0.71 s #### changing the implementation of a term (sometimes)
  175. 0.71 s
  176. 0.71 s @@ -171,7 +171,7 @@ Haskell does type resolution independently of constraints. It then sees if the t
  177. 0.71 s
  178. 0.71 s This is a good example of the difference between “additions to the API” and “non-breaking changes to the API”. This makes a function applicable in more situations, but doesn’t add anything to the API.
  179. 0.71 s
  180. 0.71 s -__FIXME__: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
  181. 0.71 s +**FIXME**: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
  182. 0.71 s
  183. 0.71 s ### other changes (bumps `D`)
  184. 0.71 s
  185. 0.71 s @@ -189,7 +189,7 @@ The most common cases of this are
  186. 0.71 s
  187. 0.71 s #### deprecation
  188. 0.71 s
  189. 0.71 s -__NB__: This case is _weaker_ than PVP (but allowed by it).
  190. 0.71 s +**NB**: This case is _weaker_ than PVP (but allowed by it).
  191. 0.71 s
  192. 0.71 s PVP says that packages “SHOULD” bump their major version when adding `deprecated` pragmas.
  193. 0.71 s
  194. 0.71 s @@ -203,16 +203,16 @@ Yes, in development, `-Werror` is often (and should be) used. However, that just
  195. 0.71 s
  196. 0.71 s This is incompatible with both PVP and SPVP. It requires that a security fix be no more significant than a minor change.
  197. 0.71 s
  198. 0.71 s -__TODO__: This section includes some things that are outside the scope of a versioning system, and should be listed as “_suggestion_”s.
  199. 0.71 s +**TODO**: This section includes some things that are outside the scope of a versioning system, and should be listed as “_suggestion_”s.
  200. 0.71 s
  201. 0.71 s -A security fix __SHOULD__ be made without breaking the API. However, if that’s not possible, the breaking change __MUST__ bump `C` and leave `A` and `B` unchanged.
  202. 0.71 s +A security fix **SHOULD** be made without breaking the API. However, if that’s not possible, the breaking change **MUST** bump `C` and leave `A` and `B` unchanged.
  203. 0.71 s
  204. 0.71 s -A security fix, even if breaking, __MUST__ not include any other breaking changes. A security fix __SHOULD__ not include any unrelated changes at all. Even trivial changes can impede analysis, and my have some subtle effect that undermines the release.
  205. 0.71 s +A security fix, even if breaking, **MUST** not include any other breaking changes. A security fix **SHOULD** not include any unrelated changes at all. Even trivial changes can impede analysis, and my have some subtle effect that undermines the release.
  206. 0.71 s
  207. 0.71 s -Whatever mechanisms are available __SHOULD__ be used to deprecate[^2] the affected releases even before the fix is available. Once a fix is available, affected versions __SHOULD__ be made unavailable.
  208. 0.71 s +Whatever mechanisms are available **SHOULD** be used to deprecate[^2] the affected releases even before the fix is available. Once a fix is available, affected versions **SHOULD** be made unavailable.
  209. 0.71 s
  210. 0.71 s [^2]: In this case, “deprecate” refers to something like the Hackage mechanism, where a deprecated release is only used if no other compatible release is available. This means that users will be downgraded where possible before a fix is even available.
  211. 0.71 s
  212. 0.71 s This helps ensure that security fixes are propagated quickly, even if it means introducing breakages that need to be repaired.
  213. 0.71 s
  214. 0.71 s -__NB__: There’s what looks like a catch-22 here, but I think it’s an illusion – if a particular major version has an older unaffected release, then the actual fixed release may introduce an unnecessary breakage. But … if the older version wasn’t affected, then the fix must have been possible without breaking _that part_ of the API. That is, any breaking fix __SHOULD__ only cause breakage to APIs that have already been deprecated.
  215. 0.71 s +**NB**: There’s what looks like a catch-22 here, but I think it’s an illusion – if a particular major version has an older unaffected release, then the actual fixed release may introduce an unnecessary breakage. But … if the older version wasn’t affected, then the fix must have been possible without breaking _that part_ of the API. That is, any breaking fix **SHOULD** only cause breakage to APIs that have already been deprecated.
  216. 0.72 s error: Cannot build '/nix/store/iyvdcf1nzsz3xrp59cph2hxihmzbx78z-treefmt-check.drv'.
  217. 0.72 s Reason: builder failed with exit code 1.
  218. 0.72 s Output paths:
  219. 0.72 s /nix/store/ysa5dz4kaf9g109g8abrzx912dvww518-treefmt-check
  220. 0.72 s Last 202 log lines:
  221. 0.72 s > treefmt v2.4.0traversed 66 files
  222. 0.72 s > emitted 52 files for processing
  223. 0.72 s > formatted 52 files (4 changed) in 340ms
  224. 0.72 s > M docs/CONTRIBUTING.md
  225. 0.72 s > M docs/CONTRIBUTING/haskell.md
  226. 0.72 s > M docs/haskell-release-process.md
  227. 0.72 s > M docs/haskell-strict-PVP.md
  228. 0.72 s > diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
  229. 0.72 s > index 2b499f5..5465a5d 100644
  230. 0.72 s > --- a/docs/CONTRIBUTING.md
  231. 0.72 s > +++ b/docs/CONTRIBUTING.md
  232. 0.72 s > @@ -25,10 +25,10 @@ All contributions are welcome, we love improvements to docs and tests.
  233. 0.72 s > ### terminology
  234. 0.72 s >
  235. 0.72 s > | generic | Haskell | Nix | Rust | versioned |
  236. 0.72 s > -|------------|---------------|------------|-----------|-----------|
  237. 0.72 s > -| repository | | | | ✔ |
  238. 0.72 s > +| ---------- | ------------- | ---------- | --------- | --------- |
  239. 0.72 s > +| repository | | | | ✔ |
  240. 0.72 s > | project | Cabal project | flake | workspace | |
  241. 0.72 s > -| package | Cabal package | derivation | crate | ✔ |
  242. 0.72 s > +| package | Cabal package | derivation | crate | ✔ |
  243. 0.72 s > | component | Cabal stanza | | | |
  244. 0.72 s >
  245. 0.72 s > There is usually one project per repository, but sometimes a project may be split across multiple repositories. It’s unlikely that more than one project would be in the same repository.
  246. 0.73 s > diff --git a/docs/CONTRIBUTING/haskell.md b/docs/CONTRIBUTING/haskell.md
  247. 0.73 s > index 963d786..4592132 100644
  248. 0.73 s > --- a/docs/CONTRIBUTING/haskell.md
  249. 0.73 s > +++ b/docs/CONTRIBUTING/haskell.md
  250. 0.73 s > @@ -50,7 +50,7 @@ Documentation is very important, but it shouldn’t detract from good naming. Th
  251. 0.73 s >
  252. 0.73 s > Documentation is written using [Haddock](https://haskell-haddock.readthedocs.io/), and it’s helpful to add Doctest examples, as described in the “testing” section below.
  253. 0.73 s >
  254. 0.73 s > -__NB__: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
  255. 0.73 s > +**NB**: Haddock isn’t Markdown! But the similarities can make it easy to forget sometimes. Please try to review your doc changes using [`cabal haddock-project`](https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-haddock-project) before submitting them.
  256. 0.73 s >
  257. 0.73 s > #### guidelines
  258. 0.73 s >
  259. 0.73 s > @@ -93,7 +93,7 @@ name foo
  260. 0.73 s > library
  261. 0.73 s > ```
  262. 0.73 s >
  263. 0.73 s > -``` cabal
  264. 0.73 s > +```cabal
  265. 0.73 s > name: foo-hedgehog
  266. 0.73 s >
  267. 0.73 s > library
  268. 0.73 s > diff --git a/docs/haskell-release-process.md b/docs/haskell-release-process.md
  269. 0.73 s > index c761703..e08874f 100644
  270. 0.73 s > --- a/docs/haskell-release-process.md
  271. 0.73 s > +++ b/docs/haskell-release-process.md
  272. 0.73 s > @@ -20,7 +20,7 @@ Don’t lump documentation & testing improvements into a breaking change just be
  273. 0.73 s >
  274. 0.73 s > ### format the PR title as a CHANGELOG entry
  275. 0.73 s >
  276. 0.73 s > -__TODO__: How does this work when there are multiple packages?
  277. 0.73 s > +**TODO**: How does this work when there are multiple packages?
  278. 0.73 s >
  279. 0.73 s > ## release updates
  280. 0.73 s >
  281. 0.73 s > @@ -37,7 +37,6 @@ In as far as the release is automated, the changes should be made in the merge c
  282. 0.73 s >
  283. 0.73 s > [^1]: This is delicate, because the CI build matrix doesn’t do a good job of solving for other versions of local packages.
  284. 0.73 s >
  285. 0.73 s > -
  286. 0.73 s > ## Hackage info
  287. 0.73 s >
  288. 0.73 s > Hackage allows you to optionally tag a release as “preferred” or ”deprecated”.
  289. 0.73 s > diff --git a/docs/haskell-strict-PVP.md b/docs/haskell-strict-PVP.md
  290. 0.73 s > index 094ce19..7893e61 100644
  291. 0.73 s > --- a/docs/haskell-strict-PVP.md
  292. 0.73 s > +++ b/docs/haskell-strict-PVP.md
  293. 0.73 s > @@ -2,15 +2,15 @@
  294. 0.73 s >
  295. 0.73 s > This is a versioning system that’s compatible with [the Haskell Package Versioning Policy](https://pvp.haskell.org/), but tries to prevent more issues with dependencies.
  296. 0.73 s >
  297. 0.73 s > -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
  298. 0.73 s > +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
  299. 0.73 s >
  300. 0.73 s > # terminology
  301. 0.73 s >
  302. 0.73 s > -- __bump__: this aligns with SemVer’s requirements, which are stricter than PVP here. “bumping” a component in a version means _incrementing_ that component while resetting all less-significant components to zero. (PVP doesn’t require resetting the less-significant components, but it’s certainly allowed and generally followed in practice.) __NB__: Because not all versions may be released, or may be unavailable for some reason, in practice it may appear as if the weaker requirements of PVP were followed (components increased instead of strictly incremented, and less significant components not reset).
  303. 0.73 s > +- **bump**: this aligns with SemVer’s requirements, which are stricter than PVP here. “bumping” a component in a version means _incrementing_ that component while resetting all less-significant components to zero. (PVP doesn’t require resetting the less-significant components, but it’s certainly allowed and generally followed in practice.) **NB**: Because not all versions may be released, or may be unavailable for some reason, in practice it may appear as if the weaker requirements of PVP were followed (components increased instead of strictly incremented, and less significant components not reset).
  304. 0.73 s >
  305. 0.73 s > -- __change__: Some versioning documents talk about changing declarations, but any change to a type is an incompatible change, so we can see changes as simply a removal followed by an addition (with a conflicting name).
  306. 0.73 s > +- **change**: Some versioning documents talk about changing declarations, but any change to a type is an incompatible change, so we can see changes as simply a removal followed by an addition (with a conflicting name).
  307. 0.73 s >
  308. 0.73 s > -- __fine-grained API tracking__: This is a term I’m coining (maybe there’s prior art) for actually looking at the full transitive API of a module (roughly, the interface file, but with some additions), and analyzing each individual change. It allows you to have narrower version bumps than is implied by dependency versions. __FIXME__: This needs a specification too (e.g., modified definitions aren’t apparent from an interface file, or, if they are, it’s not machine checkable whether they’re breaking changes – there should be a way to annotate these changes with how they affect the API, and if any annotations are missing, they can be inferred to be no more significant than the version bump)
  309. 0.73 s > +- **fine-grained API tracking**: This is a term I’m coining (maybe there’s prior art) for actually looking at the full transitive API of a module (roughly, the interface file, but with some additions), and analyzing each individual change. It allows you to have narrower version bumps than is implied by dependency versions. **FIXME**: This needs a specification too (e.g., modified definitions aren’t apparent from an interface file, or, if they are, it’s not machine checkable whether they’re breaking changes – there should be a way to annotate these changes with how they affect the API, and if any annotations are missing, they can be inferred to be no more significant than the version bump)
  310. 0.73 s >
  311. 0.73 s > # summary of differences from PVP (non-normative)
  312. 0.73 s >
  313. 0.73 s > @@ -19,14 +19,14 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S
  314. 0.73 s > - Strict PVP defines a “patch” level, corresponding to the `D` component (PVP references but never defines a “patch” level);
  315. 0.73 s > - removing any instance or adding an orphan instance requires an `A` bump instead of an increase in `A.B`;
  316. 0.73 s > - incompatible license changes require an `A` bump (PVP has nothing to say on licensing);
  317. 0.73 s > -- adding a module moved from another package only __MAY__ bump the major version (it’s “SHOULD” in PVP);
  318. 0.73 s > +- adding a module moved from another package only **MAY** bump the major version (it’s “SHOULD” in PVP);
  319. 0.73 s > - deprecation only increments `D`, not `A.B` (compatible, because this is only a “SHOULD” in PVP);
  320. 0.73 s >
  321. 0.73 s > # specification
  322. 0.73 s >
  323. 0.73 s > -A package that follows Strict PVP __SHOULD__ declare that it does so (__FIXME__: We need a machine-checkable place to specify this declaration). This allows dependencies of the package to make additional assumptions based on the package version.
  324. 0.73 s > +A package that follows Strict PVP **SHOULD** declare that it does so (**FIXME**: We need a machine-checkable place to specify this declaration). This allows dependencies of the package to make additional assumptions based on the package version.
  325. 0.73 s >
  326. 0.73 s > -A package that follows Strict PVP __MAY__ use fine-grained API tracking of its dependencies to use less significant version bumps than may be implied by the dependency versions.
  327. 0.73 s > +A package that follows Strict PVP **MAY** use fine-grained API tracking of its dependencies to use less significant version bumps than may be implied by the dependency versions.
  328. 0.73 s >
  329. 0.73 s > ## version numbers
  330. 0.73 s >
  331. 0.73 s > @@ -44,7 +44,7 @@ The package version (PVP) always has four components, `A.B.C.D`. The first three
  332. 0.73 s >
  333. 0.73 s > Here is a breakdown of some of the constraints:
  334. 0.73 s >
  335. 0.73 s > -__FIXME__: Be clearer about “adding” and “removing”, etc. being about _the API_ – adding definitions that aren’t exported has no impact on the API.
  336. 0.73 s > +**FIXME**: Be clearer about “adding” and “removing”, etc. being about _the API_ – adding definitions that aren’t exported has no impact on the API.
  337. 0.73 s >
  338. 0.73 s > ### sensitivity to additions to the API
  339. 0.73 s >
  340. 0.73 s > @@ -58,7 +58,7 @@ If your imports are [package-qualified](https://downloads.haskell.org/ghc/latest
  341. 0.73 s >
  342. 0.73 s > #### all non-package-local imports must be either qualified or have explicit import lists
  343. 0.73 s >
  344. 0.73 s > -__TODO__: Determine if `Prelude` really is [an exception to this rule](https://wiki.haskell.org/Import_modules_properly#Exception_from_the_rule) – is it true that `Prelude` is fixed going forward?
  345. 0.73 s > +**TODO**: Determine if `Prelude` really is [an exception to this rule](https://wiki.haskell.org/Import_modules_properly#Exception_from_the_rule) – is it true that `Prelude` is fixed going forward?
  346. 0.73 s >
  347. 0.73 s > #### restriction of multiple imports with the same qualifier
  348. 0.73 s >
  349. 0.73 s > @@ -72,7 +72,7 @@ Because of the transitivity of instances, orphans make you sensitive to your dep
  350. 0.73 s >
  351. 0.73 s > > _suggestion_: Cross-reference orphans in the Cabal package files. Collect the class names and relevant types for any orphans you define. Add a comment above the relevant dependencies in the Cabal package file listing which classes and types come from each.
  352. 0.73 s >
  353. 0.73 s > -__NB__: Alternatively, adding _any_ instance[^1] could be considered a transitively-breaking change. Then orphans wouldn’t need to trigger API sensitivity. On the one hand, that seems easier to manage and orphans are often unavoidable. However, it seems odd to penalize definers of non-orphan instances because of orphans, and relegating orphans to their own packages mitigates API sensitivity better than it mitigates transitively-breaking changes.
  354. 0.73 s > +**NB**: Alternatively, adding _any_ instance[^1] could be considered a transitively-breaking change. Then orphans wouldn’t need to trigger API sensitivity. On the one hand, that seems easier to manage and orphans are often unavoidable. However, it seems odd to penalize definers of non-orphan instances because of orphans, and relegating orphans to their own packages mitigates API sensitivity better than it mitigates transitively-breaking changes.
  355. 0.73 s >
  356. 0.73 s > [^1]: Adding an instance at the same time as its class or a relevant type would always be a minor change, since there’s no way for an orphan to exist before that point.
  357. 0.73 s >
  358. 0.73 s > @@ -135,13 +135,13 @@ This can happen due to syntactic changes that don’t otherwise affect the API (
  359. 0.73 s >
  360. 0.73 s > #### removing support for a compiler version
  361. 0.73 s >
  362. 0.73 s > -__TODO__: Can this be constrained at all? For example., can changing from supporting GHC 9.10.1(+) to 9.10.2(+) be considered a patch change?
  363. 0.73 s > +**TODO**: Can this be constrained at all? For example., can changing from supporting GHC 9.10.1(+) to 9.10.2(+) be considered a patch change?
  364. 0.73 s >
  365. 0.73 s > #### restricting an existing dependency’s version range in any way
  366. 0.73 s >
  367. 0.73 s > Consumers have to contend not only with our version bounds, but also with those of other libraries. It’s possible that some dependency overlapped in a very narrow way, and even just restricting a particular patch version of a dependency could make it impossible to find a dependency solution.
  368. 0.73 s >
  369. 0.73 s > -__TODO__: Determine if this is actually a lesser change. For example, can we get the solver to always fall back to a previous version (even if deprecated) if this version’s dependencies don’t intersect? If so, this is a patch change.
  370. 0.73 s > +**TODO**: Determine if this is actually a lesser change. For example, can we get the solver to always fall back to a previous version (even if deprecated) if this version’s dependencies don’t intersect? If so, this is a patch change.
  371. 0.73 s >
  372. 0.73 s > #### removing a module
  373. 0.73 s >
  374. 0.73 s > @@ -149,7 +149,7 @@ __TODO__: Determine if this is actually a lesser change. For example, can we get
  375. 0.73 s >
  376. 0.73 s > A new dependency may make it impossible to find a solution in the face of other packages’ dependency ranges.
  377. 0.73 s >
  378. 0.73 s > -__TODO__: This may be similar to the previous case – will the solver go back to an older (even if deprecated) version that doesn’t have the new dependency?
  379. 0.73 s > +**TODO**: This may be similar to the previous case – will the solver go back to an older (even if deprecated) version that doesn’t have the new dependency?
  380. 0.73 s >
  381. 0.73 s > #### changing the implementation of a term (sometimes)
  382. 0.73 s >
  383. 0.73 s > @@ -171,7 +171,7 @@ Haskell does type resolution independently of constraints. It then sees if the t
  384. 0.73 s >
  385. 0.73 s > This is a good example of the difference between “additions to the API” and “non-breaking changes to the API”. This makes a function applicable in more situations, but doesn’t add anything to the API.
  386. 0.73 s >
  387. 0.73 s > -__FIXME__: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
  388. 0.73 s > +**FIXME**: I think this might not be true with [type variable defaulting](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/type_defaulting.html). For example, if you weaken a constraint from `RealFloat` to `Num`, and a consumer is using `default (Natural, Double)`, the switch from resolving `Double` to resolving `Natural` can then introduce a runtime failure when they call `negate`. There are mechanisms to disable defaulting, like `default ()` or requiring `-Werror=type-defaults`, but those must be applied in the consumer, not the definer.
  389. 0.73 s >
  390. 0.73 s > ### other changes (bumps `D`)
  391. 0.73 s >
  392. 0.73 s > @@ -189,7 +189,7 @@ The most common cases of this are
  393. 0.73 s >
  394. 0.73 s > #### deprecation
  395. 0.73 s >
  396. 0.73 s > -__NB__: This case is _weaker_ than PVP (but allowed by it).
  397. 0.73 s > +**NB**: This case is _weaker_ than PVP (but allowed by it).
  398. 0.73 s >
  399. 0.73 s > PVP says that packages “SHOULD” bump their major version when adding `deprecated` pragmas.
  400. 0.73 s >
  401. 0.73 s > @@ -203,16 +203,16 @@ Yes, in development, `-Werror` is often (and should be) used. However, that just
  402. 0.73 s >
  403. 0.73 s > This is incompatible with both PVP and SPVP. It requires that a security fix be no more significant than a minor change.
  404. 0.73 s >
  405. 0.73 s > -__TODO__: This section includes some things that are outside the scope of a versioning system, and should be listed as “_suggestion_”s.
  406. 0.73 s > +**TODO**: This section includes some things that are outside the scope of a versioning system, and should be listed as “_suggestion_”s.
  407. 0.73 s >
  408. 0.73 s > -A security fix __SHOULD__ be made without breaking the API. However, if that’s not possible, the breaking change __MUST__ bump `C` and leave `A` and `B` unchanged.
  409. 0.73 s > +A security fix **SHOULD** be made without breaking the API. However, if that’s not possible, the breaking change **MUST** bump `C` and leave `A` and `B` unchanged.
  410. 0.73 s >
  411. 0.73 s > -A security fix, even if breaking, __MUST__ not include any other breaking changes. A security fix __SHOULD__ not include any unrelated changes at all. Even trivial changes can impede analysis, and my have some subtle effect that undermines the release.
  412. 0.73 s > +A security fix, even if breaking, **MUST** not include any other breaking changes. A security fix **SHOULD** not include any unrelated changes at all. Even trivial changes can impede analysis, and my have some subtle effect that undermines the release.
  413. 0.73 s >
  414. 0.73 s > -Whatever mechanisms are available __SHOULD__ be used to deprecate[^2] the affected releases even before the fix is available. Once a fix is available, affected versions __SHOULD__ be made unavailable.
  415. 0.73 s > +Whatever mechanisms are available **SHOULD** be used to deprecate[^2] the affected releases even before the fix is available. Once a fix is available, affected versions **SHOULD** be made unavailable.
  416. 0.73 s >
  417. 0.73 s > [^2]: In this case, “deprecate” refers to something like the Hackage mechanism, where a deprecated release is only used if no other compatible release is available. This means that users will be downgraded where possible before a fix is even available.
  418. 0.73 s >
  419. 0.73 s > This helps ensure that security fixes are propagated quickly, even if it means introducing breakages that need to be repaired.
  420. 0.73 s >
  421. 0.73 s > -__NB__: There’s what looks like a catch-22 here, but I think it’s an illusion – if a particular major version has an older unaffected release, then the actual fixed release may introduce an unnecessary breakage. But … if the older version wasn’t affected, then the fix must have been possible without breaking _that part_ of the API. That is, any breaking fix __SHOULD__ only cause breakage to APIs that have already been deprecated.
  422. 0.73 s > +**NB**: There’s what looks like a catch-22 here, but I think it’s an illusion – if a particular major version has an older unaffected release, then the actual fixed release may introduce an unnecessary breakage. But … if the older version wasn’t affected, then the fix must have been possible without breaking _that part_ of the API. That is, any breaking fix **SHOULD** only cause breakage to APIs that have already been deprecated.
  423. 0.73 s For full logs, run:
  424. 0.73 s nix log /nix/store/iyvdcf1nzsz3xrp59cph2hxihmzbx78z-treefmt-check.drv