Skip to content

feat: wiki/candidates/ approval workflow#230

Merged
Pratiyush merged 1 commit into
masterfrom
feat/51-candidates-workflow
Apr 17, 2026
Merged

feat: wiki/candidates/ approval workflow#230
Pratiyush merged 1 commit into
masterfrom
feat/51-candidates-workflow

Conversation

@Pratiyush
Copy link
Copy Markdown
Owner

Closes #51

Summary

Quality gate for LLM-generated wiki pages: new entities/concepts land in wiki/candidates/ and require human review before promotion. Discard is non-destructive (archive with reason).

PR Checklist

  • 34 candidates tests pass
  • 12th lint rule (stale_candidates) registered
  • /wiki-review slash command shipped
  • CLI llmwiki candidates list|promote|merge|discard works
  • 1431 tests total
  • CHANGELOG updated
  • GPG-signed, no AI co-author

New llmwiki/candidates.py with full promote/merge/discard workflow
for LLM-generated entity + concept pages.

Problem: /wiki-ingest can hallucinate entities. Before this PR they
landed in wiki/entities/ directly and were only caught by later lint.

Solution: new pages land in wiki/candidates/<kind>/<slug>.md with
status: candidate. Human reviews via /wiki-review (or CLI
'llmwiki candidates list|promote|merge|discard').

Public API:
  list_candidates(wiki_dir) -> list[Candidate]
  promote(slug, wiki_dir, kind?) -> Path
  merge(slug, wiki_dir, into_slug=..., kind?) -> Path
  discard(slug, wiki_dir, reason='', kind?) -> Path
  stale_candidates(wiki_dir, threshold_days=30) -> list[Candidate]
  is_candidate(path) -> bool

Promote rewrites frontmatter 'status: candidate' → 'status: reviewed'.
Merge appends candidate body under ## Candidate merge — <date> in
the target page, then archives the candidate.
Discard moves to wiki/archive/candidates/<timestamp>/ with a
.reason.txt audit-trail file.

New lint rule 'stale_candidates' (12th overall) reports candidates
sitting > 30 days as info severity.

New slash command: .claude/commands/wiki-review.md walks the workflow.

34 tests cover: list (empty/missing-dir/skip-context/preview/age),
all 3 action paths + error cases, status rewrite (replace/add),
staleness computation, CLI + slash-command + lint-rule registration.

Closes #51
@Pratiyush Pratiyush added this to the v1.1.0 milestone Apr 17, 2026
@Pratiyush Pratiyush added the feat New feature label Apr 17, 2026
@Pratiyush Pratiyush merged commit 51f628c into master Apr 17, 2026
6 of 8 checks passed
@Pratiyush Pratiyush deleted the feat/51-candidates-workflow branch April 17, 2026 21:54
Pratiyush added a commit that referenced this pull request Apr 17, 2026
Two regressions from the candidates workflow (PR #230) surfaced on
CI after merge:

1. StaleCandidates lint rule referenced `Path` without importing it,
   so the rule raised NameError against any real page — the seeded
   wiki lint job crashed on every push.
2. tests/test_candidates.py used a nested f-string with a backslash
   inside the expression, which Python 3.9 rejects at parse time
   (only 3.12+ allows backslashes in f-string parts).

Both are narrowly scoped:
- Add `from pathlib import Path` inside StaleCandidates.run()
  (matches existing lazy-import style).
- Extract the default body into a local variable in
  _write_candidate().

Regression test added in tests/test_lint_rules.py that exercises
the rule end-to-end — the same failure path CI hit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(v0.5): wiki/candidates/ approval workflow for LLM-generated pages

1 participant