Commit Graph
100 Commits
Author SHA1 Message Date
bvandeusenandClaude Opus 4.7 d4d8976f29 feat(integrity): image-detail payload includes integrity_status
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:53:54 -04:00
bvandeusenandClaude Opus 4.7 c37a3c9b55 feat(integrity): /api/system/stats exposes integrity counts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:53:12 -04:00
bvandeusenandClaude Opus 4.7 389d1bb0cf feat(integrity): /trigger accepts mode=verify → enqueues verify_integrity
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:52:18 -04:00
bvandeusenandClaude Opus 4.7 e28de547c7 feat(integrity): verify_integrity task (keyset, fail-soft) + weekly beat
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:51:33 -04:00
bvandeusenandClaude Opus 4.7 c33741837b fix(test): drop obsolete FC-2a deep-rejected assertion (deep now accepted in 2d-vi)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:33:16 -04:00
bvandeusenandClaude Opus 4.7 5dfdbf5a60 feat(deep-scan): Importer(deep=) re-derive on sha-match; import_file wires batch.scan_mode
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:32:26 -04:00
bvandeusenandClaude Opus 4.7 9535533385 feat(deep-scan): trigger accepts 'deep'; scan_directory(mode) + enqueue backfill_phash
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:31:26 -04:00
bvandeusenandClaude Opus 4.7 ae67e67299 feat(deep-scan): keyset-paginated backfill_phash task
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 14:59:04 -04:00
bvandeusenandClaude Opus 4.7 7dea165fae fix(test): archive members need structured imgs+threshold0; provenance payload gained attachments key
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:22:17 -04:00
bvandeusenandClaude Opus 4.7 cba662a900 feat(attachments): downloadable attachments in ProvenancePanel + PostInfoHeader
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:17:14 -04:00
bvandeusenandClaude Opus 4.7 74e34d359b feat(attachments): provenance payload attachments + download route
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:16:01 -04:00
bvandeusenandClaude Opus 4.7 89103c4570 feat(attachments): scan enumerates all; import_file maps 'attached' + member ML
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:14:49 -04:00
bvandeusenandClaude Opus 4.7 f97551e2f6 feat(attachments): importer dispatch — archive extract + non-media capture
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:13:36 -04:00
bvandeusenandClaude Opus 4.7 df76fd75d8 feat(attachments): fail-soft archive_extractor (zip/cbz/rar/7z)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:11:37 -04:00
bvandeusenandClaude Opus 4.7 1475bad48b feat(attachments): sha-addressed AttachmentStore
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:11:07 -04:00
bvandeusenandClaude Opus 4.7 8f69478227 feat(attachments): PostAttachment model + 0009 (table + batch counter)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:10:53 -04:00
bvandeusenandClaude Opus 4.7 e3f6e6fadd fix(test): artist_service _fixture sets artist_id (post-vii-c ArtistService reads it)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:47:45 -04:00
bvandeusenandClaude Opus 4.7 80701dabf7 fix(test): update FC-2b/2a tests that pinned pre-vii-c artist behavior
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:39:54 -04:00
bvandeusenandClaude Opus 4.7 9d61f0da44 feat(provenance): drop artist tag-kind affordances from the UI
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:37:18 -04:00
bvandeusenandClaude Opus 4.7 592c665701 feat(provenance): ML stops surfacing the artist category
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:36:43 -04:00
bvandeusenandClaude Opus 4.7 e798302cfa feat(provenance): _artists_for resolves via artist_id (closes vii-b gap)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:36:16 -04:00
bvandeusenandClaude Opus 4.7 aaf5d1ea70 feat(provenance): ArtistService resolves images via artist_id
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:34:30 -04:00
bvandeusenandClaude Opus 4.7 914cf14d9e feat(provenance): importer sets image_record.artist_id, stops minting artist tags
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:33:55 -04:00
bvandeusenandClaude Opus 4.7 63e7185811 feat(provenance): image_record.artist_id + 0008 backfill/drop-artist-tags
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 21:33:11 -04:00
bvandeusenandClaude Opus 4.7 8fe1994d8e feat(provenance): GalleryView post_id filter + PostInfoHeader wiring
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:18:05 -04:00
bvandeusenandClaude Opus 4.7 8abdaa4393 feat(provenance): modal sidebar stacks ProvenancePanel above Tags
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:17:42 -04:00
bvandeusenandClaude Opus 4.7 7e904f41b5 feat(provenance): always-on artist label on gallery thumbnails
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:17:17 -04:00
bvandeusenandClaude Opus 4.7 06f4c81418 feat(provenance): PostInfoHeader for the post-filtered gallery
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:17:02 -04:00
bvandeusenandClaude Opus 4.7 b69d637b77 feat(provenance): ProvenancePanel — peer post cards (read-only)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:16:46 -04:00
bvandeusenandClaude Opus 4.7 b33253429a feat(provenance): gallery store post_id filter (mutually exclusive with tag_id)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:16:09 -04:00
bvandeusenandClaude Opus 4.7 7bfd700671 feat(provenance): provenance store (cached image/post lookups)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:15:42 -04:00
bvandeusenandClaude Opus 4.7 63a7cbdde4 feat(provenance): locale-independent formatPostDate util
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:15:23 -04:00
bvandeusenandClaude Opus 4.7 f6d5353b3b feat(provenance): per-image artist on gallery scroll payload
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:15:07 -04:00
bvandeusenandClaude Opus 4.7 7014e6827d fix(test): ruff F841 — don't bind unmatched seed images (tuple-unpack flagged)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:29:18 -04:00
bvandeusenandClaude Opus 4.7 1590447301 feat(provenance): post_id/artist_id gallery filters via EXISTS (mutually exclusive)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:08:54 -04:00
bvandeusenandClaude Opus 4.7 bb3fb5145a feat(provenance): /api/provenance image + post endpoints
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:07:06 -04:00
bvandeusenandClaude Opus 4.7 0de8eaa4c6 feat(provenance): ProvenanceService.for_post (post-header payload)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:06:36 -04:00
bvandeusenandClaude Opus 4.7 491bdcb943 feat(provenance): ProvenanceService.for_image (peer provenance rows)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:06:15 -04:00
bvandeusenandClaude Opus 4.7 3b5f894435 feat(provenance): nh3 HTML sanitizer for scraped post descriptions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:05:45 -04:00
bvandeusenandClaude Opus 4.7 9d433fc1ab fix(test): sidecar idempotency needs phash_threshold=0 (orthogonal splits collapse at default)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:13:48 -04:00
bvandeusenandClaude Opus 4.7 9b79b66b76 feat(sidecar): importer creates Source/Post/ImageProvenance from sidecars (idempotent, fail-soft)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 14:46:17 -04:00
bvandeusenandClaude Opus 4.7 ef7e4d92a9 feat(sidecar): minimal gallery-dl sidecar find + parse util
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 14:44:37 -04:00
bvandeusenandClaude Opus 4.7 15dac50367 feat(post): add nullable description + attachment_count (migration 0007)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 09:38:43 -04:00
bvandeusenandClaude Opus 4.7 3f2f50cdb9 fix(test): threshold test needs structured images (solid colors phash-collapse)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:25:48 -04:00
bvandeusenandClaude Opus 4.7 7f55f360a3 fix(test): phash 'far' case needs structured images — solid colors phash-collapse
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:18:07 -04:00
bvandeusenandClaude Opus 4.7 c408ffd5fc feat(phash): ImportFiltersForm exposes phash_threshold
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:07:44 -04:00
bvandeusenandClaude Opus 4.7 4d5564c363 feat(phash): import task maps 'superseded' to complete + re-queues ML/thumbnail
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:06:46 -04:00
bvandeusenandClaude Opus 4.7 a510378603 feat(phash): importer near-dup dispatch + in-place supersession (clear ML)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:05:43 -04:00
bvandeusenandClaude Opus 4.7 9ef5e5047d feat(phash): import_settings.phash_threshold (migration 0006) exposed + validated in API
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:04:13 -04:00
bvandeusenandClaude Opus 4.7 d2e8dd3a3b feat(phash): compute_phash + find_similar util (hash_size=8, fits existing column)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:02:42 -04:00
bvandeusenandClaude Opus 4.7 d00379905e feat(reader): Read entry points — TagCard icon, TagsView route, SeriesManageView button
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:31:40 -04:00
bvandeusenandClaude Opus 4.7 0d838bf50d feat(reader): SeriesReaderView — IR-faithful immersive series reader
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:30:48 -04:00
bvandeusenandClaude Opus 4.7 4fb176faf6 feat(reader): seriesReader store + pure scroll/progress/clamp helpers
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:29:57 -04:00
bvandeusenandClaude Opus 4.7 f52c31367a feat(reader): immersive series-read route + route-aware AppShell (suppress TopNav)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:29:21 -04:00
bvandeusenandClaude Opus 4.7 129af2e594 feat(series): list_pages returns full image_url for the reader
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:28:20 -04:00
bvandeusenandClaude Opus 4.7 9e96525234 fix(test): seriesManage reorder spec must not JSON.parse the bodyless GET refresh
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 12:21:15 -04:00
bvandeusenandClaude Opus 4.7 886284d182 feat(series): SeriesManageView + /series/:tagId route + TagCard manage affordance
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:38:20 -04:00
bvandeusenandClaude Opus 4.7 b19aff198e feat(series): seriesManage Pinia store + pure moveItem reorder helper
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:36:44 -04:00
bvandeusenandClaude Opus 4.7 a9e7ee9ba9 feat(series): TagService.merge repoints series_page.series_tag_id
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:36:04 -04:00
bvandeusenandClaude Opus 4.7 d8e585a76e feat(series): /api/series pages/add/remove/reorder/cover routes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:35:12 -04:00
bvandeusenandClaude Opus 4.7 0db76c70e8 feat(series): SeriesService list/add(move)/remove/reorder/cover with guards
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:34:17 -04:00
bvandeusenandClaude Opus 4.7 b83baa7d7f feat(series): SeriesPage model + 0005 migration (unique image, ordered pages)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:33:12 -04:00
bvandeusenandClaude Opus 4.7 9062942af6 feat(nav): teleport Gallery Select into the nav action slot
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:40:39 -04:00
bvandeusenandClaude Opus 4.7 a2529d750a feat(nav): teleport Showcase Shuffle into the nav action slot
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:40:14 -04:00
bvandeusenandClaude Opus 4.7 af2598451c feat(nav): health dot beside wordmark + #fc-nav-actions per-view slot
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:39:36 -04:00
bvandeusenandClaude Opus 4.7 5a6070c3fa fix(theme): define on-surface-variant = vellum so muted body text stays readable on obsidian
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:01:51 -04:00
bvandeusenandClaude Opus 4.7 85b6f37e3d fix(bulk): Select toggle in a right-aligned toolbar, not floated over the nav health marker
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:48:59 -04:00
bvandeusenandClaude Opus 4.7 35e26d6226 fix(bulk): node-safe toast (globalThis.window) + common-tags test matches non-empty spec guard
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:15:23 -04:00
bvandeusenandClaude Opus 4.7 82689e10bc feat(bulk): IR-style BulkEditorPanel + GalleryView select toggle and wiring
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:05:33 -04:00
bvandeusenandClaude Opus 4.7 bff9af1478 feat(bulk): GalleryItem select-mode click + checkbox/order-badge overlay
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:04:29 -04:00
bvandeusenandClaude Opus 4.7 349d8e50ef feat(bulk): gallerySelection Pinia store with order, mode, bulk actions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:03:54 -04:00
bvandeusenandClaude Opus 4.7 f946918cd2 feat(bulk): SuggestionService.for_selection consensus + POST /api/suggestions/bulk
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:03:16 -04:00
bvandeusenandClaude Opus 4.7 e1c8400c87 feat(bulk): BulkTagService (common_tags/bulk_add/bulk_remove) + 3 image bulk-tag routes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:02:01 -04:00
bvandeusenandClaude Opus 4.7 93b6fc21c8 fix(tags): invalid 'copyright' kind 500 — KINDS uses real enum 'fandom'; directory 400s on bad kind
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:51:27 -04:00
bvandeusenandClaude Opus 4.7 98c9fb9402 fix(tests): read column values not stale ORM entities after Core-DML merge (MissingGreenlet)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:48:50 -04:00
bvandeusenandClaude Opus 4.7 a50701ee6d feat(frontend): inline tag rename, merge confirm dialog, TagsView wiring
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:42:46 -04:00
bvandeusenandClaude Opus 4.7 1d1574e586 feat(frontend): tagDirectory rename and merge store actions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:41:20 -04:00
bvandeusenandClaude Opus 4.7 305687dc33 feat(api): rich 409 merge hint and POST tags merge endpoint with backfill enqueue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:40:37 -04:00
bvandeusenandClaude Opus 4.7 8fbeabe9ba feat(tags): protective alias creation per observed tagger category with kind fallback
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:39:16 -04:00
bvandeusenandClaude Opus 4.7 33efba8bf5 feat(tags): merge repoints allowlist, embedding, aliases, fandom children
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:38:27 -04:00
bvandeusenandClaude Opus 4.7 003181ed41 feat(tags): merge repoints image_tag and tag_suggestion_rejection with dedup
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:36:13 -04:00
bvandeusenandClaude Opus 4.7 e0a455466d feat(tags): TagService.merge guards + MergeResult + repoint stubs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:35:26 -04:00
bvandeusenandClaude Opus 4.7 96e6003b66 feat(tags): TagMergeConflict + provenance helper, enrich rename collision
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:34:25 -04:00
bvandeusen 062a87e968 feat(ui): drop active-link underline + redundant page-title headers 2026-05-15 23:27:38 -04:00
bvandeusen e92b05028b feat(ui): nav order — Showcase before Gallery 2026-05-15 23:18:59 -04:00
bvandeusen 9bb801a566 refactor(ui): AppShell = TopNav + content slot (drop left drawer/v-main) 2026-05-15 23:14:20 -04:00
bvandeusen 18ad61265e feat(ui): IR-style gradient-fade TopNav (brand, centered links, health) 2026-05-15 23:13:42 -04:00
bvandeusen 4a29a6d197 fix(web): pass create_app as a hypercorn factory (backend.app:create_app()) 2026-05-15 22:53:49 -04:00
bvandeusen dfa6a5c895 fix(integration): lazy seed-snapshot (unblock unit job); isolate recover test from eager import 2026-05-15 22:43:46 -04:00
bvandeusen 7a896605e0 fix(integration): snapshot/restore seeded singletons, dispose app engine per test 2026-05-15 22:35:37 -04:00
bvandeusen 13be9085b5 fix(integration): asyncio auto-mode, per-test truncation, artist images IN-subquery 2026-05-15 22:23:32 -04:00
bvandeusen 65a055408b ci(integration): reach services by bridge IP via docker socket, no host ports 2026-05-15 22:18:01 -04:00
bvandeusen cd8d0bd606 ci(integration): publish service ports, connect via localhost (host runner) 2026-05-15 22:02:43 -04:00
bvandeusen 827a4180a9 ci(integration): add pgvector+redis integration job; amend lint-only policy 2026-05-15 21:46:10 -04:00
bvandeusen 5faa19234d fix(fc2c-i): assert / redirect via navigation, not resolve() 2026-05-15 21:29:52 -04:00
bvandeusen 5a4663fa3d fix(fc2c-i): router falls back to memory history when no window (vitest) 2026-05-15 21:27:28 -04:00
bvandeusen 85d8b4b150 fix(fc2c-i): vitest needs plugin-vue to transform SFCs in router.spec 2026-05-15 21:15:04 -04:00
bvandeusen 4c1cabe4ee feat(fc2c-i): rich artist page with sparkline and FC-4 stubs 2026-05-15 21:14:07 -04:00
bvandeusen a984149ee2 feat(fc2c-i): tag directory view with previews, filter, search 2026-05-15 21:13:26 -04:00
bvandeusen c17c4b1667 feat(fc2c-i): showcase view with shortest-column masonry 2026-05-15 21:12:53 -04:00