Build the resolution of #480: the detached sweep's notices land in the record, and --ls reads them.
Scope, per the decision:
- A per-repo last-sweep note in
metadata.json beside last_fetched, overwritten on every sweep (bounded by construction, no rotation, no new file). A successful sweep clears it; a refused pack or failed fetch writes the repository and git's own words.
dl --ls and --ls --json are the reading surface. The table gets a terse marker; the JSON carries the note verbatim. Nothing new prints on the launch path.
- Not a
usize/string that conflates "no note" with "could not read": absence and presence are distinct states, per the map's constructive-modeling defaults.
- Test shape, from the ticket: a sweep whose
pack-refs refuses leaves the refusal readable in the record and visible in --ls, asserted end to end. Today no test can distinguish the notice being raised from being read; this closes that.
Facts already verified on the map (fact-finder trace, 2026-08-29): ProcessRunner::detach nulls all three fds (devlaunch-runner/src/lib.rs:660); the --update-cache child's say() is eprintln! into that null (dl/src/commands.rs:346, :355); there is no existing persist-and-print mechanism — the #481 retired-key notice re-derives from config.toml on every run and writes nothing — so this deliberately introduces the first background-learned condition that survives to a foreground run.
Build the resolution of #480: the detached sweep's notices land in the record, and
--lsreads them.Scope, per the decision:
metadata.jsonbesidelast_fetched, overwritten on every sweep (bounded by construction, no rotation, no new file). A successful sweep clears it; a refused pack or failed fetch writes the repository and git's own words.dl --lsand--ls --jsonare the reading surface. The table gets a terse marker; the JSON carries the note verbatim. Nothing new prints on the launch path.usize/string that conflates "no note" with "could not read": absence and presence are distinct states, per the map's constructive-modeling defaults.pack-refsrefuses leaves the refusal readable in the record and visible in--ls, asserted end to end. Today no test can distinguish the notice being raised from being read; this closes that.Facts already verified on the map (fact-finder trace, 2026-08-29):
ProcessRunner::detachnulls all three fds (devlaunch-runner/src/lib.rs:660); the--update-cachechild'ssay()iseprintln!into that null (dl/src/commands.rs:346,:355); there is no existing persist-and-print mechanism — the #481 retired-key notice re-derives fromconfig.tomlon every run and writes nothing — so this deliberately introduces the first background-learned condition that survives to a foreground run.