• 2026.10.17.1 d75d9ada3c

    2026.10.17.1
    Some checks failed
    / pr-review (push) Has been skipped
    / container (push) Blocked by required conditions
    / publish-container (push) Blocked by required conditions
    / deploy-docs (push) Blocked by required conditions
    / gitleaks (push) Successful in 28s
    / pr-review (release) Has been skipped
    / container (release) Blocked by required conditions
    / publish-container (release) Blocked by required conditions
    / deploy-docs (release) Blocked by required conditions
    / gitleaks (release) Successful in 39s
    / checks (release) Failing after 15m38s
    / checks (push) Failing after 16m20s
    Stable

    marvin8 released this 2026-10-17 09:51:32 +00:00 | 0 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.10.17.1] - 2026-10-17

    • New articles are now matched against every existing group on the same story, not just the most recently touched ones — previously only the last few hours of groups were considered, so any story that kept developing spawned a duplicate group
    • The daily consolidation pass now actively merges groups covering the same story and attaches new developments to the group's existing coverage
    • Existing duplicate groups aren't deleted — they age out through normal 7-day expiry once the fix takes over
    • New toggle on the Feeds page: Disable aggregation — built for announcement/status feeds (hosting notices, tracker signups, server status) whose items have no distinct stories to group
    • Opted-out feeds still fetch on schedule; their articles just stay plain reading-list items instead of collapsing into one endless group on every refresh
    • Default is unchanged: regular news feeds aggregate as before, and switching off leaves existing groups to expire naturally

    Commits

    • 🔀 Merge branch 'feat/issue-87-feed-aggregation-opt-out' 747089a
    • ✅ Pin the aggregation flag's NOT NULL DEFAULT constraint (#87) b8e4d64
    • 🐛 Drop the bound-parameter IN clause from the aggregating-feed filter 86442fd
    • 🔀 Merge branch 'feat/issue-85-86-cross-run-story-dedup' 67bcbaf
    • 🔀 Merge branch 'feat/issue-85-86-cross-run-story-dedup' a947fc8
    • 🐛 Strip aggregate_search FTS objects in the legacy-database migration test 2b981a8
    • ⬆️ Pin WuMing action to 0.13.0 and set a medium severity floor 2f9ab6a
    • ✨ Merge-aware consolidation: collapse duplicate topics, widen candidates (#86) 672ce23
    • ✨ Pre-filter existing aggregates by title relevance in incremental runs (#85) 87859ab
    • 🔀 Merge branch 'feat/issue-99-openrouter-review' 77e3aa7
    • 🔧 migrate PR review to openrouter with pinned 0.11.0 action 71b1666
    Downloads
  • 2026.10.11.2 d1c522af19

    2026.10.11.2
    All checks were successful
    / pr-review (push) Has been skipped
    / gitleaks (push) Successful in 15s
    / checks (push) Successful in 12m16s
    / publish-container (push) Has been skipped
    / deploy-docs (push) Has been skipped
    / container (push) Successful in 1m42s
    / pr-review (release) Has been skipped
    / gitleaks (release) Successful in 14s
    / checks (release) Successful in 12m2s
    / container (release) Has been skipped
    / publish-container (release) Successful in 3m17s
    / deploy-docs (release) Successful in 4m14s
    Stable

    marvin8 released this 2026-10-11 09:46:34 +00:00 | 13 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.10.11.2] - 2026-10-11

    Commits

    • 🔀 Merge branch 'feat/issue-78-fast-test-fixtures' 0431511
    • ⚡ Run the pytest nox sessions in parallel with pytest-xdist b7810d2
    • ⚡ Build the schema once per session and copy it per test 1a2528e
    Downloads
  • 2026.10.11.1 0d14085c24

    2026.10.11.1
    Some checks failed
    / pr-review (push) Has been skipped
    / gitleaks (push) Successful in 16s
    / pr-review (release) Has been skipped
    / gitleaks (release) Successful in 37s
    / checks (push) Successful in 45m7s
    / publish-container (push) Has been skipped
    / deploy-docs (push) Has been skipped
    / checks (release) Failing after 45m7s
    / container (release) Has been skipped
    / deploy-docs (release) Has been skipped
    / publish-container (release) Has been skipped
    / container (push) Successful in 1m53s
    Stable

    marvin8 released this 2026-10-11 07:04:25 +00:00 | 18 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.10.11.1] - 2026-10-11

    Commits

    • ⬆️ bump deps 7fdf39b
    • 🔀 Merge branch 'feat/issue-73-remove-tags' aff660d
    • ✅ Cover the tag-table migration round trip; keep ignore rules in the index highlights 15c5fbd
    • 📝 Sync docs and worker loop with the tag removal 85a6013
    • 💥 Drop the tags and article_tags tables fe31b28
    • 🔥 Remove tag machinery: extractor, data layer, UI, and CLI a2b951d
    • 🐛 Match ignore rules against article categories instead of tag names e822757
    • ✅ Failing reader test: ignore rules match member article categories 57424c8
    • 🔀 Merge branch 'feat/issue-74-cap-existing-topics' 6b5d1cc
    • ✅ Address WuMing review: cap log signal, discriminating tests f416c0c
    • 📝 Document YUNJIN_MAX_PROMPT_TOPICS e1f649b
    • ✨ Cap incremental EXISTING TOPICS to the most recently updated 6c1cf49
    • 🔀 Merge branch 'feat/issue-71-aggregation-consolidation' 709f837
    • 📝 Scope eligibility filter to the incremental pass; strengthen title-only test 1ebec46
    • 📝 Address WuMing docs review: names/overviews, consolidation wording, pipeline line 6e06887
    • 📝 Address WuMing review: eligibility wording, verbatim title pin, restored docstrings cd51c48
    • 🐛 Fix review findings: user-scoped unlink, migration backfill, consolidation timing 18ae8f6
    • 📝 Document consolidation and eligibility environment variables 04c97db
    • ✨ Nightly consolidation pass merges stray aggregates in place 399660e
    • ✅ Warn when the LLM leaves articles unassigned 272a569
    • ✨ Membership-based article eligibility with 30-day floor bf2216d
    • ✨ Prompt anchors: aggregate name + recent member titles; require total assignment 90ba68f
    • ✨ Reader sources group titles from the name column eedd8d3
    • 🐛 Keep creation-time aggregate name; summary holds overview only e2a24f3
    • ✨ Add name column to aggregates with backfill migration 1c0cda2
    • 🔀 Merge branch 'fix/issue-70-summary-prompt' 8722b90
    • ✅ Tune meta-commentary monitor: INFO severity, wider coverage 676fc17
    • 🐛 Align monitoring regex with the exact prompt-banned phrases 1eae416
    • ✅ Monitor summaries for banned classification phrasing cf28daf
    • 🐛 Summaries describe content only, never classify the article 3cde8c7
    • ✅ Test summary prompt bans classification and grouping rationale 5ad9185
    • 🔀 Merge branch 'fix/issue-75-webauthn-error-handling' e470d53
    • 📝 Document already-registered and generic passkey failures 5354f4b
    • 🐛 Strip unpaired quotes from WebAuthn env values too d80d0d9
    • 🔧 Update asynccontextmanager annotation for current ty e4b3916
    • 🐛 Surface WebAuthn failures instead of dying silently 579be69
    • ✅ Test quote/whitespace stripping in WebAuthnConfig.from_env 7c6bcfc
    Downloads
  • 2026.10.6.1 99b59ec10e

    2026.10.6.1
    All checks were successful
    / pr-review (push) Has been skipped
    / gitleaks (push) Successful in 23s
    / pr-review (release) Has been skipped
    / gitleaks (release) Successful in 32s
    / checks (push) Successful in 27m16s
    / publish-container (push) Has been skipped
    / deploy-docs (push) Has been skipped
    / checks (release) Successful in 26m58s
    / container (release) Has been skipped
    / container (push) Successful in 1m48s
    / deploy-docs (release) Successful in 2m4s
    / publish-container (release) Successful in 3m22s
    Stable

    marvin8 released this 2026-10-06 04:29:24 +00:00 | 57 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.10.6.1] - 2026-10-06

    • Sign-in is here — yunjin now has real accounts: a first-run setup page, username/password login with configurable session lifetime, logout, and CSRF protection on every state-changing request. No more implicit single-user access.

    • Everything is per-account — each account gets its own feeds, topic aggregates, read state, display settings, ignore rules, and OPML import/export. Shared feeds are still fetched only once no matter how many accounts subscribe to them.

    • Passkeys (optional) — sign in with a fingerprint, device PIN, or security key instead of a password; enroll and manage passkeys from Settings → Account, with shorter 12-hour passkey sessions. Passwords always remain the fallback. Requires serving yunjin over HTTPS on a stable domain and setting two new environment variables (YUNJIN_RP_ID, YUNJIN_ORIGIN).

    • Account self-service and simple administration — users can change their own password and delete their own account (with full data cleanup); there's no sign-up page and no admin role — accounts are managed from the server with the new yunjin create-user and delete-user commands.

    • Documentation expanded — new pages for passkeys, account management, and the CLI, including the HTTPS prerequisite and configuration for passkey support.

    Commits

    • 🔀 Merge branch 'feat/multiuser' 89f26f7
    • 🔀 Merge branch 'feat/issue-67-account-management' into feat/multiuser cea51eb
    • ✅ Restore session lifetime config via monkeypatch d631863
    • 📝 Qualify passkey gating, operator wording, and seeded default in docs f7fba96
    • 📝 Move account docs to a dedicated page ab3edcd
    • 📝 Anchor the gitleaks vector regex and round out account docs e1a8fb2
    • 📝 Say aggregates, not groups, in the passkey deletion docs f94e6ca
    • ✅ Expect IntegrityError in credential-id uniqueness test f05ef6a
    • 🔒 Scope gitleaks allowlist to the public fixture vector bbc03b6
    • 🐛 Close setup-gate bypass and harden registration errors 5ee6dc5
    • 📝 Document account management and passkeys 0ff72cf
    • ✨ Add create-user and delete-user CLI commands 45bfb5d
    • ✨ Add self-service account deletion with data cleanup e08d218
    • ✨ Add password change with session handling 366c86a
    • ✨ Add passkey enrollment and credential management 0bb3e56
    • ✨ Add username-less passkey login c4c3f0c
    • 🔒 Enforce per-login session lifetimes fcbfd15
    • ✨ Add webauthn ceremony service d0b3730
    • ➕ Add webauthn dependency 5c4d189
    • 🗃️ Add webauthn credential schema and data access layer dc90ee9
    • 🔀 Merge branch 'feat/issue-65-data-ownership' into feat/multiuser f80a44a
    • ✅ Cover get_articles_for_feeds and clarify unsubscribe docs 7d3b6c2
    • 📝 Mark reuse-ignored add-feed options in the CLI table f74f9f2
    • 📝 Reword the waitress licence-ignore rationale a49c786
    • ⏪ Run the nox pytest session with plain pytest bcbf9e8
    • ✅ Assert the subscription UNIQUE constraint by indexed columns 5439ead
    • 🔒 Scope aggregate article links to the aggregating user c851e8a
    • ✅ Pin unsubscribe effect and document feed-reuse metadata 819cb98
    • 📝 Fix refresh docstring and generics annotation in aggregator 821d00a
    • 📝 Add per-user CLI flags and document data ownership 1de8592
    • ✨ Replace feed deletion with per-user unsubscribe 97524d3
    • ✨ Scope feed management and OPML to the session user b0140b3
    • 🐛 Make subscription cleanup atomic 01551c3
    • ✨ Add subscription service with orphan-feed GC bfdd67d
    • 🗃️ Add subscription model and data access layer 3bcd54e
    • ✨ Cluster and read aggregates per user 69a8b44
    • 🗃️ Add feed subscriptions and per-user aggregates migration e489054
    • 🔧 Switch WuMing agents to DeepSeek flash and raise diff cap to 5000 4a2457d
    • 🔧 Bump dependencies and align pre-commit revisions a78fe97
    • 🙈 Ignore local .pi and media directories 0255325
    • 🔀 Merge branch 'feat/effort1-auth' into feat/multiuser 5326063
    • 🔁 Re-trigger CI after PR #63 push non-dispatch ff1ee47
    • 🐛 Container smoke test fetches the login page bdd5fab
    • 🐛 Equalize failed-login work to prevent username enumeration b7c618a
    • 🐛 Initialize database in set-password command 4411eda
    • 📝 Add set-password CLI and document session configuration 8782486
    • ✨ Derive acting user from session on all routes 91eabdc
    • 🔒 Enforce authentication and CSRF across all routes ae6619a
    • ✨ Add setup, login, and logout routes with session config 7dfc606
    • ♻️ Extract safe_next_path redirect helper 459bea7
    • ✨ Add auth service with password hashing and session validity 485edf3
    • ✨ Add password hash and session validity to user model b7b3d7a
    • ✨ Add user credential columns migration 6dcd63f
    • 🔀 Merge branch 'feat/favicon-raster-fallbacks' e47d317
    • 🐛 Smoke test fetches apple-touch-icon from its /static path b471631
    • ✅ Smoke test checks icon content types and serves both icons 8abb4bd
    • 🐛 Fetch smoke-test ICO to file to avoid SIGPIPE under pipefail 72b64a0
    • ✅ Route test compares favicon.ico bytes to static file ae6f4ee
    • 🐛 Update container smoke test for direct ICO favicon serving 08c6125
    • ✅ Strengthen favicon fallback assertions per review 18b8e78
    • 🔧 Retrigger CI after upstream Forgejo hosting outage 7530060
    • 🔧 Retrigger CI after transient zhuiri runner failure 1fefeb4
    • 👽 Add ICO and apple-touch-icon raster fallbacks 56c08cb
    • 🎨 Draw cloud favicon as explicit vector art in primary blue 446794c
    Downloads
  • 2026.10.1.1 bed2365130

    2026.10.1.1
    All checks were successful
    / pr-review (push) Has been skipped
    / gitleaks (push) Successful in 29s
    / pr-review (release) Has been skipped
    / gitleaks (release) Successful in 42s
    / checks (push) Successful in 2m14s
    / publish-container (push) Has been skipped
    / deploy-docs (push) Has been skipped
    / container (push) Successful in 1m46s
    / checks (release) Successful in 1m46s
    / container (release) Has been skipped
    / deploy-docs (release) Successful in 1m28s
    / publish-container (release) Successful in 2m41s
    Stable

    marvin8 released this 2026-09-30 21:38:36 +00:00 | 123 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.10.1.1] - 2026-10-01

    Commits

    • 🔀 Merge branch 'feat/print-version-at-startup' 761ff5f
    • ✅ Restore cached wsgi module via monkeypatch.delitem 02343f3
    • 📝 Use version placeholder in CLI docs banner example ce2612e
    • 🐛 Stamp web version before app construction; import test module once 110d2ab
    • ✨ Print yunjin version at CLI and web startup ebd6105
    • ✅ Add failing startup-version tests for CLI and web entry points 4f46023
    Downloads
  • 2026.9.30.1 7ee09e33eb

    2026.9.30.1
    All checks were successful
    / pr-review (push) Has been skipped
    / gitleaks (push) Successful in 25s
    / pr-review (release) Has been skipped
    / gitleaks (release) Successful in 46s
    / checks (push) Successful in 2m24s
    / publish-container (push) Has been skipped
    / deploy-docs (push) Has been skipped
    / checks (release) Successful in 2m31s
    / container (release) Has been skipped
    / container (push) Successful in 2m36s
    / deploy-docs (release) Successful in 1m52s
    / publish-container (release) Successful in 3m12s
    Stable

    marvin8 released this 2026-09-30 09:48:42 +00:00 | 131 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.9.30.1] - 2026-09-30

    Commits

    • 🔀 Merge branch 'feat/container-version-and-favicon' 6b5d761
    • 💚 Anchor the PYTHONPATH env check and bound the smoke curls 064d6d3
    • 🐛 Kill the smoke-test server's process group, document what runs f12f1a9
    • 💚 Assert the fetched page links the favicon in the smoke test 2354a91
    • ✅ Follow the actual redirect Location in the favicon test d316b05
    • 🐛 Centre the favicon cloud so it does not clip cb64dc6
    • 💚 Boot the app in the container smoke test 2cf562b
    • 🐛 Keep src/ nesting in the project-install layer and harden smoke test 95135b2
    • 🔧 Address WuMing review wave on PR #58 43e8697
    • 💚 Smoke-test image contents via buildah instead of podman run 5b0a621
    • 🔧 Install project non-editable behind a cached dependency layer 6cd1ec1
    • 💚 Smoke-test container version and favicon in CI 178deca
    • ✨ Add cloud favicon 5461c0f
    • 🐛 Ship package metadata in container image 20c70a5
    • 🔀 Merge branch 'feat/opml-export' 33868a9
    • ✨ Add OPML export of all feeds 7057363
    Downloads
  • 2026.9.26.1 56ef7dea56

    2026.9.26.1
    All checks were successful
    / pr-review (push) Has been skipped
    / gitleaks (push) Successful in 15s
    / pr-review (release) Has been skipped
    / gitleaks (release) Successful in 28s
    / checks (push) Successful in 2m14s
    / publish-container (push) Has been skipped
    / deploy-docs (push) Has been skipped
    / checks (release) Successful in 2m39s
    / container (release) Has been skipped
    / container (push) Successful in 1m33s
    / publish-container (release) Successful in 2m57s
    / deploy-docs (release) Successful in 1m4s
    Stable

    marvin8 released this 2026-09-26 03:08:15 +00:00 | 149 commits to main since this release

    Signed by marvin8
    SSH key fingerprint: SHA256:B4Q+9pbWSIqGYTl3Ub/FPrBSqAVd2OkCR13hYRG5wek

    [2026.9.26.1] - 2026-09-26

    Commits

    • 🔀 Merge branch 'fix/calendar-release-transition' 0c670af
    • 🐛 Make the release recipe work from the legacy 0.4.0 version 8a59c9a
    • 🔀 Merge branch 'feat/reader-tweaks-and-docs' fdae0a1
    • 📝 Name Yunjin in the README tagline 0d45b2f
    • 🔧 Address WuMing review waves on PR #51 a5538ad
    • 🔥 Remove stale Roadmap.md a2ab8dd
    • 📝 Refresh AGENTS.md to match current CI and layout 4a46279
    • 📝 Rewrite README for the current project 94b2e04
    • 🐛 Point the footer at the forge and link versioned docs fb5ea54
    • 👷 Publish versioned docs to the pages branch 7728996
    • 📖 Add MkDocs documentation site 359c812
    • ✨ Remember the hide-read preference in a cookie 61de2b2
    • 💄 Show only the group title on reader cards 57b976a
    • 🔀 Merge branch 'feat/issue-40-container-packaging' 7bcb138
    • 🔧 Cap worker interval digits and default dev labels 516500b
    • 🐛 Run worker init in the background so it stays signal-killable 8778a04
    • 🐛 Address WuMing review waves 4/5 on PR #46 74d4a27
    • ✨ Include extract-media in the worker loop fd7f836
    • 🔧 Rename docker- files to container- for podman setups 4fc421d
    • 🐛 Harden worker entrypoint signal and init handling 4103731
    • 🔁 Re-trigger CI after zhuiri checks-job flake c0fdf6d
    • 🔧 Address WuMing review wave on PR #46 a1cecd9
    • 👷 Build container image in CI 6c0a114
    • 👷 Add container image with web and worker entrypoints 1a73a70
    • 🔀 Merge branch 'feat/issue-37-feed-discovery' 5edc936
    • 🐛 Sanitize rendered discovery errors and scope test logger state f2da211
    • 🐛 Handle feed link type variants and protocol-relative site URLs c9209a0
    • 🐛 Strip control characters from feed discovery error logs 7084583
    • ✨ Add feed discovery to the add-feed page a2d8dc1
    • ✨ Discover feeds from a site homepage 3a7e682
    • 🔀 Merge branch 'feat/issue-42-ui-ux-improvements' 3fe2259
    • 🐛 Keep original media URLs in the rail; Guardian signs its query strings 971a9e3
    • ✅ Build rail test media explicitly instead of deleting fixture rows d4f275b
    • ✨ Ask the LLM for multi-paragraph aggregate overviews 13da9da
    • ✨ Dedupe photo variants in the aggregate media rail e78bc61
    • 🩹 Guard aggregate summary split and strengthen tests 1a00541
    • 🔁 Re-trigger CI after zhuiri checkout flake 841c75f
    • ♻️ Rework aggregate view: sharp title, full overview, media rail 83bc39c
    • 🎨 Show ISO-8601 updated dates on reader cards a17bbd2
    • 🎨 Put nav links inline with the app title and add 云锦 4148092
    • 🔀 Merge branch 'feat/weekly-checks-action' 03aebf3
    • 👷 Run weekly checks on suanni 597ec58
    • 🔧 Add workflow name and least-privilege permissions 0e40ff7
    • 👷 Add weekly dependency and advisory checks 5f3c9f8
    • 🔀 Merge branch 'feat/issue-38-fetcher-resilience' a384214
    • ✅ Address review: scheme-redirect test, log sanitization, stable date 0b995c1
    • ⚡ Refresh feeds concurrently with bounded parallelism 95e866f
    • ✨ Support conditional GET for feed polls b7e9f80
    • ✨ Add per-host politeness gate a4e9181
    • ✨ Add retry with backoff via tenacity 4285428
    • ♻️ Convert feed fetch pipeline to asyncio 34e54d4
    • ⬆️ Bump dependencies 748d257
    • 🔀 Merge branch 'feat/issue-33-featured-image' b5980fd
    • 🐛 Retry blocked article fetches with the extractor identity bca5355
    • 🐛 Send browser headers and reject error pages in article fetches 37ba95d
    • 🐛 Resolve the media directory absolutely when serving 7d4759b
    • 🔒 Guard featured media assignment and sanitize ingest logs 676f6e2
    • ✨ Serve the featured image on reader cards 4878e82
    • ✨ Choose and download the featured image at ingest 4aae169
    • ✨ Add featured image candidate selection service 3f29fb2
    • 🔀 Merge branch 'fix/issue-34-refresh-robustness' e471b34
    • 🔀 Merge branch 'feat/issue-23-full-text' dbf5046
    • ⏪ Group on feed teasers instead of full text 10b3a49
    • 🐛 Degrade gracefully when the LLM invents aggregate ids 906f4ce
    • 🐛 Rewind full-text columns in the legacy-migration fixture 8af76f9
    • ✅ Tighten full-text test assertions 25e1e41
    • ✨ Render stored full text on the article page 5cafd64
    • ✨ Feed article full text to LLM aggregation and summaries 0cbda4a
    • ✨ Store article full text during feed ingestion a5a9d41
    • ➕ Add trafilatura, mistune and nh3 ceb153c
    • 🔀 Merge branch 'feat/issue-20-ignore-rules' dd1b0e1
    • 🔥 Remove unread-aggregate helper superseded by the list query aad5458
    • 🐛 Ignore empty ignore rules in matches_any_rule 23e5770
    • 🐛 Next-unread walk no longer revisits the current group b8043b5
    • ✨ Filter ignored aggregates from the reader and next-unread navigation 8aa0203
    • ✨ Add ignore rules setting with settings-page editor 826371a
    • ✨ Add ignore rules service 5c2ba14
    • 🔀 Merge branch 'feat/issue-22-wider-card-images' 2c0e562
    • ✨ Add card image width display setting 2c5156a
    • ✨ Widen card images via an --aggregate-image-width variable 4ea8d5e
    • 🔀 Merge branch 'feat/issue-21-image-persistence' 0a3d8f8
    • 🔒 Re-validate media redirects, harden Content-Length, filter image media 849e162
    • 🔒 Guard media downloads: URL validation, SVG exclusion, streaming size cap 9d82ec2
    • 🐛 Extract media from feed entry summaries and content fa98e83
    • ✨ Serve stored media from the reader ba13d81
    • ✨ Download article media to local storage bf2cab7
    • ✨ Add local file storage columns to media 1923a60
    • ✅ Add missing test for get_next_aggregate_with_unread 9a3fa36
    • 🔀 Merge branch 'feat/issue-5-keyboard-shortcuts' 857002c
    • ✨ Add g shortcut to open next unread group 3050d53
    • 🐛 Unread route redirects to index; Enter/Space activate focused controls 038cd18
    • ✨ Extend reader shortcuts to groups with unread toggle deff23c
    • 🔒 Restrict shortcut navigation to http/https URLs 0d12a82
    • ✨ Add setting to mark groups read when viewed 6400026
    • ✨ Add FreshRSS-style keyboard shortcuts 45c3310
    • 🔀 Merge branch 'feat/issue-8-display-settings-dark-mode' 1328fec
    • 🙈 Ignore the generated secret key file 9838f7e
    • 🐛 Tag and accent badges use on-accent text colour 8abedec
    • 🐛 Sweep hardcoded colours into theme variables for dark mode 7df4ecf
    • 🐛 Seed default user on web startup for user-keyed writes 48617e2
    • 🔧 Address WuMing review: settings robustness fixes b38705a
    • 🐛 Run database migrations on web app startup 47d1027
    • 🔒 Create secret key atomically with 0600, cover save_settings rollback 4c5805a
    • 🔒 Create secret key file with owner-only permissions 79e2d22
    • 🔒 Harden display settings: secret key, CSS breakout guard, atomic saves a442180
    • ✨ Add display settings: font family, base font size, custom CSS 9d9be10
    • ✨ Add user-settable theme: system, light, or dark 9e48d93
    • ✨ Add per-user settings key/value store ec34850
    • 🔀 Merge branch 'feat/issue-19-aggregate-article-ordering' 0b8ef10
    • ✅ Add deterministic tie-breaker and discriminating ordering tests c4ae5a1
    • ✨ Order aggregate articles newest-first e8df818
    • 🔀 Merge remote-tracking branch 'origin/feat/issue-18-read-unread' f0f30cc
    • ✅ Type mark-aggregate-read return, lock hide_read card links 217f412
    • 🐛 Preserve hide_read filter when marking aggregate as read 33b7873
    • ✨ Add mark-group-read and hide-read toggle to reader 3bfcb47
    • 🔀 Merge branch 'feat/issue-2-feed-user-agent' cdc5e00
    • ✨ Follow feed redirects manually, re-validating each hop through the SSRF guard bd78da3
    • ✅ Assert guard execution in allow-path tests, mock DNS in fetch tests a6674a5
    • ✨ Block SSRF-unsafe feed URLs (schemes, private/loopback/link-local hosts) 4b26273
    • 🐛 Address WuMing review: whitespace UA fallback, independent test literal, monkeypatch 224f2b6
    • 🐛 Treat empty YUNJIN_HTTP_USER_AGENT as unset 15952f7
    • ✅ Lock User-Agent default assertion and isolate env in test f9b1172
    • 🐛 Send browser-like User-Agent when fetching RSS feeds f669f0c
    • 🔀 Merge branch 'feat/issue-10-httpx2-migration' 7201df4
    • 📝 Update dependency summary in Roadmap.md c07eef8
    • ♻️ Migrate HTTP client from httpx to httpx2 99731f0
    • 🔀 Merge branch 'feat/issue-9-justfile' 3e8b960
    • fix: replace remaining cang references with yunjin in bumpversion config a2dd5de
    • fix: add transitive dependency constraints to resolve pysentry findings a9f7e8f
    • chore: remove per-release RELEASE_NOTES_*.md files (single Release-Notes.md from now on) c26fe8f
    • wrench: Adopt Marvin8 platform tooling improvements 37ac527
    • 📝 Polish pre-commit, justfile, noxfile, and pylock 451a2ae
    • wrench: Add calver parse/serialize to bumpversion config a850615
    • memo: Add justfile with release recipe 21a67b0
    • wrench: Replace uv-ship with bump-my-version in pyproject.toml d0971ef
    • 🔀 Merge branch 'feat/issue-1-llm-aggregation' 819d86a
    • 🚨 Fix ruff violations in test file and wsgi.py 71c49de
    • 📝 Improve aggregation prompt: group by individual news story not broad topic e6226d5
    • ✨ Replace embedding/DBSCAN aggregation with LLM-based pipeline 424e589
    • 🔀 Merge branch 'feat/issue-7-forgejo-actions-ci' cb10edb
    • 📝 Migrate to gitleaks git subcommand, clarify CI docs 5e08d4a
    • 🔧 Allowlist detect-secrets baseline from gitleaks scan b2f56de
    • 🐛 Fix gitleaks job scanning /tmp instead of repo, split install step d873323
    • 📝 Address WuMing review: clarify CI docs, add reader row-builder test 250fe3f
    • 👷 Add Forgejo Actions CI with checks, gitleaks, and WuMing review 3aaf400
    • 🔧 Add noxfile.py with ty, ruff, complexipy, and pytest sessions 5cac5f2
    • ♻️ Refactor reader index to fix type and complexity errors d730532
    • 🔀 Merge branch 'docs/issue-3-add-agents-md' fcc3f79
    • 📝 CHANGELOG.md is generated by the justfile release recipe e135123
    • 📝 Address review: httpx2 convention, just releases, global release-notes steps d9801f9
    • 📝 Replace LLM_SYSTEM_PROMPT.md with project AGENTS.md 2892ab8
    • Docs: Officially abandoning this project. Also commiting latest local work. c68b09b
    • Feat: Various improvements around tag extraction, getting full text of news if available in feed, adjust aggregation defaults. 007b778
    Downloads