feat(wiki): Phase 7 — active_lint_tracked + loop integration#8371
Merged
HydraOps-T-rav merged 2 commits intomainfrom Apr 20, 2026
Merged
feat(wiki): Phase 7 — active_lint_tracked + loop integration#8371HydraOps-T-rav merged 2 commits intomainfrom
HydraOps-T-rav merged 2 commits intomainfrom
Conversation
Closes the last gap from Phase 4: the ``RepoWikiLoop`` lint pass now
writes to the tracked per-entry layout, producing the uncommitted
diffs that ``_maybe_open_maintenance_pr`` turns into ``chore(wiki):
maintenance`` PRs.
New module-level helpers in src/repo_wiki.py
- ``_split_tracked_entry(text)`` — forgiving frontmatter parser that
returns (fields, raw block, body) without pydantic validation.
- ``_update_tracked_entry_status(text, *, status, stale_reason=None)``
— rewrites the ``status:`` frontmatter line and optionally adds
``stale_reason``, preserving field order.
- ``_tracked_entry_age_days(fields, now)`` — parses ``created_at`` and
returns day delta for the 90-day prune window.
- ``active_lint_tracked(tracked_root, repo_slug, closed_issues)`` —
scans ``{tracked_root}/{repo_slug}/{topic}/*.md``, flips
``status: active`` → ``status: stale`` with ``stale_reason`` for
entries whose ``source_issue`` int is in the closed set, and
prunes stale entries older than 90 days.
RepoWikiLoop
- ``_do_work`` now computes ``tracked_root`` when
``config.repo_wiki_git_backed`` is True, merges tracked repos into
the slug list BEFORE the no-repos early-return (a freshly-migrated
repo may only exist in the tracked location), and after the legacy
``active_lint`` call runs ``active_lint_tracked`` via
``asyncio.to_thread``. Tracked results are added to the same
counters.
- New module-level ``_list_tracked_repos(tracked_root)`` mirrors
``RepoWikiStore.list_repos``' ``index.md`` / ``index.json`` gate.
Tests (14 new)
- ``tests/test_active_lint_tracked.py`` (12) — zero-stats when missing
/ empty, flips active→stale for closed issues, skips already-stale,
ignores open + ``unknown`` source issues, prunes stale >90 days,
doesn't prune fresh stale, mark-then-not-prune in same pass,
idempotence, malformed frontmatter tolerance, counts across topics.
- ``tests/test_repo_wiki_loop_pr.py::TestTrackedActiveLintIntegration``
(2) — end-to-end flip when source issue closed, and opt-out when
``repo_wiki_git_backed=False``.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review follow-up for #8371: the 90-day prune clock runs off ``created_at`` (same as legacy ``active_lint``) rather than a separate stale-since timestamp, so an old active entry whose source issue just closed is flipped stale AND pruned in the same pass. Adds a docstring note and a regression test pinning the behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the last gap from Phase 4: the
RepoWikiLooplint pass now writes to the tracked per-entry layout, producing the uncommitted diffs that_maybe_open_maintenance_prturns intochore(wiki): maintenancePRs.Before this PR, stale flagging only happened on the legacy gitignored store, so the Phase 4 PR-opening code path was dormant. With this PR, when a source issue closes, the loop writes
status: staleintorepo_wiki/{owner}/{repo}/{topic}/*.mdand the next tick opens the maintenance PR.Helpers in
src/repo_wiki.py_split_tracked_entry(text)— forgiving frontmatter parser (no pydantic)._update_tracked_entry_status(text, *, status, stale_reason=None)— rewrites thestatus:line, optionally addsstale_reason._tracked_entry_age_days(fields, now)— for the 90-day prune window.active_lint_tracked(tracked_root, repo_slug, closed_issues)— scans{tracked_root}/{repo_slug}/{topic}/*.md, flipsactive→stalewith reason for closed source issues, prunes stale entries older than 90 days.RepoWikiLoop._do_worktracked_root = config.repo_root / config.repo_wiki_pathwhenconfig.repo_wiki_git_backedis True.active_lintcall, runsactive_lint_trackedviaasyncio.to_threadand folds its counters intostats._list_tracked_reposgates onindex.md/index.json(same asRepoWikiStore.list_repos).What's out of scope
compile_topicis still legacy-layout-only. Porting synthesis to the tracked layout is a follow-up; it requires emitting a new per-entry file and marking inputs assuperseded, plus theWikiCompilerneeds to read tracked entries.force-compile/mark-stale/rebuild-indexfrom the queue come next.Tests (14 new, 78 total pass)
tests/test_active_lint_tracked.py(12): zero-stats when missing/empty, flips active→stale, skips already-stale, ignores open +unknownsource issues, prunes >90d, doesn't prune fresh stale, mark-then-not-prune in same pass, idempotence, malformed-frontmatter tolerance, counts across topics.tests/test_repo_wiki_loop_pr.py::TestTrackedActiveLintIntegration(2): end-to-end flip when source closed; opt-out whenrepo_wiki_git_backed=False.Test plan
uv run pytest tests/test_active_lint_tracked.py tests/test_repo_wiki_loop_pr.py tests/test_wiki_maint_queue.py tests/test_repo_wiki.py— 78 passed.make lint-checkclean.make quality.chore(wiki): maintenance YYYY-MM-DDPR in HydraFlow.🤖 Generated with Claude Code