fix: prune unstarred repos from Rejected Additions in star scan

The star scan pruned unstarred repos from its untracked ledger but left their Rejected Additions lines in docs/audit-logs.md, so that list went stale after unstars.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Vinta Chen
2026-11-08 22:04:43 +08:00
co-authored by Claude
parent b2e37f102d
commit 66c764a67d
3 changed files with 33 additions and 3 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ A star scan turns the maintainer's GitHub stars into proposed additions. Every s
## 1. Scan
Run `uv run python .claude/skills/scan-github-stars/scripts/scan_github_stars.py`, adding `--full` when the argument is `full`. With no ledger yet, a plain run already covers every star. Print the drop and prune counts from stderr. Done when the candidate TSV is in hand.
Run `uv run python .claude/skills/scan-github-stars/scripts/scan_github_stars.py`, adding `--full` when the argument is `full`. With no ledger yet, a plain run already covers every star. Print the drop and prune counts from stderr. When it pruned Rejected Additions lines, commit `docs/audit-logs.md` on its own, since unlike the ledger it is tracked. Done when the candidate TSV is in hand.
## 2. Screen
@@ -6,7 +6,8 @@ recomputed every run, so a repo that becomes active again resurfaces. An
incremental run also drops stars already judged: model screen-outs in
local/starred-scan.tsv and maintainer rejections under docs/audit-logs.md
"Rejected Additions". `--full` keeps them and shows the earlier verdict in the
`prior` column. Ledger rows for repos no longer starred are pruned each run.
`prior` column. Ledger rows and Rejected Additions lines for repos no longer
starred are pruned each run.
Prints survivors as TSV on stdout, drop and prune counts on stderr.
"""
@@ -93,6 +94,22 @@ def prune_ledger(starred: set[str]) -> int:
return len(rows) - len(kept)
def prune_register(starred: set[str]) -> int:
"""Drop Rejected Additions lines for repos no longer starred; `owner/*` patterns stay."""
lines = REGISTER.read_text().splitlines(keepends=True)
start = lines.index("## Rejected Additions\n")
end = next((i for i in range(start + 1, len(lines)) if lines[i].startswith("## ")), len(lines))
kept = []
for line in lines[start:end]:
match = REJECTED_LINE_RE.match(line)
if match and not match.group(1).endswith("/*") and match.group(1).lower() not in starred:
continue
kept.append(line)
if len(kept) < end - start:
REGISTER.write_text("".join(lines[:start] + kept + lines[end:]))
return end - start - len(kept)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--full", action="store_true", help="rejudge stars already screened out or rejected")
@@ -104,7 +121,9 @@ def main() -> None:
prior = prior_verdicts()
stars: list[Star] = [json.loads(line) for line in gh("api", "--paginate", "user/starred?per_page=100", "--jq", ".[]").splitlines()]
pruned = prune_ledger({star["full_name"].lower() for star in stars})
starred = {star["full_name"].lower() for star in stars}
pruned = prune_ledger(starred)
pruned_rejections = prune_register(starred)
dropped = Counter()
print("repo\tlanguage\tstars\tpushed\ttopics\tdescription\tprior")
for star in stars:
@@ -131,6 +150,8 @@ def main() -> None:
print(f" dropped {count}: {reason}", file=sys.stderr)
if pruned:
print(f" pruned {pruned} ledger rows for repos no longer starred", file=sys.stderr)
if pruned_rejections:
print(f" pruned {pruned_rejections} Rejected Additions lines for repos no longer starred", file=sys.stderr)
if __name__ == "__main__":
+9
View File
@@ -122,6 +122,15 @@ def test_ledger_rows_keyed_by_github_url(scan):
assert module.LEDGER.read_text() == kept
def test_unstarred_repos_are_pruned_from_rejected_additions(scan):
module, _, run = scan
kept = "## Rejected Additions\n- Example/Project -- 2026-10-16: kept\n- gone/* -- 2026-10-16: organization pattern\n"
module.REGISTER.write_text(kept + "- gone/repo -- 2026-10-16: unstarred\n\n## Last Audited\n")
assert "pruned 1 Rejected Additions" in run("--full").err
assert module.REGISTER.read_text() == kept + "\n## Last Audited\n"
def test_parking_keeps_other_exclusions(scan):
module, star, run = scan
now = datetime.now(UTC)