5fe8f228c1
Add a read-only /ecosystem page that consumes the sibling services' JSON APIs (Nexus entities, Praxis attention, Hexis capabilities), fetched concurrently with honest per-panel error states. Siblings stay headless — mavweb is their human surface (arch §16). Wired via mavweb -nexus/-praxis/-hexis flags; mavweb joins the ecosystem compose network. Fix mobile horizontal overflow across all pages: .content is a flex child with default min-width:auto, so it refused to shrink below the tables' intrinsic width. min-width:0 lets wide tables pan inside .scroll instead of dragging the page sideways. Verified via CDP geometry check (scrollWidth === clientWidth at 430px). Also includes in-progress Ethos UI redesign, ecosystem deploy compose, and planning docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
30 lines
2.4 KiB
Markdown
30 lines
2.4 KiB
Markdown
# Plan: RSS / News Feed Reader
|
|
|
|
**Goal:** Maven periodically polls configured RSS/Atom feeds, extracts new items, classifies them by relevance using the embedder, and either stores interesting items as notes or surfaces breaking news via the dispatcher.
|
|
|
|
**Done when:**
|
|
- `internal/rss/` package — feed parser (Go stdlib `encoding/xml` or `github.com/mmcdole/gofeed`), poll loop
|
|
- Feed config in `config.Config` — `feeds: [{name, url, category, poll_interval}]`
|
|
- New items are classified by the existing `router.Embedder` — items below a relevance threshold are silently dropped
|
|
- Interesting items: written as `WriteNote` with `source="rss:<feed_name>"`; breaking/high-severity items dispatched as care nudges (sev2-3)
|
|
- Queryable via voice: "что нового в лентах?", "что по технологиям?"
|
|
|
|
**Scope:**
|
|
- New `internal/rss/` package — periodic poller, feed parser, item classifier
|
|
- Config extension: `feeds` array in `config.Config`
|
|
- Reuses `internal/router.Embedder` for relevance scoring (same ONNX model or HashEmbedder floor)
|
|
- Reuses `internal/ipc.CoreAPI` for writing notes
|
|
- Reuses `internal/delivery.Dispatcher` for breaking news nudges
|
|
- Reuses `internal/llm.Client` for item summarization (optional, for long articles)
|
|
|
|
**Steps:**
|
|
1. Add `gofeed` or raw XML parser — `internal/rss/feed.go`: `ParseFeed(url) ([]Item, error)` where `Item{Title, Link, Summary, Published, Content}`
|
|
2. Create `internal/rss/poller.go` — `Poller` holds `[]FeedConfig`, polls each on its own interval, tracks `last_poll` per feed via a fact (`kind=config, key=rss:poll:<name>`)
|
|
3. Implement relevance classifier — embed each item's title+summary with `router.Embedder`, compare against user interest profile (built from notes/facts), drop items below threshold
|
|
4. Interesting items → `ipc.WriteNote(ctx, ts, title+"\n"+summary, embedding, "rss:<feed_name>")`
|
|
5. Breaking items (keywords: "CVE", "outage", "critical") → `ipc.WriteFact(kind=env, key=news:breaking, value=title)` → loop rule `BreakingNewsRule` (sev3) dispatches nudge
|
|
6. Wire poller into `cmd/mavend/main.go` — starts after unlock, separate goroutine
|
|
7. Add voice query handler — `"что нового?"` queries `RecentNotes` filtered by source prefix `rss:` and phrases via `phraser.PhraseQuery`
|
|
8. Add `feeds` block to `config.Config` and `deploy/mavend.json`
|
|
9. Test with a live RSS feed (e.g., `https://news.ycombinator.com/rss`) — verify items appear in notes table
|