The daily sweep now compares every open card with the cards closed in the last 30 days and lists the ones another card looks to have finished, with the number of the card that did the work, under the stale list on the Astra log. Three signals, in order of how much they say and first-hit wins: the closed card's title repeats the open one's (the planner's own repeat rule), the closed card ports or follows the open card itself (`Port of #48`, `Follows #48`), or both carry the same card over. It closes nothing and labels nothing — the report is for Astra and the CEO, so the rule can stay a checkable hint instead of a verdict, and a card whose work landed under another number stops being silently ranked and queued again. The venture loop's own issues are out of both lists: they are not cards, and two signups for one venture carry the same title by design, which would have put every repeat signup on the report. A card whose `closed_at` is older than the window is dropped too, since Gitea's `since` filters on the last update. `repeat_of` moved from astra.py to router.py, which astra and housekeeping both already load, so the sweep and the planner share one copy of the rule rather than drifting apart. `refs` and `superseded` sit beside it, pure and testable. The card asked for the test in test_time.py with a World holding one superseded and one live card. The matching rule is there (check 198, two open cards: #48, whose work #139 did, and #60, which is live), and the report the sweep writes from it is checked in test_housekeeping.py, where the sweep's own fake forge lives — test_time.py's World drives the heartbeat and cannot run the sweep. No workflow change is needed: housekeeping.yml already runs the whole sweep. Closes #198 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116Joj4QVA1Gg2WrUmbbfRT