Patch release rolling up 10 fixes from the post-v26.05.25.0 work session.
Maintenance / recovery
9d5abb0recover_interrupted_tasks now sweeps pending/queued orphans (>30 min) to failed, not just processing (>5 min). Fixes the 5,490-row pile operator hit when scan_directory crashed mid-enqueue.
b6a917a/api/import/clear-stuck endpoint + "Clear stuck..." UI button on the import task list. Manual escape hatch for the autoretry-loop case the automatic sweep can't break (e.g., corrupt file PIL OSError loop).
3a359f6 Quick scan button always visible, disabled when an active batch is present, with an inline "Clear stuck" action next to the spinner. Operator was unable to start scans because the wedged batch hid the button.
ML pipeline
3b3e756 Tagger + downloader aligned with actual Camie v2 HF layout: camie-tagger-v2.onnx (not model.onnx), JSON metadata (not selected_tags.csv), ImageNet normalize, NCHW, sigmoid on refined logits. Verified against the published onnx_inference.py reference.
6b1bb87 Pinned-test rename to match Camie v2 filenames.
Importer resilience
68cffce Importer catches PIL.OSError during _transparency_pct + compute_phash and skips as invalid_image instead of letting Celery autoretry loop forever on a corrupt file. Operator hit this with a broken JPEG in the IR set.
Gallery sort/display
c361032 Gallery scroll / timeline / jump / neighbor-nav now sort/group by COALESCE(post.post_date, image_record.created_at). Migrated content surfaces at its original publish date, not FC's scan-week date. tag_apply phase 4 now sets image_record.primary_post_id (idempotent, doesn't clobber importer-set values). API response gains posted_at + effective_date fields alongside the existing created_at for future modal display.
9f54efd tag_apply phase 4 now covers deviantart + pixiv (was silently dropping ALL PostMetadata for those platforms). Operator's missing IR provenance had this as one of two root causes.
UI polish
52445eb Directory card width 220px → 440px; preview slots get explicit min/max-height + overflow: hidden so tall source images can't escape on browsers where aspect-ratio doesn't compute.
Migration recovery notes
After deploy, to backfill IR-migrated images with their post dates and pick up the previously-skipped DeviantArt + Pixiv entries:
Run /api/migrate/tag_apply again on the existing manifest (phase 4 is idempotent; existing rows pass through; new primary_post_id and new platform-coverage entries backfill).
Patch release rolling up 10 fixes from the post-v26.05.25.0 work session.
## Maintenance / recovery
- **`9d5abb0`** `recover_interrupted_tasks` now sweeps pending/queued orphans (>30 min) to `failed`, not just `processing` (>5 min). Fixes the 5,490-row pile operator hit when `scan_directory` crashed mid-enqueue.
- **`b6a917a`** `/api/import/clear-stuck` endpoint + "Clear stuck..." UI button on the import task list. Manual escape hatch for the autoretry-loop case the automatic sweep can't break (e.g., corrupt file PIL OSError loop).
- **`3a359f6`** Quick scan button always visible, disabled when an active batch is present, with an inline "Clear stuck" action next to the spinner. Operator was unable to start scans because the wedged batch hid the button.
## ML pipeline
- **`3b3e756`** Tagger + downloader aligned with actual Camie v2 HF layout: `camie-tagger-v2.onnx` (not `model.onnx`), JSON metadata (not `selected_tags.csv`), ImageNet normalize, NCHW, sigmoid on refined logits. Verified against the published `onnx_inference.py` reference.
- **`6b1bb87`** Pinned-test rename to match Camie v2 filenames.
## Importer resilience
- **`68cffce`** Importer catches `PIL.OSError` during `_transparency_pct` + `compute_phash` and skips as `invalid_image` instead of letting Celery autoretry loop forever on a corrupt file. Operator hit this with a broken JPEG in the IR set.
## Gallery sort/display
- **`c361032`** Gallery scroll / timeline / jump / neighbor-nav now sort/group by `COALESCE(post.post_date, image_record.created_at)`. Migrated content surfaces at its original publish date, not FC's scan-week date. tag_apply phase 4 now sets `image_record.primary_post_id` (idempotent, doesn't clobber importer-set values). API response gains `posted_at` + `effective_date` fields alongside the existing `created_at` for future modal display.
- **`9f54efd`** tag_apply phase 4 now covers `deviantart` + `pixiv` (was silently dropping ALL PostMetadata for those platforms). Operator's missing IR provenance had this as one of two root causes.
## UI polish
- **`52445eb`** Directory card width 220px → 440px; preview slots get explicit min/max-height + `overflow: hidden` so tall source images can't escape on browsers where `aspect-ratio` doesn't compute.
## Migration recovery notes
After deploy, to backfill IR-migrated images with their post dates and pick up the previously-skipped DeviantArt + Pixiv entries:
1. Run `/api/migrate/tag_apply` again on the existing manifest (phase 4 is idempotent; existing rows pass through; new `primary_post_id` and new platform-coverage entries backfill).
2. Gallery + timeline + jump immediately reflect publish dates after that.
## Schema changes
None. All fixes are logic-only.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Patch release rolling up 10 fixes from the post-v26.05.25.0 work session.
Maintenance / recovery
9d5abb0recover_interrupted_tasksnow sweeps pending/queued orphans (>30 min) tofailed, not justprocessing(>5 min). Fixes the 5,490-row pile operator hit whenscan_directorycrashed mid-enqueue.b6a917a/api/import/clear-stuckendpoint + "Clear stuck..." UI button on the import task list. Manual escape hatch for the autoretry-loop case the automatic sweep can't break (e.g., corrupt file PIL OSError loop).3a359f6Quick scan button always visible, disabled when an active batch is present, with an inline "Clear stuck" action next to the spinner. Operator was unable to start scans because the wedged batch hid the button.ML pipeline
3b3e756Tagger + downloader aligned with actual Camie v2 HF layout:camie-tagger-v2.onnx(notmodel.onnx), JSON metadata (notselected_tags.csv), ImageNet normalize, NCHW, sigmoid on refined logits. Verified against the publishedonnx_inference.pyreference.6b1bb87Pinned-test rename to match Camie v2 filenames.Importer resilience
68cffceImporter catchesPIL.OSErrorduring_transparency_pct+compute_phashand skips asinvalid_imageinstead of letting Celery autoretry loop forever on a corrupt file. Operator hit this with a broken JPEG in the IR set.Gallery sort/display
c361032Gallery scroll / timeline / jump / neighbor-nav now sort/group byCOALESCE(post.post_date, image_record.created_at). Migrated content surfaces at its original publish date, not FC's scan-week date. tag_apply phase 4 now setsimage_record.primary_post_id(idempotent, doesn't clobber importer-set values). API response gainsposted_at+effective_datefields alongside the existingcreated_atfor future modal display.9f54efdtag_apply phase 4 now coversdeviantart+pixiv(was silently dropping ALL PostMetadata for those platforms). Operator's missing IR provenance had this as one of two root causes.UI polish
52445ebDirectory card width 220px → 440px; preview slots get explicit min/max-height +overflow: hiddenso tall source images can't escape on browsers whereaspect-ratiodoesn't compute.Migration recovery notes
After deploy, to backfill IR-migrated images with their post dates and pick up the previously-skipped DeviantArt + Pixiv entries:
/api/migrate/tag_applyagain on the existing manifest (phase 4 is idempotent; existing rows pass through; newprimary_post_idand new platform-coverage entries backfill).Schema changes
None. All fixes are logic-only.
🤖 Generated with Claude Code