bulk commit changes!

This commit is contained in:
2026-02-13 02:32:06 -05:00
parent c8f98c54c9
commit bf4a40f533
152 changed files with 2210 additions and 19 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-12

View File

@@ -0,0 +1,95 @@
## Context
ClawFort currently stores and displays full headline/summary text from the ingestion pipeline and renders feed content directly in cards/hero. There is no dedicated concise summary format, modal reading experience, or summary-specific analytics lifecycle.
This change introduces a structured summary artifact per fetched article, with template-driven rendering and event instrumentation.
Constraints:
- Reuse existing Perplexity integration for generation.
- Keep source attribution visible and preserved.
- Prefer royalty-free image retrieval via MCP integration when available, with deterministic fallback path.
- Ensure modal interactions are fully tagged in Umami.
## Goals / Non-Goals
**Goals:**
- Generate and persist concise summary content at ingestion time.
- Persist and return template-compatible summary fields and image metadata.
- Present summary in a modal dialog with required visual structure.
- Track modal open/close/link-out analytics events consistently.
**Non-Goals:**
- Replacing the existing core feed API model end-to-end.
- Building a full long-form article reader.
- Introducing user-authored summary editing workflows.
- Supporting arbitrary analytics providers beyond current Umami hooks.
## Decisions
### Decision: Persist structured summary fields alongside article records
**Decision:** Store summary artifacts as explicit fields (TL;DR bullets, summary body, citation/source, summary image URL/credit) linked to each article.
**Rationale:**
- Enables deterministic API response shape for modal rendering.
- Keeps summary retrieval simple at read time.
- Avoids dynamic prompt regeneration during page interactions.
**Alternatives considered:**
- Generate summary on-demand at modal open: rejected due to latency and cost spikes.
- Store a single blob markdown string only: rejected due to weaker field-level control and analytics granularity.
### Decision: Use Perplexity for summary generation with strict output schema
**Decision:** Prompt Perplexity to return machine-parseable JSON fields that map directly to the template sections.
**Rationale:**
- Existing Perplexity integration and operational familiarity.
- Structured output reduces frontend parsing fragility.
**Alternatives considered:**
- Free-form text generation then regex parsing: rejected as brittle.
### Decision: Prefer MCP royalty-free image sourcing, fallback to deterministic non-MCP source path
**Decision:** When MCP image retrieval integration is configured, use it first; otherwise use a configured royalty-free provider path and fallback placeholder.
**Rationale:**
- Satisfies preference for MCP leverage while preserving reliability.
- Maintains legal/licensing constraints and avoids blocked ingestion.
**Alternatives considered:**
- Hard dependency on MCP only: rejected due to availability/runtime coupling risk.
### Decision: Add modal-specific analytics event contract
**Decision:** Define and emit explicit Umami events for summary modal open, close, and source link-out clicks.
**Rationale:**
- Makes summary engagement measurable independently of feed interactions.
- Prevents implicit/ambiguous event interpretation.
**Alternatives considered:**
- Reusing existing generic card click events only: rejected due to insufficient modal-level observability.
## Risks / Trade-offs
- **[Risk] Summary generation adds ingest latency** -> Mitigation: bounded retries and skip/fallback behavior.
- **[Risk] Provider output schema drift breaks parser** -> Mitigation: strict validation + fallback summary text behavior.
- **[Risk] Royalty-free image selection may be semantically weak** -> Mitigation: relevance prompt constraints and placeholder fallback.
- **[Trade-off] Additional stored fields increase row size** -> Mitigation: concise field limits and optional archival policy alignment.
- **[Risk] Event overcount from repeated modal toggles** -> Mitigation: standardize open/close trigger boundaries and dedupe rules in frontend logic.
## Migration Plan
1. Add summary/image metadata fields or related model for persisted summary artifacts.
2. Extend ingestion flow to generate structured summary + citation via Perplexity.
3. Integrate royalty-free image retrieval with MCP-preferred flow and fallback.
4. Extend API payloads to return summary-modal-ready data.
5. Implement frontend modal rendering with exact template and analytics tags.
6. Validate event tagging correctness and rendering fallback behavior.
Rollback:
- Disable modal entrypoint and return existing feed behavior while retaining stored summary data.
## Open Questions
- Should TL;DR bullet count be fixed (for example 3) or provider-adaptive within a bounded range?
- Should summary modal open be card-click only or have an explicit "Read Summary" CTA in each card?
- Which royalty-free provider is preferred default when MCP is unavailable?

