Skip to content

feat(enrich): thin-page enrichment proposes expansions for stub pages#403

Open
claytonlin1110 wants to merge 2 commits into
vouchdev:testfrom
claytonlin1110:feat/thin-page-enrichment
Open

feat(enrich): thin-page enrichment proposes expansions for stub pages#403
claytonlin1110 wants to merge 2 commits into
vouchdev:testfrom
claytonlin1110:feat/thin-page-enrichment

Conversation

@claytonlin1110

Copy link
Copy Markdown
Contributor

summary

implements #309: a maintenance pass that finds thin pages (stub title + one-line body, few or no claims/sources) and drafts an enriched revision synthesized strictly from related approved material already in the kb.

  • kb.enrich_page (+ mcp/jsonl/cli registration across all four surfaces, src/vouch/enrich.py) scores one page against enrichment.min_body_chars / enrichment.min_citations (config.yaml, sane defaults, overridable per-invocation). a page is thin when len(page.body) is under the char threshold or len(page.claims) + len(page.sources) is under the citation threshold.
  • candidate material is gathered by reusing synthesize.synthesize (feat: kb.synthesize — answer-mode retrieval over the review-gated KB #222) against the page's title+body as query, rather than re-deriving clauses from context.build_context_pack directly — this keeps the "every sentence traces to an approved claim" invariant identical between the two features and only pulls approved, non-retracted claims.
  • the synthesized addition is appended to the page's existing body (a stub's hand-written text is never discarded or overwritten), and the cited claim ids / their evidence source ids are unioned into the page's claims / sources.
  • the enriched page is filed via propose_page with slug_hint set to the existing page id, landing as a pending proposal — nothing is written durably without a human kb.approve. mirrors compile.py's propose-never-approve shape, including a distinct page-enricher actor so self-approval stays blocked by the default gate.
  • vouch enrich-pages batches this over kb.list_pages(), with --dry-run, --min-body-chars, --min-citations, --limit, --json; one page's rejection (e.g. a page kind's required fields tightened since last approval) is recorded as a skip rather than sinking the batch.
  • docs/enrich.md + CHANGELOG entry.

test plan

  • tests/test_enrich_page.py — thin-page selection (both thresholds), above-threshold / no-related-claim skips, the propose-not-write invariant (proposal then approve revises the existing page, not a duplicate), dry-run, every-sentence-has-a-resolvable-citation, config load (present/default/bad-value fallback), batch dry-run + --limit, audit event, capabilities/HANDLERS parity, jsonl wire (success + clean missing-page error)
  • ruff check src tests clean
  • mypy src clean (no new errors beyond the pre-existing sandbox.py win32 / missing-jinja2 gaps on this machine)
  • targeted pytest (enrich, synthesize, compile, storage, capabilities) green aside from two pre-existing, unrelated failures confirmed present on a pristine upstream/test checkout too (the host_compat/openclaw-manifest tests, and test_jsonl_kb_compile_files_proposals's use of a cat stub llm_cmd, which doesn't exist as a Windows shell built-in)

🤖 Generated with Claude Code

adds kb.enrich_page plus vouch enrich-page / enrich-pages: scores a page
against enrichment.min_body_chars / enrichment.min_citations in
config.yaml and, for a qualifying thin page, drafts an addition
synthesized strictly from approved, non-retracted claims already in the
kb (reusing kb.synthesize's rendering so every added sentence carries a
resolvable [claim_id] citation). the addition is appended to the page's
existing body and filed via propose_page with slug_hint set to the
existing page id -- nothing is ever written durably, only proposed.
enrich-pages batches this over all thin pages with --dry-run / --limit,
mirroring compile.py's propose-never-approve shape.

closes vouchdev#309
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7bd3a1de-4d4f-41fa-8b12-4d3f6773fc0f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added docs documentation, specs, examples, and repo guidance cli command line interface mcp mcp, jsonl, and http surfaces storage kb storage, migrations, schemas, and proposals tests tests and fixtures size: L 500-999 changed non-doc lines labels Jul 6, 2026
kb.capabilities' host_compat block read openclaw.compat.pluginApi from
openclaw.plugin.json, but the manifest deliberately excludes a
top-level "openclaw" key (test_openclaw_plugin_manifest.py's
dead-dialect-fields check) -- so _load_host_compat() always returned
{}, failing the vouchdev#237 drift tests unconditionally. package.json is the
one place openclaw.compat.pluginApi actually lives; point the reader
(and the mirroring test fixture) there instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli command line interface docs documentation, specs, examples, and repo guidance mcp mcp, jsonl, and http surfaces size: L 500-999 changed non-doc lines storage kb storage, migrations, schemas, and proposals tests tests and fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant