Release Notes
Fishwrap is evolving from a personal script into a robust “Anti-Feed” platform. Here is the history of that evolution.
v2.0.0 (The Newsstand) - May 5, 2026
This release marks the transition from “code you clone” to “image you pull.” Fishwrap now ships as a signed OCI image at ghcr.io/maxspevack/fishwrap. Downstream products pull the pinned image, mount a config, and run it.
This is a major version bump per docs/VERSIONING.md’s “fundamental architectural shifts” criterion. The way consumers integrate with fishwrap changes structurally. If you were cloning fishwrap into a vendor/ directory and running its venv install, that path no longer works — switch to docker pull ghcr.io/maxspevack/fishwrap:2.0 and run via docker run. See docs/IMAGE_CONTRACT.md for the full new integration shape, and Daily Clamour for a worked example.
📦 The Artifact
- OCI image release: every
v*tag push triggers.github/workflows/release.yml, which builds and publishes the image to GHCR. Stable tags publish both the exact tag (:2.0.0) and the floating minor (:2.0); pre-release tags (-rc1,-alpha.1, etc.) publish only the exact tag. - Documented consumer contract:
docs/IMAGE_CONTRACT.mddescribes inputs, outputs, entrypoints, versioning policy, and pinning recommendations. The contract surface is the only thing consumers should depend on.
✨ New CLI Surface
fishwrap-build --config <path>: runs the full pipeline. Replaces the four-steppython -m fishwrap.{fetcher,editor,enhancer,printer}sequence.fishwrap-version: prints the running image’s semver to stdout. The only supported way for downstream consumers to read the version.fishwrap-validate-config <path>: schema-checks a config file in ~100 ms before the pipeline runs. Catches missing keys and wrong types up-front instead of mid-fetch crashes.
🤖 Production CI
- Daily demo refresh:
.github/workflows/demos.ymlruns at 12:00 UTC daily, rebuilds all four reference demos against the published image, validates output size (≥10 KB), and deploys to fishwrap.org viaactions/deploy-pages. Per-vertical isolation: one bad feed does not block other demos.
🏗️ Engine Improvements
- Self-bootstrapping schema: the engine now self-initializes its SQLite schema via
Base.metadata.create_allin_initialize_engine. Ephemeral DBs in CI just work; fresh local clones no longer crash with “no such table: articles.” - Lazy weasyprint: PDF generation is optional.
printer.pylazy-imports weasyprint inside the PDF code path, gated byImportError. The v2.0 image ships without weasyprint and its ~80 MB native dependency stack; PDF returns when a real consumer asks.
🧹 Decommissioned
- The launchd ship pipeline retired:
ship_demos.sh,publish_demo.sh,scripts/refresh_demos.sh, the launchd plist, and themake ship/make publish/make run-clamourMakefile targets all removed. CI replaces them. ROADMAP.mdremoved: roadmap state lives in GitHub Issues and Milestones to prevent drift between the file and reality.
📚 Documentation
docs/CONFIG_SCHEMA.md: every config key the engine recognizes, mirrored from the validator.docs/adr/001-release-artifact.md: internal decision record for the image-based release artifact.docs/RELEASING.md: rewritten as a procedural runbook for cutting future releases.README.md: rewritten around the image-based quick-start (docker run …instead ofmake setup).CONTRIBUTING.md: updated with a Two Audiences framing — engine contributors vs. image consumers.
🛠️ Release Engineering
- Action versions current: release and demo workflows use the latest major versions of
actions/checkout,docker/build-push-action,docker/login-action,docker/metadata-action, anddocker/setup-buildx-action— Node 24-compatible ahead of GitHub’s June 2026 deprecation. - No
:latesttag:flavor: latest=falsesuppresses the auto-generated:latesttag that would otherwise be a footgun for consumers who pin loosely.
v1.3.3 (The Synchronization) - Dec 14, 2025
A maintenance release to synchronize documentation updates and ensure all downstream artifacts are built from the latest stable baseline.
📚 Documentation
- Blog Vol 5: Added “The Release” (Release Engineering Case Study).
- Runbook Refinements: Clarified the separation of concerns between Engine and Product in deployment documentation.
v1.3.2 (The Chronos Update) - Dec 13, 2025
A feature release enabling high-precision publication metadata.
🚀 New Features
- Publication Timestamp: The engine now injects the precise generation time (e.g.,
08:00 AM PST) into the template context (time_str). This reinforces the “Snapshot in Time” philosophy of the Anti-Feed. - Forward Compatibility: Themes have been updated to conditionally render this timestamp, ensuring smooth upgrades.
v1.3.1 (The Polish) - Dec 13, 2025
A maintenance release focused on UI refinement, build stability, and release engineering.
🐛 Bug Fixes & Polish
- Transparency UI: Fixed the “Tab Flashing” bug in the Glass Box modal and enforced high-contrast text colors for readability.
- Visuals: Updated the “Bubble” score badges to have fixed widths for better alignment.
- Data Clarity: Renamed “Signal Delta” to “Delta” and reordered the “Source Efficiency” table (Input → Output → Delta) for better logical flow.
- Footer: Replaced the text-based version string with a clean GitHub icon + version badge (e.g.,
v1.3.1).
🛠️ Release Engineering
- Automated Release Script: Introduced
scripts/release.shto automate the version bump, build verification, and tagging process. - Test Gate: The release pipeline now enforces a
make testpass, running the full unit test suite before allowing a release. - Build Hardening: Updated
Makefileto suppress legacySyntaxWarningnoise and use a robustinstall_venv.shscript for environment setup. - Runbook: Published
docs/RELEASING.mdas the definitive guide for shipping new versions.
v1.3.0 (Digital Origami) - Dec 13, 2025
This release focuses on Experience and Stability. We polished the “Glass Box” UI, overhauled the documentation identity, and hardened the build system to survive bleeding-edge environments (Python 3.14).
🎨 UX & Branding
- Tabbed Transparency UI: The “Glass Box” modal now features a clean, tabbed interface separating “Vitals” (The Funnel), “Sources” (Efficiency), and “The Bubble” (Cut-Line).
- Digital Origami: Rolled out the new brand identity across the documentation.
- Sidebar Restoration: Fixed a regression in the demo themes where the sidebar navigation was lost.
📚 Documentation
- The Architect’s Log: Reorganized the engineering docs into a proper blog structure.
- Brand Bible: Added comprehensive brand guidelines and GenAI prompts for assets.
🛡️ Engineering
- Robust Build System: Updated
Makefileto explicitly handle shell environments (bash) and simplify dependency installation (install_venv.sh), fixing deployment issues on modern macOS. - Dependencies: Cleaned up the dependency tree, reverting the experimental Pydantic refactor to maintain compatibility with Python 3.14.
v1.2.0 (The Glass Box) - Dec 12, 2025
This release marks the transition from “Script” to “System.” We realized that speed wasn’t enough; we needed Trust. We rebuilt the engine to be auditable, persistent, and transparent.
🏛️ The Architecture
- SQLite Migration: We moved from atomic JSON files to a robust SQLite backend (
fishwrap.db). This enables long-term history (“The Chronicle”) and prevents data corruption during concurrent fetches. - The Auditor: A new forensic module that runs after every edition. It generates a Transparency Report (
transparency.html) that proves the algorithm isn’t just a mirror of the most popular links. - Anti-Feed Metrics: We introduced the “Anti-Feed Protection” score (Yield Rate) and “Source Efficiency” metrics to quantify how much noise we filter out.
🔭 Observability
- The HUD: New console reporting for “Cut-Line” stories (what almost made it) and “Drift” (when a story is forced into a different section).
- Database CLI: Introduced
fw-db, a command-line tool for managing the newsroom database (status,prune,vacuum).
📚 Documentation
- The Architect’s Log: Launched the engineering blog with case studies on Algorithms, Concurrency, and Consistency.
- Brand Identity: Established the “Digital Origami” design language.
v1.1.0 (The Parallel Press) - Dec 12, 2025
The “Speed” update. We realized our sequential processing was too slow for the scale of the web. We broke the single-lane highway and built a ten-lane freeway.
⚡ Performance
- Concurrency: Implemented
ThreadPoolExecutorfor the Fetcher and Enhancer. Pipeline runtime dropped from ~51s to ~15s (3.5x speedup). - Rate Limiting: We flew too close to the sun and DDoS’d Reddit. We implemented Token Bucket rate limiting to be polite citizens of the open web.
🧠 Logic
- The “Memento” Fix: Solved a critical bug where the engine would forget scraped text every hour. We now merge new data with existing cache, ensuring 100% cache hit rates on subsequent runs.
- The Jaccard Hatchet: Optimized deduplication from O(N²) to effective O(N) by pre-filtering candidates with Set Intersection before running expensive fuzzy matching.
v1.0.0 (The Foundation) - Dec 11, 2025
The initial release. A proof-of-concept that a Python script could replace a doomscroll.
- Core Engine: The four-stage pipeline (Fetcher -> Editor -> Enhancer -> Printer).
- JSON Storage: Simple file-based persistence (
articles_db.json). - Basic Output: Generation of a static HTML edition and a rudimentary PDF.
Pre-History (The Prototype Era)
Before v1.0, we were figuring out what we were actually building.
v0.9.0 (The Fleet) - Dec 10, 2025
Theme: “Verticalization.” We proved the platform thesis by launching specific verticals.
- The Zero Day: A cybersecurity-focused briefing.
- The Hallucination: An AI research briefing.
- This proved Fishwrap wasn’t just a news reader; it was a generic engine for any stream of information.
v0.3.0 (The Schism) - Dec 9, 2025
Theme: “Separation of Concerns.”
- We extracted the “Engine” (
fishwrap) from the “Product” (dailyclamour.com). - This architecture allowed us to treat the Daily Clamour as just one instance of the Fishwrap technology.
v0.2.0 (The Identity) - Dec 8, 2025
Theme: “Ink & Grit.”
- Established the “Vintage” aesthetic.
- Introduced “Scoop the Pearl” as the mascot.
- Moved from a generic HTML list to the “Bento Grid” layout.
v0.1.0 (The Seed) - Dec 07, 2025
Theme: “The Genesis.”
- The very first commit of the Fishwrap project. A simple script to fetch, process, and print basic news headlines.
- This was the day the “Anti-Feed” began.