Skip to content

feat(wiki): Phase 7 — active_lint_tracked + loop integration#8371

Merged
HydraOps-T-rav merged 2 commits intomainfrom
hydraflow/wiki-active-lint-tracked
Apr 20, 2026
Merged

feat(wiki): Phase 7 — active_lint_tracked + loop integration#8371
HydraOps-T-rav merged 2 commits intomainfrom
hydraflow/wiki-active-lint-tracked

Conversation

@HydraOps-T-rav
Copy link
Copy Markdown
Collaborator

Summary

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.

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: stale into repo_wiki/{owner}/{repo}/{topic}/*.md and 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 the status: line, optionally adds stale_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, flips activestale with reason for closed source issues, prunes stale entries older than 90 days.

RepoWikiLoop._do_work

  • Computes tracked_root = config.repo_root / config.repo_wiki_path 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.
  • After the legacy active_lint call, runs active_lint_tracked via asyncio.to_thread and folds its counters into stats.
  • Module-level _list_tracked_repos gates on index.md / index.json (same as RepoWikiStore.list_repos).

What's out of scope

  • compile_topic is 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 as superseded, plus the WikiCompiler needs to read tracked entries.
  • Admin-task execution still logs-only; tracked-layout mutations for force-compile / mark-stale / rebuild-index from 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 + unknown source 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 when repo_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-check clean.
  • CI make quality.
  • After merge, the next wiki tick with a newly-closed issue produces a chore(wiki): maintenance YYYY-MM-DD PR in HydraFlow.

🤖 Generated with Claude Code

T-rav-Hydra-Ops and others added 2 commits April 20, 2026 09:34
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>
@HydraOps-T-rav HydraOps-T-rav merged commit 6a1815c into main Apr 20, 2026
22 of 23 checks passed
@HydraOps-T-rav HydraOps-T-rav deleted the hydraflow/wiki-active-lint-tracked branch April 20, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant