Media management — wayfinder map #181

Closed
opened 2026-08-12 04:12:45 +00:00 by rosa · 1 comment
Owner

Destination

Every design decision locked for the two-part media-manage surface: (a) a picker in the post editor for selecting already-uploaded Media, and (b) a per-user media library page (list, upload, delete). Plan-only: the map ends when an implementation spec exists and nothing is left to decide — the build happens in ordinary sessions afterwards. (Redrawn: growing the Micropub media endpoint to full capability was originally part (c); see Out of scope.)

Reached — the spec is Media management: Library page and editor picker — implementation spec (ready-for-agent).

Notes

  • Domain language lives in CONTEXT.md (Media, Photo, Library, Processing/Ready/Failed, Reconciler); relevant ADRs are 0017–0021 (media storage, capability URLs, one-create-op-behind-adapters, deferred processing, staged originals) and 0023 (space reclamation — the mechanism that makes delete actually return disk).
  • Grilling tickets use /grilling + /domain-modeling; prototype tickets use /prototype; research tickets are resolved by a /research subagent capturing findings on a throwaway research/<name> branch.
  • Blocking is expressed in prose in each ticket body (a "Blocked by" line), not via native dependencies. Child tickets are the open issues carrying a wayfinder:* label.
  • Standing decisions from charting: delete is warn-and-allow (show affected Posts, then detach — the SET NULL machinery already exists); the picker complements inline upload, which stays; the library is strictly per-user.

Decisions so far

  • Survey Micropub media-endpoint extensions and client behavior — target Quill + Sparkles; list via GET ?q=source[&limit&offset] returning {"items":[{url, published, mime_type}]} newest-first (bare object for &url= lookup, 400 on unknown); delete via form-encoded POST action=delete&url= to the media endpoint, gated on delete+media scopes. (The endpoint growth these shapes were for was later ruled out of scope; the findings stand on record.)
  • Does Media grow user-facing metadata? — capture the original filename as an opaque, read-only display label (basename only, length-capped, absent allowed; display falls back to upload date); alt stays strictly per-Post on Photo; no other new metadata — library/picker show the existing date, status, and Ready-rendition dimensions.
  • Design the media library page — the Library (now in the glossary): route /media, "Media" nav entry; newest-first square-tile grid, no pagination, tiles lazy-load the full rendition (no thumbnail pipeline); single-file upload via create_media; Processing tiles display-only, Failed deletable with no retry; delete via the standard confirm page listing referencing Posts (title → slug) with status, then detach-and-delete.
  • Prototype the media picker in the post editor — variant A wins: the file input stays primary with a collapsed "pick from your library" tile grid beneath it; precedence extends to remove > upload > pick > keep with upload and pick mutually exclusive; Processing tiles disabled, Failed excluded; no CSP change needed. Prototype preserved on branch prototype/media-picker.
  • Assemble the implementation spec — spec published as #188, folding every decision plus the domain-op shapes: MediaFilename capture through both adapters; list_media_for, resolve_owned_photo (id-based ownership check, Micropub's resolve_photo delegates to it), list_posts_referencing, delete_media (owner-scoped, Processing refused); repository-port additions with conformance tests; web routes/pages; docs need only a one-line CONTEXT.md deletion note, no new ADR.

Not yet specified

Nothing — the way is clear. Every decision is closed and the destination is reached; implementation proceeds from the spec.

