On this page
Dev-overlay sentinel loading and venv inspection, shared between the ``rlsbl dev sync``/``dev status`` commands and the ``dev-overlay-drift`` check.
#rlsbl.overlay_state
#rlsbl.overlay_state
Dev-overlay sentinel loading and venv inspection, shared between the rlsbl dev sync/dev status commands and the dev-overlay-drift check.
Extracted from commands/dev_sync.py to break the checks/ -> commands/ layering violation: checks/project.py's dev-overlay-drift check needs to read the overlay sentinel and inspect the venv, but the checks layer must not import the commands layer. This module hosts the read-side logic (sentinel loading, venv dist-info inspection, overlay classification) so both layers can consume it without a cross-layer import. The write-side (_write_sentinel) and the sync orchestration stay in commands/dev_sync.py, which is the only writer.
Pure relocation -- no behavior change from the original dev_sync definitions.
#MalformedSentinelError
Raised when the overlay sentinel exists but cannot be parsed or read.
A present-but-corrupt sentinel must never read as "no overlays declared" (which would silently SKIP the drift check and exit dev status 0). The sentinel is regenerable local state, so the remedy is to delete it and re-run rlsbl dev sync. Callers surface this loudly rather than degrading.
#_normalize
def _normalize(name)PEP 503 distribution-name normalization.
#load_sentinel
def load_sentinel(project_root)Read SENTINEL_FILENAME. Returns a list of {"package", "path", "version"} dicts, or None when the sentinel does not exist.
A missing sentinel means no overlays were ever declared -- e.g. a fresh CI checkout, where the gitignored sentinel never existed. That is the honest not-applicable state (skip), never a failure.
A present-but-unparseable sentinel (invalid TOML) or a present-but- unreadable one (OSError) is a hard error (:class:MalformedSentinelError), NEVER a silent empty list: reading corruption as "no overlays" would make the drift check SKIP and dev status exit 0 while overlays may in fact be wiped. Mirrors _load_overlays, which also hard-errors on invalid TOML.
#_venv_site_packages
def _venv_site_packages(project_root)Return existing site-packages directories under the project's .venv (one per Python minor version present).
#_read_dist_info_metadata
def _read_dist_info_metadata(dist_info)Return (name, version) from a *.dist-info directory's METADATA file, falling back to the directory-name split when METADATA is absent. Either element may be None if unreadable.
#_read_direct_url
def _read_direct_url(dist_info)Return (editable, path) from a dist-info's direct_url.json.
A registry wheel has no direct_url.json -> (False, None). A uv editable install writes dir_info.editable = true and a file:// url pointing at the checkout -> (True, "/abs/checkout"). A non-editable local install -> (False, "/abs/path").
#inspect_installed
def inspect_installed(project_root, package)Inspect the project's .venv for how package is installed.
Returns {"found", "editable", "path", "version"}:
found=False: no dist-info for package in the venv (missing).editable=Truewithpath: uv editable install;pathis the
file:// checkout it points at.
editable=False: a registry wheel or non-editable install -- i.e. the
overlay was wiped.
#classify_overlay
def classify_overlay(entry, installed)Compare a sentinel entry against the installed venv state.
Returns (state, detail) where state is OVERLAY_HEALTHY / OVERLAY_WIPED / OVERLAY_MISSING and detail is a human-readable line naming the package and the exact rlsbl dev sync remediation.