Add optional automated pipeline: collect / generate / eval / prune#8
Add optional automated pipeline: collect / generate / eval / prune#8Abukhadeejah wants to merge 2 commits into
Conversation
… cards out Implements the six framework steps as four schedulable commands (collect / generate / eval / prune) for people who already collect signals into Postgres+pgvector. The manual workflow is unchanged. - pgvector semantic clustering (HTTP endpoint or Supabase match_signals RPC) - strong-cluster gates: recurring (>=3 sources), platform diversity, distinct authors (one person repeating themselves is not a trend) - citation allowlist guard: URLs the model never received get de-linked - faithfulness LLM-judge (0-100 groundedness) + link liveness checks - conservative prune lifecycle: active -> probation -> retired, archived never deleted, dry-run by default Zero new required dependencies: everything network-facing imports httpx lazily, so the core package and CI stay dependency-free. Pipeline extras install via pip install "bookmark-maxxing[pipeline]".
|
Arsalan, this is a strong direction and very aligned with where Bookmark Maxxing should go. I reviewed it locally and the core test suite passes:
Before we merge, can you patch two things?
Right now
A generated name like Please add tests for:
The docs and PR body say the pipeline uses strong gates: recurring sources, platform diversity, and distinct authors. In code, Please either:
My preference is to enforce Suggested tests:
Once those two are fixed, I think this becomes a very mergeable contribution. The architecture is promising: optional extras, lazy network imports, read-only collection, citation allowlist, eval history, and conservative pruning are all the right shape for this repo. |
… gates - sanitize_slug() normalizes LLM-generated name/domain to kebab-case and rejects path-like input (separators, '..', absolute paths); resolved output path is asserted to stay under PIPELINE_OUTPUT_DIR before any write or archive move - all three gates (recurring, diversity, distinct-authors) are now hard: cmd_generate skips with the named failing gate(s) before any LLM call; collect output gains "strong" + "failed_gates" fields - prune guards the archive move against unsafe DB-sourced names - docs updated; 8 new tests (traversal/absolute/domain rejection, valid name writes, per-gate skip reporting)
|
Both addressed in 4c51d3e — thanks for the sharp review. 1. Path sanitization — added 2. Gates now hard, per your preference — CI re-verified locally: 51 tests pass under |
bennewell35
left a comment
There was a problem hiding this comment.
Approved. Thanks for the quick, precise follow-up.
I re-reviewed commit 4c51d3e locally and verified the two blockers are addressed:
- generated skill names/domains are sanitized before filesystem writes
- path traversal and absolute paths are rejected
- archive/prune paths use the same containment guard
- strong-cluster gates are now enforced before generation
collectreportsstrongandfailed_gates
Local verification on the updated branch:
PYTHONPATH=src python3 -m unittest discover -s tests-> 51 tests passedpython3 -m compileall -q src tests-> cleangit diff --check-> clean- manual path check rejected
../../escaped-skilland/tmp/escaped, while normalizing a valid name safely underPIPELINE_OUTPUT_DIR
This is a strong contribution and a meaningful step toward making Bookmark Maxxing a real signal-to-skill pipeline.
Proposal issue: #7
Summary
Optional, fully automated implementation of the six framework steps for people who already collect signals into Postgres+pgvector. The manual workflow in
framework.mdis unchanged — this is purely additive, as abookmark_maxxing.pipelinesubpackage with its own console scriptbookmark-maxxing-pipeline.collect "<theme>"— ranked semantic matches from your own signal store (HTTP or Supabase RPC), read-onlygenerate: recurring (>=3 sources), platform diversity, distinct authorsgenerate "<theme>"— LLM writes a card pertemplates/skill-card.md, primary sources onlyskills/<domain>/<name>/+ upsert toskill_cardstableeval(faithfulness judge + link liveness) +prune(active → probation → retired, archived never deleted, dry-run by default)Anti-hallucination: a citation allowlist guard de-links any URL the model didn't receive in the signals (text kept, link dropped).
Zero new required dependencies
Everything network-facing (
httpx) is imported lazily inside the functions that use it, so the core package and the dependency-free CI (unittest discoveron bare 3.10/3.11/3.12) are untouched. Pipeline users opt in withpip install "bookmark-maxxing[pipeline]".Files
src/bookmark_maxxing/pipeline/— config, llm, collect, gates, generate, evaluate, prune, adapters, clischemas/skills-table.sql—skill_cardstable + commentedmatch_signalsRPC contractdocs/automated-pipeline.md— setup + usagetests/test_pipeline.py— pure-logic unittest coverage: gates, citation guard, frontmatter, prune decisions (no network/DB).env.example— new optional "Automated pipeline" sectionpyproject.toml—[pipeline]extra + second console scriptTest plan
PYTHONPATH=src python3 -m unittest discover -s tests— 43 tests pass (existing + 18 new)python3 -m compileall -q src testscleangit diff --checkclean