Skip to content

docs: a locked bind whose marker is gone is never reported and never collected #149

Description

@Verdenroz

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions