Skip to content

madfam-org/bloom-scroll

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

143 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌱 Bloom Scroll

From Doom Scrolling to Bloom Scrolling

A perspective-driven content aggregator that counters infinite scrolling by optimizing for serendipity, finite feeds, and raw data instead of engagement and outrage.


🎯 Mission

Transform the endless scroll into a finite, intentional experience that leaves users feeling more informed and optimistic. Bloom Scroll synthesizes diverse content sourcesβ€”from statistical truth to frontier science to visual cultureβ€”into a curated daily digest rooted in epistemic progress and constructive perspective.

Core Principle: "The End" is the product. Every feed has a definitive stopping point.


🌸 The "Slow Web" Philosophy

Bloom Scroll is built on four anti-doomscroll principles:

1. Finite Feeds (20-Item Daily Limit)

  • Hard cap of 20 cards per day
  • Completion celebrated with "The Garden is Watered" message
  • No "Load More" escape hatch
  • Daily reset encourages routine

2. Upward Scrolling (Reverse Chronology)

  • Users "plant" seeds at the bottom
  • Scroll up to see ideas bloom
  • Newest content appears at bottom (like chat)
  • Natural stopping point at top (completion widget)

3. Raw Data Over Cooked Media

  • Render charts from source CSV/JSON (not screenshots)
  • Interactive visualizations with fl_chart
  • Preserve data provenance and context
  • "Show your work" transparency

4. Serendipity Over Similarity

  • Penalize echo chambers (cosine distance 0.3-0.8)
  • Prioritize blindspot perspectives
  • Mix aesthetics + data + science
  • "Robin Hood" visual rhythm

πŸ› οΈ Tech Stack

Python FastAPI Flutter PostgreSQL pgvector Docker Redis

Backend

  • FastAPI (Python 3.11+) - Async REST API
  • PostgreSQL (15+) with pgvector - Vector similarity search
  • Sentence-BERT (all-MiniLM-L6-v2) - 384-dim embeddings
  • Redis - Caching and session management

Frontend

  • Flutter/Dart - Cross-platform web/mobile UI
  • Riverpod - State management
  • fl_chart - Interactive data visualization
  • Masonry Grid - Staggered layout (Pinterest-style)

Infrastructure

  • Docker Compose - Local development
  • Alembic - Database migrations
  • Kubernetes + ArgoCD - Production deployment for almanac.solar

βœ… Current State

Last audited: 2026-05-28. See docs/CURRENT_STATE.md for the evidence log from repository inspection and public production probes.

Key observed facts:

  • Public web: https://almanac.solar returns HTTP 200.
  • Public API health: https://api.almanac.solar/health returns healthy with database OK, 8 indexed embeddings, and 8 cards.
  • The production Flutter bundle is baked to https://api.almanac.solar/api/v1.
  • /docs and /openapi.json are hidden in production and covered by scripts/prod-smoke.sh.
  • Backend installs are deterministic through backend/poetry.lock; production ML wheels are pinned separately in backend/requirements-ml-linux-cpu.txt so Linux images use CPU-only PyTorch.
  • Enclii reports the bloom-scroll-services Argo app healthy/synced at argocd-a84a3de; API and web are both healthy at 2/2 replicas.
  • Root docker-compose.yml is a lightweight compatibility stack on API port 5200; infrastructure/ remains the preferred local development path.

πŸš€ Quick Start

Prerequisites

  • Docker & Docker Compose
  • (Optional) Python 3.11+ for backend development
  • (Optional) Flutter SDK 3.0+ for frontend development

1. Start local infrastructure 🌱

cd infrastructure
docker-compose -f docker-compose.dev.yml up -d

This starts:

  • PostgreSQL with pgvector extension
  • Redis cache

2. Run backend migrations πŸ—„οΈ

cd ../backend
poetry install
poetry run alembic upgrade head

Creates the bloom_cards table with vector columns.

3. Start the API

poetry run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

The local API runs at http://localhost:8000.

4. Seed content 🌾

curl -X POST "http://localhost:8000/api/v1/ingest/owid/all"
curl -X POST "http://localhost:8000/api/v1/ingest/aesthetics/all?limit_per_channel=2"

5. Run the Flutter app πŸ“±

cd frontend
flutter pub get
flutter run -d chrome --dart-define=API_BASE_URL=http://localhost:8000

API Endpoints:

  • iOS Simulator: http://localhost:8000
  • Android Emulator: http://10.0.2.2:8000
  • Physical Device: http://<your-ip>:8000

View local API docs: http://localhost:8000/docs


πŸ“ Directory Structure

bloom-scroll/
β”œβ”€β”€ πŸ“– docs/                          # Documentation & Architecture
β”‚   β”œβ”€β”€ brief.md                      # Product concept
β”‚   β”œβ”€β”€ prd.md                        # Product Requirements Document
β”‚   β”œβ”€β”€ CURRENT_STATE.md              # Evidence-backed current implementation and prod state
β”‚   β”œβ”€β”€ ARCHITECTURE.md               # Technical deep dive
β”‚   β”œβ”€β”€ DESIGN_SYSTEM.md              # "Paper & Ink" design tokens
β”‚   β”œβ”€β”€ ROADMAP.md                    # Story tracking (STORY-001 to STORY-007)
β”‚   β”œβ”€β”€ design_tokens.md              # Raw design specifications
β”‚   β”œβ”€β”€ STORY-004-IMPLEMENTATION.md   # Serendipity algorithm docs
β”‚   β”œβ”€β”€ STORY-006-IMPLEMENTATION.md   # Perspective overlay docs
β”‚   └── STORY-007-IMPLEMENTATION.md   # Finite feed docs
β”‚
β”œβ”€β”€ 🐍 backend/                       # Python FastAPI
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ models/                   # SQLAlchemy models (BloomCard)
β”‚   β”‚   β”œβ”€β”€ ingestion/                # Implemented OWID + Are.na connectors
β”‚   β”‚   β”œβ”€β”€ curation/                 # Bloom algorithm (serendipity)
β”‚   β”‚   β”œβ”€β”€ analysis/                 # NLP models (SBERT, BiasBERT)
β”‚   β”‚   β”œβ”€β”€ api/                      # REST endpoints
β”‚   β”‚   └── core/                     # Database, config
β”‚   β”œβ”€β”€ alembic/                      # Database migrations
β”‚   β”œβ”€β”€ tests/                        # Pytest tests
β”‚   β”œβ”€β”€ Dockerfile
β”‚   β”œβ”€β”€ pyproject.toml                # Poetry dependencies
β”‚   └── README.md
β”‚
β”œβ”€β”€ 🎨 frontend/                      # Flutter/Dart
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ models/                   # Dart data models (BloomCard, Feed)
β”‚   β”‚   β”œβ”€β”€ screens/                  # Feed screen, settings
β”‚   β”‚   β”œβ”€β”€ widgets/                  # Cards, perspective overlay, completion
β”‚   β”‚   β”œβ”€β”€ providers/                # Riverpod state management
β”‚   β”‚   β”œβ”€β”€ services/                 # API client, storage
β”‚   β”‚   └── theme/                    # Design tokens (colors, typography)
β”‚   β”œβ”€β”€ assets/                       # Images, icons
β”‚   β”œβ”€β”€ test/                         # Flutter tests
β”‚   β”œβ”€β”€ pubspec.yaml                  # Dependencies
β”‚   └── README.md
β”‚
β”œβ”€β”€ πŸ—οΈ infrastructure/                # Local Docker Compose stacks
β”‚   β”œβ”€β”€ docker-compose.dev.yml        # Postgres + Redis for host-run backend
β”‚   └── docker-compose.yml            # Full local stack
β”‚
β”œβ”€β”€ docker-compose.yml                # Legacy root Compose file; see docs/CURRENT_STATE.md
└── README.md                         # This file

🎨 Design Philosophy

