Only IncompatiblePlatform counts as a knowing skip; other malformed
manifest data stays out of the satisfied set so the reconciliation can
still flag a broken promise. Backend-provided names are recorded before
the manifest-name evidence so the overlap warns once, in the backend's
own suppression loop. ar runs rcs/qs so the symbol index is explicit,
and the copy shim prints and returns 1 like its siblings instead of
re-raising.
The legacy manifest-less layout is legal and the 3.1.2 core ships one
such library (FSTools), so the warning would be unactionable noise; a
test now pins the level.
A truncated bundled library.json now raises the module's named error
with the clean-all hint instead of a raw JSONDecodeError. The renamed
_reconcile_versionless_skips advertises that it records into
backend.provided_requests. Two real-converter tests gain the
registry-guard patch their siblings use so a regression fails offline.
Rely on normalize_dependencies' guarantee of a non-empty string name
instead of re-checking it, collect sources in a single pass that
re-roots on the resolved directory rather than calling realpath per
file, probe library.properties once, hoist the invariant log-level
choice out of the warning loop, and record provided_requests as a set
since order was never used.
The walk records across re-resolutions, so a dependency a re-resolved
manifest no longer declares would have failed the build by name. The
reconciliation now intersects the recordings with the dependency names
of the manifests actually emitted, keeping the raise for real broken
promises. The manifest-name warning also gains the treeless-backend
gate its sibling got, since those backends cannot act on it either.
A version-less dependency the walk skips on the backend's promise is now
recorded like the versioned path, and a bundled candidate the backend
knowingly skips through the platform filter counts as satisfied, so the
post-emit reconciliation covers both paths without raising on legitimate
builds. The manifest-name warning deduplicates like its sibling, the
final drop warning stays at debug for backends without provides() since
they can never supply a bundled name, and a bundled library missing both
manifests leaves a debug trace instead of silently building on defaults.
Extra-script LINKFLAGS travel outside build.flags by design; the backend
now drains them into the library's link flags, matching the ESP-IDF
backend, instead of dropping a link-stage input silently. An unfulfilled
provides() promise raises by name (deduplicated) like the module's other
can-never-link checks, the vacuous end-to-end silence test is replaced
by a link-flags test that can fail, and a version-less dependency
assumed satisfied by manifest name alone warns like its backend twin
since the match is name-only evidence.