Files
rsspipe/docs/005_rules_and_hooks_specification.md
T

9.9 KiB

RSSPipe Rules & Automation Hooks Specification (005_rules_and_hooks_specification.md)

1. Overview & Vision

The Rules & Hooks Engine is the reactive event-processing backbone of RSSPipe. It connects the ingestion lifecycle with the Multi-Variant Data Store (entry_variants), allowing users to automate content enrichment (scraping, tagging, AI, audio), triage (read, starred, archive), and notifications without writing code.


2. Core Mental Model: 3-Level Execution Flow

Every Rule is evaluated deterministically using a three-level hierarchy:

graph TD
    A[Level 1: Event Trigger] --> B{Level 2: Conditions Evaluator}
    B -- All / Any Match --> C[Level 3: Action Execution Pipeline]
    B -- No Match --> D[No Action]
    C --> E[Store Variant / Mutate Status / Dispatch Event]
    E -. New Variant Event .-> A

3. Level 1: Event Triggers

The trigger specifies when a rule is evaluated.

Trigger Type Identifier Description Sub-Options / Parameters
New Entry Ingested new_entry (on_post_created) Fires immediately after an article is discovered and parsed by crawler/OPML. None
Variant Changed variant_change (on_variant_updated) Fires when a specific variant key is added, updated, or deleted. Sub-Choice (Event Type):
• key_added (Key didn't exist, now created)
• value_changed (Key existed, value modified)
• key_deleted (Variant removed)
Target Key Filter:
• Specific variant_key (e.g. keywords, readability_full_text, ai_summary) or * (any variant).
Cron Schedule (Future) cron Recurring background schedule (e.g., daily digests, archival runs). Cron expression (e.g. 0 8 * * *)
Manual Execution manual Triggered on-demand via UI or API. None

4. Level 2: Conditions & Allowlisted Fields

Rules evaluate conditions against an allowlist of strongly typed fields. The UI dynamically presents appropriate operators and input controls based on the field type.

4.1 Allowlisted Fields & Operators

Field Name Type Allowed Operators UI Input Type & Behavior Example Evaluation
feed_id string / set ==, !=, in, not_in Multi-Select Feed Picker with search, "Select All", and "Invert" buttons. feed_id in ["feed-1", "feed-2", ...] (Applies to 24/30 feeds in 2 clicks)
category_id string / set ==, !=, in, not_in Category Dropdown / Multi-Select Chips. category_id in ["cat-tech", "cat-ai"]
title string contains, not_contains, ==, !=, matches (regex), starts_with, ends_with Text input or comma-separated token badges. title contains "DeepSeek"
raw_content / content string contains, not_contains, matches (regex) Text input. content contains "breaking news"
author string contains, not_contains, ==, != Text input. author == "Paul Graham"
created_at / published_at timestamp >=, <=, within_last_hours, older_than_days Number + unit dropdown (e.g. "Within last 24 hours"). published_at within_last_hours 48
is_read boolean ==, != Toggle (Read / Unread). is_read == false
is_starred boolean ==, != Toggle (Starred / Not Starred). is_starred == true
variants.<key> variant_value exists, not_exists, contains, not_contains, ==, != Key name + value input. variants.keywords contains "LLM"

4.2 Match Modes

  • all (AND): Every condition in the rule must evaluate to true.
  • any (OR): At least one condition must evaluate to true.

5. Level 3: Action Execution Pipeline

When a rule's conditions are satisfied, one or more actions execute sequentially.

5.1 Supported Core Actions

Action Identifier Parameters Description
set_variant variant_key (string), value (string/json/yaml), content_type (string) Adds or updates a key-value variant (e.g., adding tags, keywords, custom annotations).
readability_scrape None Fetches webpage full-text HTML and stores in entry_variants(key='readability_full_text').
mark_read None Sets is_read = true (auto-triage/archive).
mark_starred None Sets is_starred = true.

6. Safety Architecture: Endless Loop Prevention

Because actions like set_variant emit on_variant_updated events, rules could theoretically trigger cyclic loops (e.g., Rule A triggers on variant_change for key="tags" and adds a new tag to key="tags").

Loop Guard Mechanisms

  1. Static Validation (Rule Creation Time):
    • If Trigger is variant_change on key="X" and an Action is set_variant on key="X", the UI / API warns and rejects identical recursive rules unless an explicit guard predicate (e.g., value not contains "Y") is specified.
  2. Runtime Execution Context & Depth Guard:
    • Every event emitted by the Event Bus carries a RecursionDepth: int (max depth = 5) and ExecutionPath: []string tracking rule IDs.
    • If an event exceeds depth 5 or encounters the same Rule ID in its call stack, execution is aborted with an error log: WARN: Cyclic rule execution aborted for rule: {rule_id}.

7. UI/UX Design Specification for Settings

7.1 Rule List View

  • Clean card layout grouped by Trigger type (New Entry, Variant Change, Cron).
  • Card shows a natural language sentence:

    "When New Post Arrives in 24 Feeds and Title contains 'AI' \rightarrow Scrape Full Text, Mark Starred"

  • Toggle switch (Active/Inactive), Edit button, Test button, Delete button.

7.2 Interactive Rule Builder Modal Layout

┌────────────────────────────────────────────────────────────────────────┐
│ Create Automation Rule                                           [ ✕ ] │
├────────────────────────────────────────────────────────────────────────┤
│ Rule Name: [ Auto-Scrape Tech Feeds                                  ] │
│                                                                        │
│ 1. WHEN (Trigger)                                                      │
│    (●) New Entry Arrives       ( ) Variant Changed      ( ) Schedule   │
│                                                                        │
│    [If Variant Changed Selected]                                       │
│    Event: [ Key Added ▼ ]   Target Key: [ keywords                   ] │
│                                                                        │
│ 2. IF (Conditions)                       Match: [ All Conditions (AND) ]│
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │ Field: [ Feed ID ▼ ]   Op: [ In List (24 Feeds) ▼ ]             │ │
│    │ [ Quick Select: All | None | Invert ]                           │ │
│    │ [✓] Hacker News  [✓] 36Kr  [✓] FT Chinese  [✓] InfoQ  [ ] Douban│ │
│    │                                                      [ ✕ Remove]│ │
│    ├─────────────────────────────────────────────────────────────────┤ │
│    │ Field: [ Title ▼ ]     Op: [ Contains Any ▼ ]                   │ │
│    │ Value: [ AI, LLM, Machine Learning                            ] │ │
│    │                                                      [ ✕ Remove]│ │
│    └─────────────────────────────────────────────────────────────────┘ │
│    [ + Add Condition ]                                                 │
│                                                                        │
│ 3. THEN DO (Actions)                                                   │
│    [✓] ⚡ Scrape Full Text (Readability)                                │
│    [✓] ⭐ Mark as Starred                                               │
│    [ ] 🏷️ Set Variant / Tag -> Key: [tags     ] Val: [ai-digest      ] │
│    [ ] ✓ Mark as Read                                                  │
│                                                                        │
│ [ Cancel ]                                         [ Create Rule ]     │
└────────────────────────────────────────────────────────────────────────┘

8. Backlog Roadmap for Rules & Hooks

The following capabilities are reserved for upcoming iterations:

  1. Auto-Delete / Retention Rule Action (delete_entry):
    • Scope: Automatically delete matching entries older than N days (requires retention policy discussion).
  2. Aggregated Shares & Auto-Share Action (share_entry):
    • Scope: Action to automatically generate public share links for high-priority articles, plus a dedicated /shares dashboard aggregating all shared items.
  3. Advanced AI & Audio Pipeline Actions:
    • generate_ai_summary: Calls LLM to summarize content \rightarrow stores in entry_variants.ai_summary.
    • generate_tts: Synthesizes article voice audio \rightarrow stores .mp3 blob in ./data/blobs/{id}/tts.mp3.
    • generate_podcast: Generates dual-speaker conversational audio discussions.