What a repository depends on
headwater starts from a repository state: the content of a repository at one commit, together with any uncommitted change the asker names as part of it. Every bound dependency description reads that state and reports what it declares (40). headwater reads only the dependencies the state declares, and invents none (1).
Declarations and identities
A declaration is one place in a repository state that names a
dependency, with what it says of the version. A dependency entry in
package.json, a requirement in pyproject.toml, a FROM line in a
Dockerfile and a uses: line in a workflow are each a declaration
(C.2).
Every dependency has exactly one identity, whichever declaration names
it and whichever source publishes it (2). The identity is a Package URL
without its version: pkg:npm/react, pkg:pypi/fastapi,
pkg:github/jdx/mise (C.1). Two declarations of one identity are one
dependency, wherever in the repository they sit.
headwater reports a declaration it cannot read as unread, naming the declaration and the reason, and never drops it from a report (1). A dependency left out would read as one with nothing newer. An unread entry says what is true: headwater does not know.
The pin
A dependency’s pin is the version the repository runs. Each description
reads it where its ecosystem records it: the version a lockfile
resolves for npm, Cargo and Python, an exact == requirement for
Python, the version go.mod names for Go (C.2). A pin is exactly one
version or unknown (3). A range with no lockfile behind it, a latest
tag, a branch or a version prefix names no single version, so its pin is
unknown.
headwater reports a dependency whose pin is unknown as unknown, never as having nothing newer (3). An asker who reads that nothing is newer can rely on it.
A dependency declared at more than one pin in one repository state is reported with every declaration and its pin. A release is newer for it when it is newer than the oldest of them (4). The report measures from the declaration that lags, and a fixer sees which one that is.
acme_client and acme-client are one Package URL, so the two declarations are one dependency, measured from its older pin (2, 4). A range with no lockfile names no single version, and the report says the pin is unknown (3).Reading changes nothing
headwater never writes a repository’s content, its history or its configuration (5). A dependency description gives two answers, the dependencies and the tiers, and both are the same for the same repository state. Reading either changes nothing (42). Agents in many checkouts of one repository ask at once (section 9), and a read that changed anything would change what the others read.
The descriptions
Each ecosystem’s declarations have a profile of their own (C.2): npm, Python, Cargo, Go, mise, GitHub Actions, container images and the watch list. The first set is the watch list, npm and Python (section 9). Each profile says which files it reads and where it finds the pin, and each reports the pin as unknown where its files name no single version. The watch list declares what no other file can, and has a chapter of its own.
Still to rule: questions 5, 7, 8, 17, 29 and 30, in Open questions.