Problem
soothfast.lock accumulates entries for binds that no documentation references any more, and nothing reports them.
docs check iterates the markers found in the scanned pages and looks each up in the lock (cargo-soothfast/src/docs.rs). It never walks the lock looking for the reverse: an entry with no marker pointing at it. A bind whose marker was renamed or deleted simply stays, indefinitely, with no output.
docs accept only clears them in the full-scope case:
pub fn merge(existing: &Binds, fresh: &Binds, full_scope: bool) -> Binds {
if full_scope { fresh.clone() } else { /* extend, keeping orphans */ }
}
A full-scope accept (no PATHS) hard-errors on the first bind outside the named package, so a repo whose binds span crates cannot run one at all. Such a repo has no way to garbage-collect its lock.
Observed
A consumer upgrading to 0.2.0 found 8 orphan entries in a lock of otherwise-current binds: renamed or removed markers from earlier work, none referenced by any current page, none ever flagged by docs check under 0.1.x. Three were re-export paths whose canonical-path twins carried identical hashes.
They were cleared only as a side effect of the v2 migration: comparable() empties an older-format lock, so the partial accept wrote just what current markers referenced. On a same-format partial accept they would have survived. So the migration masked the gap rather than the gap being fixed.
soothfast's own lock is currently clean (9 locked, 0 orphans), which is why this has not surfaced here.
Why it matters
An orphan is not merely untidy. The lock is the record of which prose a human verified, so an entry nobody can trace to a page is a claim about nothing. It also inflates the diff of a legitimate migration: the consumer above had to establish that 8 disappearing entries were collection rather than drift before trusting their accept, which is real work that a report would have saved.
The failure is silent, which is the category that has cost the most here.
The mechanism already exists in the other engine
spec probe solves exactly this for probes: retain_probes computes locked-but-undeclared entries, reports each as a failure, and requires --allow-gone to drop them — the no-delete-to-go-green rule. The docs side has no equivalent.
Suggested direction
Mirror the probe behavior:
docs check reports a locked item that no scanned page binds. Whether that is a failure or a notice needs deciding: a partial-scope check only scans some pages, so an entry bound on an unscanned page would false-positive. The probe side avoids this because the manifest is always the complete declaration.
docs accept drops orphans behind --allow-gone, matching the flag that already exists for probes.
The scoping problem is the real design question and worth resolving before implementing: either the check needs to know the full set of pages, or the report belongs to a full-scope invocation only.
Problem
soothfast.lockaccumulates entries for binds that no documentation references any more, and nothing reports them.docs checkiterates the markers found in the scanned pages and looks each up in the lock (cargo-soothfast/src/docs.rs). It never walks the lock looking for the reverse: an entry with no marker pointing at it. A bind whose marker was renamed or deleted simply stays, indefinitely, with no output.docs acceptonly clears them in the full-scope case:A full-scope accept (no PATHS) hard-errors on the first bind outside the named package, so a repo whose binds span crates cannot run one at all. Such a repo has no way to garbage-collect its lock.
Observed
A consumer upgrading to 0.2.0 found 8 orphan entries in a lock of otherwise-current binds: renamed or removed markers from earlier work, none referenced by any current page, none ever flagged by
docs checkunder 0.1.x. Three were re-export paths whose canonical-path twins carried identical hashes.They were cleared only as a side effect of the v2 migration:
comparable()empties an older-format lock, so the partial accept wrote just what current markers referenced. On a same-format partial accept they would have survived. So the migration masked the gap rather than the gap being fixed.soothfast's own lock is currently clean (9 locked, 0 orphans), which is why this has not surfaced here.
Why it matters
An orphan is not merely untidy. The lock is the record of which prose a human verified, so an entry nobody can trace to a page is a claim about nothing. It also inflates the diff of a legitimate migration: the consumer above had to establish that 8 disappearing entries were collection rather than drift before trusting their accept, which is real work that a report would have saved.
The failure is silent, which is the category that has cost the most here.
The mechanism already exists in the other engine
spec probesolves exactly this for probes:retain_probescomputes locked-but-undeclared entries, reports each as a failure, and requires--allow-goneto drop them — the no-delete-to-go-green rule. The docs side has no equivalent.Suggested direction
Mirror the probe behavior:
docs checkreports a locked item that no scanned page binds. Whether that is a failure or a notice needs deciding: a partial-scope check only scans some pages, so an entry bound on an unscanned page would false-positive. The probe side avoids this because the manifest is always the complete declaration.docs acceptdrops orphans behind--allow-gone, matching the flag that already exists for probes.The scoping problem is the real design question and worth resolving before implementing: either the check needs to know the full set of pages, or the report belongs to a full-scope invocation only.