View File

@@ -0,0 +1,37 @@
## Why
Users need a quick, concise view of fetched news without reading long article text. Adding a TL;DR summary flow improves scan speed, reading experience, and engagement while keeping source transparency.
## What Changes
- **New Capabilities:**
- Generate concise article summaries via Perplexity when news is fetched.
- Store structured summary content in the database using the required display template.
- Fetch and attach an appropriate royalty-free image for each summarized article.
- Render summary content in a modal dialog from the landing page.
- Add Umami event tagging for modal opens, closes, and source link-outs.
- **Backend:**
- Extend ingestion to call Perplexity summary generation and persist summary output.
- Integrate royalty-free image sourcing (prefer MCP path when available).
- **Frontend:**
- Add summary modal UI and interaction flow.
- Add event tracking for all required user actions in the modal.
## Capabilities
### New Capabilities
- `article-tldr-summary`: Generate and persist concise TL;DR + summary content per fetched article using Perplexity.
- `summary-modal-experience`: Display summary content in a modal dialog using the standardized template format.
- `royalty-free-image-enrichment`: Attach appropriate royalty-free images for summarized articles, leveraging MCP integration when available.
- `summary-analytics-tagging`: Track summary modal opens, closes, and external source link-outs via Umami event tags.
### Modified Capabilities
- None.
## Impact
- **Code:** Ingestion pipeline, storage model/schema, API response payloads, and frontend modal interactions will be updated.
- **APIs:** Existing news payloads will include summary/template-ready fields and image metadata.
- **Dependencies:** Reuses Perplexity; may add/enable royalty-free image provider integration (including MCP route if available).
- **Infrastructure:** No major topology change expected.
- **Data:** Database will store summary artifacts and associated image/source metadata.

View File

@@ -0,0 +1,22 @@
## ADDED Requirements
### Requirement: System generates structured TL;DR summary for each fetched article
The system SHALL generate a concise summary artifact for each newly fetched article using Perplexity during ingestion.
#### Scenario: Successful summary generation
- **WHEN** a new article is accepted in ingestion
- **THEN** the system generates TL;DR bullet points and a concise summary body
- **AND** output is persisted in a structured, template-compatible format
#### Scenario: Summary generation fallback
- **WHEN** summary generation fails for an article
- **THEN** ingestion continues without failing the entire cycle
- **AND** the article remains available with existing non-summary content
### Requirement: Summary storage includes citation and source context
The system SHALL persist source/citation information needed to render summary provenance.
#### Scenario: Persist source and citation metadata
- **WHEN** summary content is stored
- **THEN** associated source/citation fields are stored with the article summary artifact
- **AND** response payloads can render a "Source and Citation" section

View File

@@ -0,0 +1,22 @@
## ADDED Requirements
### Requirement: System enriches summaries with appropriate royalty-free images
The system SHALL attach an appropriate royalty-free image to each summarized article.
#### Scenario: Successful royalty-free image retrieval
- **WHEN** summary generation succeeds for an article
- **THEN** the system retrieves an appropriate royalty-free image for that article context
- **AND** stores image URL and attribution metadata for rendering
#### Scenario: MCP-preferred retrieval path
- **WHEN** MCP image integration is available in runtime
- **THEN** the system uses MCP-based retrieval as the preferred image sourcing path
- **AND** falls back to configured non-MCP royalty-free source path when MCP retrieval fails or is unavailable
### Requirement: Image retrieval failures do not block article availability
The system SHALL remain resilient when image sourcing fails.
#### Scenario: Image fallback behavior
- **WHEN** no suitable royalty-free image can be retrieved
- **THEN** the article summary remains available for modal display
- **AND** UI uses configured placeholder/fallback image behavior

View File

