Skip to content

feat(hooks): intake-sweep feeds deferred-link sources into the staging funnel#279

Merged
tieubao merged 2 commits into
masterfrom
feat/intake-sweep
Jul 20, 2026
Merged

feat(hooks): intake-sweep feeds deferred-link sources into the staging funnel#279
tieubao merged 2 commits into
masterfrom
feat/intake-sweep

Conversation

@tieubao

@tieubao tieubao commented Jul 20, 2026

Copy link
Copy Markdown
Member

What

hooks/intake-sweep.py + shim: sweep a consumer's persisted "review later" sources (digest keeper ledger, saved browser collections, any future store) into the _meta/backlog-staging.md funnel, through the one staging-block grammar, keeping board promote as the human gate. Wired into backlog-stage.sh --surface so the existing SessionStart hook line is the single install point.

Why

Session transcripts already flow to the board via backlog-stage, but deferred-link stores had no promote path (ops-toolkit ID-379). The kit stays personal-data-free: sources are declared per-consumer in _meta/intake-sources.json; no config = silent no-op for every other consumer.

Design points

  • Adapter kinds: jsonl (field filter + field map) and command (JSON array on stdout). Per-source fail-safe; 15s command timeout; always exits 0.
  • Dedup: norm-title vs board+staging, URL membership in either file, plus a durable swept-keys state file (a promoted/rejected key is never re-proposed).
  • Daily self-throttle (INTAKE_SWEEP_MIN_INTERVAL), --force for manual/test runs.

Test

bash tests/test-intake-sweep.sh, 19 assertions, hermetic (temp repos, no model call): both adapter kinds, all three dedup layers with negative controls (skip-verdict, board dup, staging-url dup, promoted-away key), config gate, throttle, and the --surface wiring end to end. Regression: test-learn-drain, test-learn-propose, test-board all PASS.

tieubao added 2 commits July 20, 2026 12:42
…g funnel

backlog-stage harvests session transcripts into _meta/backlog-staging.md, but
persisted "review later" stores (a digest keeper ledger, saved browser
collections) had no path into the board funnel at all. intake-sweep.py closes
that: generic jsonl + command adapters, declared per-consumer in
_meta/intake-sources.json (the kit carries no personal paths; no config file
means silent no-op), rendering through the ONE staging-block grammar
(lib/learn/staging-format.py) so `board promote` keeps the human gate.

Dedup is three-layered and durable: normalized title vs board + staging (all
block states), URL membership in either file (catches renamed rows), and a
swept-keys state file so a once-staged key is never re-proposed after promote/
reject. Self-throttles to daily; adapter failures are per-source fail-safe;
always exits 0.

Wiring: backlog-stage.sh runs the sweep on its --surface pass, so the existing
SessionStart hook line is the single install point and the surfaced candidate
count already includes swept items.

Tests: tests/test-intake-sweep.sh (19 assertions, hermetic) covering both
adapter kinds, all three dedup layers with negative controls, the config gate,
the throttle, and the surface wiring end to end.
The meta-integrity suite pins README layout/summary/table counts and the
architecture fallback-layer table to the live hooks/*.sh census; the new
hook made them 24.
@tieubao
tieubao merged commit b6aadf1 into master Jul 20, 2026
2 checks passed
@tieubao
tieubao deleted the feat/intake-sweep branch July 20, 2026 05:53
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