#1519)
* fix(manifest): resolve Maven dependencies through Maven's own resolver
The Maven facts extension collected the dependency graph with
maven-dependency-tree, then re-resolved each artifact itself, passing the
root module's repository list for every node in the tree. Maven resolves
each node against the repositories that node's own descriptor lineage
contributes, so a dependency served only by a repository declared in one
module of a reactor could not be materialized for any other module that
reached it. Aether's local repository also records which repository each
cached file came from, so not even an already-downloaded copy counted as
available, and --with-files aborted the scan on a dependency the build
itself resolves without trouble.
Resolution now goes through ProjectDependenciesResolver, the component
Maven's own lifecycle uses to build a project's classpath. Per-node
repositories, dependency management, scope derivation and reactor
substitution are Maven's rather than a re-implementation of them, and
failures are reported from Maven's own per-dependency errors. Which
artifacts get fetched is expressed as a DependencyFilter, so a plain
--facts run collects without downloading anything and a reactor sibling's
jar is never requested at the validate phase the CLI runs, where nothing
has been packaged. A filtered-out node yields no ArtifactResult, so it can
never be mistaken for a resolution failure.
Coordinate ids keep Maven's `type` rather than Aether's file extension, and
versions use the base version so a resolved remote snapshot cannot leak a
timestamped coordinate no manifest names. Conflict-losing nodes, which a
verbose collect leaves in the graph, are skipped. Records are byte-identical
to the previous output on the projects exercised here.
Drops the bundled maven-dependency-tree; the extension jar goes 67K -> 26K.
Adds two compat fixtures. repo-inheritance covers a dependency reachable
only through a repository a sibling module declares, plus the fail-closed
half: an unresolvable dependency must still be reported, since a silently
missing jar leaves reachability blind to what it contains.
duplicate-failure covers several modules failing on the same dependency,
whose identical failures collapse in the value-equality accumulator shared
across the reactor. The Maven matrix now spans 3.2.5 through 4.0.0-rc-6,
the range the extension claims to support.
* docs(changelog): restore [Unreleased] and drop the burned 1.1.161 section
1.1.161 never reached npm — 1.1.160 is still latest there — so no user can
install what that section describes. Its tag and GitHub release are
immutable and stay; the changelog documents the published package, and
GitHub generates its own release notes from the PR list, so the two need
not agree. The next bump derives 1.1.162 from the reachable tag either way,
so nothing here affects the release tooling.
How the section got there: #1516 wrote its heading as
`## [Unreleased] - 2026-08-27`, and unreleasedRange() in
scripts/release/changelog.mts locates the block by comparing the trimmed,
lowercased heading for equality with `## [unreleased]`. The trailing date
made it miss, so the release found nothing accrued, fell back to the
commit-derived section, and inserted its own heading above the block it
could not see — stranding `[Unreleased]` below a released version.
- Drops the 1.1.161 section and returns the Coana 15.10.25 note to
`## [Unreleased]`, to be promoted by the next release that ships.
- Puts `## [Unreleased]` back at the top, without a date.
- Leaves out "stop the coana bump from hand-writing versions": a
release-workflow change with nothing for a user of the package to act
on, which only appeared because the commit-derived fallback ran.
- Files the Maven resolver fix under `[Unreleased]`.
The locator's intolerance of a trailing date is left alone here; it wants
its own change.
* docs(bump-coana): forbid a date on the [Unreleased] heading
The rule against writing a `## [<version>]` heading did not say what the
heading may look like when it is recreated, and #1516 shows why that
matters. The bump wrote `## [1.1.161](...) - 2026-08-27`; the follow-up
correction changed the version to `Unreleased` but kept the date, leaving
`## [Unreleased] - 2026-08-27`.
unreleasedRange() in scripts/release/changelog.mts matches that heading for
equality — case-insensitively, but otherwise exactly — so the dated form is
invisible to it. The release promoted nothing, fell back to the section
derived from the commits in range, and inserted its own heading above the
block it could not see. The note sat below a released version where no
release would pick it up, and the version it named never reached npm.
Pins the recreated heading to exactly `## [Unreleased]` and says why a date
breaks promotion, so the next correction of a malformed heading lands on
the form the release can actually find.