Out of scope

  • Growing the Micropub media endpoint to full capability (q=source listing + delete) — Map q=source and delete onto the domain closed unresolved: Micropub's client base is too small to justify the extra protocol surface. Clients keep plain upload; listing and delete live in the web library only.
  • Automatic orphan-Media garbage collection — already-tracked debt (ADR-0017, issue #134).
  • Multi-photo Posts — "a Post has at most one Photo" is untouched by this effort.
  • An Operator/admin media surface (browse or delete other users' Media).
  • Swapping a Post's Photo from the library side ("use this on…").
## Destination Every design decision locked for the two-part media-manage surface: (a) a picker in the post editor for selecting already-uploaded Media, and (b) a per-user media library page (list, upload, delete). Plan-only: the map ends when an implementation spec exists and nothing is left to decide — the build happens in ordinary sessions afterwards. (Redrawn: growing the Micropub media endpoint to full capability was originally part (c); see Out of scope.) **Reached** — the spec is [Media management: Library page and editor picker — implementation spec](https://code.cosmicrose.dev/rosa/vernier/issues/188) (`ready-for-agent`). ## Notes - Domain language lives in `CONTEXT.md` (Media, Photo, Library, Processing/Ready/Failed, Reconciler); relevant ADRs are 0017–0021 (media storage, capability URLs, one-create-op-behind-adapters, deferred processing, staged originals) and 0023 (space reclamation — the mechanism that makes delete actually return disk). - Grilling tickets use `/grilling` + `/domain-modeling`; prototype tickets use `/prototype`; research tickets are resolved by a `/research` subagent capturing findings on a throwaway `research/<name>` branch. - Blocking is expressed **in prose** in each ticket body (a "Blocked by" line), not via native dependencies. Child tickets are the open issues carrying a `wayfinder:*` label. - Standing decisions from charting: delete is **warn-and-allow** (show affected Posts, then detach — the `SET NULL` machinery already exists); the picker **complements** inline upload, which stays; the library is strictly per-user. ## Decisions so far - [Survey Micropub media-endpoint extensions and client behavior](https://code.cosmicrose.dev/rosa/vernier/issues/182) — target Quill + Sparkles; list via `GET ?q=source[&limit&offset]` returning `{"items":[{url, published, mime_type}]}` newest-first (bare object for `&url=` lookup, 400 on unknown); delete via form-encoded `POST action=delete&url=` to the media endpoint, gated on `delete`+`media` scopes. *(The endpoint growth these shapes were for was later ruled out of scope; the findings stand on record.)* - [Does Media grow user-facing metadata?](https://code.cosmicrose.dev/rosa/vernier/issues/183) — capture the original filename as an opaque, read-only display label (basename only, length-capped, absent allowed; display falls back to upload date); alt stays strictly per-Post on Photo; no other new metadata — library/picker show the existing date, status, and Ready-rendition dimensions. - [Design the media library page](https://code.cosmicrose.dev/rosa/vernier/issues/184) — the **Library** (now in the glossary): route `/media`, "Media" nav entry; newest-first square-tile grid, no pagination, tiles lazy-load the full rendition (no thumbnail pipeline); single-file upload via `create_media`; Processing tiles display-only, Failed deletable with no retry; delete via the standard confirm page listing referencing Posts (title → slug) with status, then detach-and-delete. - [Prototype the media picker in the post editor](https://code.cosmicrose.dev/rosa/vernier/issues/185) — variant A wins: the file input stays primary with a collapsed "pick from your library" tile grid beneath it; precedence extends to remove > upload > pick > keep with upload and pick mutually exclusive; Processing tiles disabled, Failed excluded; no CSP change needed. Prototype preserved on branch `prototype/media-picker`. - [Assemble the implementation spec](https://code.cosmicrose.dev/rosa/vernier/issues/187) — spec published as [#188](https://code.cosmicrose.dev/rosa/vernier/issues/188), folding every decision plus the domain-op shapes: `MediaFilename` capture through both adapters; `list_media_for`, `resolve_owned_photo` (id-based ownership check, Micropub's `resolve_photo` delegates to it), `list_posts_referencing`, `delete_media` (owner-scoped, Processing refused); repository-port additions with conformance tests; web routes/pages; docs need only a one-line CONTEXT.md deletion note, no new ADR. ## Not yet specified Nothing — the way is clear. Every decision is closed and the destination is reached; implementation proceeds from [the spec](https://code.cosmicrose.dev/rosa/vernier/issues/188). ## Out of scope - Growing the Micropub media endpoint to full capability (`q=source` listing + delete) — [Map q=source and delete onto the domain](https://code.cosmicrose.dev/rosa/vernier/issues/186) closed unresolved: Micropub's client base is too small to justify the extra protocol surface. Clients keep plain upload; listing and delete live in the web library only. - Automatic orphan-Media garbage collection — already-tracked debt (ADR-0017, issue #134). - Multi-photo Posts — "a Post has at most one Photo" is untouched by this effort. - An Operator/admin media surface (browse or delete other users' Media). - Swapping a Post's Photo from the library side ("use this on…").
rosa changed title from Media management & full media endpoint — wayfinder map to Media management — wayfinder map 2026-08-12 04:48:58 +00:00
Author
Owner

Destination reached: the implementation spec is #188 and nothing is left to decide. All tickets closed; the build proceeds from the spec in ordinary sessions.

Destination reached: the implementation spec is #188 and nothing is left to decide. All tickets closed; the build proceeds from the spec in ordinary sessions.
rosa closed this issue 2026-08-12 05:49:02 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rosa/vernier#181
No description provided.