Skip to content

Conversation

@thomashoneyman
Copy link
Member

Closes #366 by filling in the remainder of the spec, minus package aliasing, as that was never quite figured out.

@thomashoneyman thomashoneyman requested a review from f-f January 21, 2026 18:11
- **Declarative manifests**: Package manifests declare properties about packages without imperative hooks like npm's `postinstall`
- **Verified builds**: All packages are known to solve and compile with at least one supported compiler version. This enables features like Pursuit's compiler compatibility filter and allows solvers to produce build plans targeting a specific compiler.
- **Location-agnostic publishing**: Packages can be published from any supported location type, including arbitrary git repositories, not just GitHub.
- **Mono/polyrepo support**: A single repository can host multiple packages using the `subdir` field in package lo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Mono/polyrepo support**: A single repository can host multiple packages using the `subdir` field in package lo
- **Mono/polyrepo support**: A single repository can host multiple packages using the `subdir` field in the package location data

- **Version**: A specific release of a package, identified by a semantic version (see [Version](#version)).
- **Range**: A constraint specifying acceptable versions of a dependency (see [Range](#range)).
- **Location**: The remote location from which the registry fetches package source code (see [Location](#location)).
- **Ref**: An arbitrary reference identifying a particular snapshot of the code at a location—for Git locations this would be a Git ref such as a tag or commit hash.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Ref**: An arbitrary reference identifying a particular snapshot of the code at a location—for Git locations this would be a Git ref such as a tag or commit hash.
- **Ref**: An arbitrary reference identifying a particular snapshot of the code at a location. For Git locations this would be a Git ref such as a tag or commit hash.

### 3.1 Compatibility Guarantees

A description of our forward-compatibility guarantees and what that means.
The registry guarantees forward compatibility for its core data types. Forward compatibility means that new clients will always be able to read data written by older clients. This guarantee is critical because package manifests are baked into immutable package tarballs forever—any client, including older ones, must always be able to read any manifest in the registry.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first part of this sentence contradicts the second 🙂
Forward compatibility is when a system is able to accept input intended for a later version of itself. In Registry terms, it means that older clients are always able to read data produced by newer clients, so the other way around of how it's written now:

Suggested change
The registry guarantees forward compatibility for its core data types. Forward compatibility means that new clients will always be able to read data written by older clients. This guarantee is critical because package manifests are baked into immutable package tarballs foreverany client, including older ones, must always be able to read any manifest in the registry.
The registry guarantees forward compatibility for its core data types. Forward compatibility means that older clients will always be able to read data written by newer clients. This guarantee is critical because package manifests are baked into immutable package tarballs forever: any client, including older ones, must always be able to read any manifest in the registry.


To maintain forward compatibility, the only permitted schema changes are:

1. **Adding new fields**: New optional fields may be introduced; older clients will ignore them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. **Adding new fields**: New optional fields may be introduced; older clients will ignore them.
1. **Adding new optional fields**: New optional fields may be introduced; older clients will ignore them.

2. **Removing optional fields**: Optional fields may be removed if no longer needed.
3. **Relaxing constraints**: Constraints not enforced by the type system may be loosened (e.g., increasing a maximum length).

Changes that would break forward compatibility (such as removing required fields, renaming fields, or changing the type of a field) are not permitted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth making it extra clear 😂

Suggested change
Changes that would break forward compatibility (such as removing required fields, renaming fields, or changing the type of a field) are not permitted.
Changes that would break forward compatibility (such as removing required fields, renaming fields, or changing the type of a field) are not permitted **under any circumstances**.


### 4.4 Manifest Index Repository

The manifest index is stored in the [purescript/registry-index](https://github.com/purescript/registry-index) repository. This index caches all package manifests in a structure optimized for efficient lookup by package managers. See [Section 3.6 (Manifest Index)](#36-manifest-index) for the index structure.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noting why the index exists, not sure we mention it anywhere else

Suggested change
The manifest index is stored in the [purescript/registry-index](https://github.com/purescript/registry-index) repository. This index caches all package manifests in a structure optimized for efficient lookup by package managers. See [Section 3.6 (Manifest Index)](#36-manifest-index) for the index structure.
The manifest index is stored in the [purescript/registry-index](https://github.com/purescript/registry-index) repository. This index caches all package manifests in a structure optimized for efficient lookup by package managers, as downloading the archives just to peek at the manifests inside is wildly impractical. See [Section 3.6 (Manifest Index)](#36-manifest-index) for the index structure.

Comment on lines +912 to +913
| Registry API | `https://registry.purescript.org/api` | Submit publish, unpublish, and transfer operations |
| Package Storage | `https://packages.registry.purescript.org` | Download package tarballs |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency:

Suggested change
| Registry API | `https://registry.purescript.org/api` | Submit publish, unpublish, and transfer operations |
| Package Storage | `https://packages.registry.purescript.org` | Download package tarballs |
| Registry API | `registry.purescript.org/api` | Submit publish, unpublish, and transfer operations |
| Package Storage | `packages.registry.purescript.org` | Download package tarballs |

}
```

Poll until `finishedAt` is present, then check `success` to determine the outcome. Stream logs to the user by tracking the `since` timestamp.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Poll until `finishedAt` is present, then check `success` to determine the outcome. Stream logs to the user by tracking the `since` timestamp.
Poll until `finishedAt` is present, then check `success` to determine the outcome. The `since` parameter can be used for pagination, and to stream logs to the user.

Comment on lines +1040 to +1049
### 8.5 Dependency Resolution

Package managers should implement a dependency solver that:

1. Reads available versions from the manifest index
2. Respects version ranges specified in manifests
3. Ensures all transitive dependencies are satisfied
4. Optionally constrains solutions to a specific compiler version using the `compilers` field in metadata

The registry provides a solver implementation in [`Registry.Solver`](./lib/src/Solver.purs).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is common sense, but it doesn't have to happen this way - for what we know it might be possible to generate build plans without respecting the version ranges for example.
I am not sure we should have this section at all? Or I would frame it as "you will want to solve versions at some point, the registry has a solver"

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.

Registry Spec

3 participants