@@ -0,0 +1,22 @@
## ADDED Requirements
### Requirement: Modal interactions are tagged for analytics
The system SHALL emit Umami analytics events for summary modal open and close actions.
#### Scenario: Modal open event tagging
- **WHEN** a user opens the summary modal
- **THEN** the system emits a modal-open Umami event
- **AND** event payload includes article context identifier
#### Scenario: Modal close event tagging
- **WHEN** a user closes the summary modal
- **THEN** the system emits a modal-close Umami event
- **AND** event payload includes article context identifier when available
### Requirement: Source link-out interactions are tagged for analytics
The system SHALL emit Umami analytics events for source/citation link-outs from summary modal.
#### Scenario: Source link-out event tagging
- **WHEN** a user clicks source/citation link in summary modal
- **THEN** the system emits a link-out Umami event before or at navigation trigger
- **AND** event includes source URL or source identifier metadata

View File

@@ -0,0 +1,22 @@
## ADDED Requirements
### Requirement: Summary is rendered in a modal dialog using standard template
The system SHALL render article summary content in a modal dialog using the required structure.
#### Scenario: Open summary modal
- **WHEN** a user triggers summary view for an article
- **THEN** a modal dialog opens and displays content in this order: relevant image, TL;DR bullets, summary body, source and citation, and "Powered by Perplexity"
- **AND** modal content corresponds to the selected article
#### Scenario: Close summary modal
- **WHEN** a user closes the modal via close control or backdrop interaction
- **THEN** the modal is dismissed cleanly
- **AND** user returns to previous feed context without page navigation
### Requirement: Modal content preserves source link-out behavior
The system SHALL provide source link-outs from the summary modal.
#### Scenario: Source link-out from modal
- **WHEN** a user clicks source/citation link in the modal
- **THEN** the original source opens in a new tab/window
- **AND** modal behavior remains stable for continued browsing

View File

@@ -0,0 +1,46 @@
## 1. Summary Data Model and Persistence
- [x] 1.1 Add persisted summary fields for TL;DR bullets, summary body, source/citation, and summary image metadata
- [x] 1.2 Update database initialization/migration path for summary-related storage changes
- [x] 1.3 Add repository read/write helpers for structured summary artifact fields
## 2. Ingestion-Time Summary Generation
- [x] 2.1 Extend ingestion flow to request structured TL;DR + summary output from Perplexity for each fetched article
- [x] 2.2 Implement strict parser/validator for summary output schema used by the frontend template
- [x] 2.3 Persist generated summary artifacts with article records during the same ingestion cycle
- [x] 2.4 Add graceful fallback behavior when summary generation fails without blocking article availability
## 3. Royalty-Free Image Enrichment
- [x] 3.1 Implement royalty-free image retrieval for summarized articles with relevance constraints
- [x] 3.2 Prefer MCP-based image retrieval path when available
- [x] 3.3 Implement deterministic non-MCP fallback image path and placeholder behavior
- [x] 3.4 Persist image attribution/licensing metadata required for compliant display
## 4. API Delivery for Summary Modal
- [x] 4.1 Extend API response payloads to include summary-modal-ready fields
- [x] 4.2 Ensure API payload contract maps directly to required template sections
- [x] 4.3 Preserve source and citation link-out data in API responses
## 5. Frontend Summary Modal Experience
- [x] 5.1 Implement summary modal dialog component in landing page flow
- [x] 5.2 Render modal using required order: image, TL;DR bullets, summary, source/citation, Powered by Perplexity
- [x] 5.3 Add article-level trigger to open summary modal from feed interactions
- [x] 5.4 Implement robust modal close behavior (close control + backdrop interaction)
## 6. Analytics Event Tagging
- [x] 6.1 Emit Umami event on summary modal open with article context
- [x] 6.2 Emit Umami event on summary modal close with article context when available
- [x] 6.3 Emit Umami event on source/citation link-out from modal with source metadata
- [x] 6.4 Validate event naming and payload consistency across repeated interactions
## 7. Validation and Documentation
- [x] 7.1 Validate end-to-end summary generation, persistence, and modal rendering for new articles
- [x] 7.2 Validate fallback behavior for summary/image retrieval failures
- [x] 7.3 Validate source/citation visibility and external link behavior in modal
- [x] 7.4 Update README with summary modal feature behavior and analytics event contract