"Paper & Ink" - The UI feels like a printed Sunday newspaper, not a software application.

  • High Contrast: Black ink (#1A1A1A) on warm paper (#FDFCF8)
  • No Shadows: Use borders and whitespace for hierarchy
  • Data First: Charts are the "hero" images, not decorations
  • Botanical Colors: Growth green (#2D6A4F) for positive trends

See DESIGN_SYSTEM.md for complete specifications.


πŸ“Š Content Sources

Six content types blended into unified BloomCard format:

Type Source Purpose
πŸ“ˆ Data Our World in Data Statistical truth, macro trends
πŸ”¬ Science OpenAlex Frontier research, academic papers
🎨 Aesthetic Are.na / CARI Visual culture, design inspiration
🌐 Indie Web Neocities Human-made web, small internet
πŸ“– Narrative TVTropes Story patterns, cultural analysis
πŸŽ“ Education My-MOOC Free courses, skill building

πŸ§ͺ Development

Backend Development

cd backend

# Install dependencies (Poetry)
poetry install

# Run tests
poetry run pytest

# Code quality
poetry run black .
poetry run ruff check .
poetry run mypy . --ignore-missing-imports

# Database migrations
poetry run alembic revision --autogenerate -m "Description"
poetry run alembic upgrade head

# Start dev server
poetry run uvicorn app.main:app --reload

Frontend Development

cd frontend

# Install dependencies
flutter pub get

# Generate code (Riverpod, JSON serialization)
flutter pub run build_runner build --delete-conflicting-outputs

# Run tests
flutter test

# Static analysis
flutter analyze --no-fatal-infos

# Build for release
flutter build web --release --dart-define=API_BASE_URL=http://localhost:8000

πŸ“š Documentation

Implementation Docs

  • STORY-004 - Serendipity algorithm & vector search
  • STORY-006 - Perspective overlay & 3D flip animation
  • STORY-007 - Finite feed & completion widget

πŸ—ΊοΈ Current Status

Version: 0.1.0 Phase: Production alpha / stabilization Last Updated: 2026-05-28

Completed Stories βœ…

  • βœ… STORY-001: Infrastructure & OWID Ingestion
  • βœ… STORY-002: Flutter Scaffold & Charting
  • βœ… STORY-003: Aesthetics & Masonry Grid
  • βœ… STORY-004: Vector Serendipity & Bias Engine
  • βœ… STORY-006: Perspective Overlay & Flip Animation
  • βœ… STORY-007: Finite Feed & Completion Widget

Needs Verification / Hardening 🚧

  • βœ… STORY-005 backend repair: Poison pill and feed tests now target current modules/endpoints.
  • βœ… Production docs exposure: /docs and /openapi.json are hidden on api.almanac.solar by the production environment gate and covered by scripts/prod-smoke.sh.
  • βœ… Auth hardening: Janua RS256/JWKS verification is implemented with issuer and optional audience checks.
  • βœ… OpenAlex ingestion: Science cards now have a repo-owned connector and API endpoints.
  • βœ… Control-plane observability release: Enclii CLI v1.0.0-alpha.1 reports runtime health correctly from the distributed GitHub release artifact.
  • βœ… Backend dependency determinism: backend/poetry.lock is committed, CPU-only ML wheels are pinned separately for Docker, and lockfile guard tests prevent CUDA drift.
  • πŸ”œ Next stability priority: frontend E2E/stress coverage, production observability, and load/soak testing.

See ROADMAP.md for detailed tracking.


🌱 Core Principles

  1. Finite Feeds: Respect user time with definitive endpoints
  2. Serendipity: High-value outliers over echo chambers
  3. Transparency: Show data provenance and bias scores
  4. Privacy: No tracking sold to third parties

πŸ“„ License

Proprietary - Bloom Scroll Team


Built with intention. Consumed with mindfulness. 🌸

About

Finite-feed content aggregator built on Slow Web principles. 20 items/day curated for serendipity over engagement. Flutter + FastAPI + pgvector.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors