Skip to content

spec: media upload routes, attachments on post/comment writes — release v0.13.0 - #42

Merged
bvalosek merged 3 commits into
mainfrom
spec/media-upload-attachments
Sep 9, 2026
Merged

spec: media upload routes, attachments on post/comment writes — release v0.13.0#42
bvalosek merged 3 commits into
mainfrom
spec/media-upload-attachments

Conversation

@bvalosek

@bvalosek bvalosek commented Sep 9, 2026

Copy link
Copy Markdown
Member

What

Re-sync of the platform contract from metalabel-dfos at f91497523 (main) — merged platform PRs since v0.12.0 that reach the document: #3286 (external API media upload routes, attachments on post/comment writes), #3289 (hoisted error rows, FeedSpaceRefOutput id/did split), and #3295 (a covering grant widens space addressability — description-only in the document, behavior change at runtime, see below). #3291, #3294, #3296, and #3297 also merged in the window and moved nothing in the compiled document. Bumps to v0.13.0.

Generated from the local platform checkout at that SHA (merge truth). These platform changes are merged but not yet deployed; the snapshot describes them ahead of api.dfos.com, per the README's pre-1.0 note.

⚠️ One wire-level break, invisible to the compiler

FeedSpaceRefOutput.id changes meaning. It was the space's protocol DID (did:dfos:…). It is now the space's stable entity id (space_…), and a new required did: string carries the DID. The TypeScript type of id is unchanged (string), so nothing fails to compile. What breaks at runtime:

  • Anyone parsing feed space.id as a DID (regex, did:dfos: prefix check, handing it to the protocol client) gets a space_… id instead.
  • Anyone passing feed space.id back as {space} on a space route keeps working. Both the entity id and the DID are accepted there.

Migration: read space.did where you need the DID. Pre-1.0 the repo rule keeps this a minor; the break is called out here and should be in the release notes.

Runtime behavior change on private spaces (#3295, no shape change)

The document change is one description string on FeedSpaceRefOutput.id. What a consumer notices is on the wire:

  • On a space with no public profile, a request on the credential-aware routes (posts, comments, media) carrying a credential that covers the space (or a bare identity proof) from a live member now gets the member projection on reads and success on writes, where it got 404 before. Private spaces round-trip from the feed for members.
  • Writes by non-members of a private space are now 404 rather than 403. The space does not resolve for them, so the route answers as if it does not exist.
  • The anonymous routes (GET /spaces/{space}, pages, topics, events, products, releases) still require a public profile. Unchanged.

Everything else a consumer notices (additive)

  • New media namespace (41 → 43 operations). media.createUpload is POST /spaces/{space}/media (201, input { filename, contentType, size }, output PublicMediaUploadOutput = { media: PublicOwnMediaOutput, upload: { url, method: 'PUT', headers: { 'Content-Type', 'Content-Disposition' }, expiresAt } }). media.getUpload is GET /spaces/{space}/media/{mediaId} returning PublicOwnMediaOutput.
  • Two new schemas. PublicOwnMediaOutput is PublicMediaOutput with url optional plus uploaded: boolean. PublicMediaUploadOutput wraps it (by $ref) with the presigned upload.
  • attachments?: string[] added to the createPost / editPost / createComment / editComment request bodies.
  • PublicCommentOutput.attachments: PublicMediaOutput[] added.
  • Comment body is now optional on create and edit (at least one of body/attachments server-side). Because every field on those two inputs is now optional, the whole requestBody is optional on those operations. Loosening only.
  • Error rows hoisted onto operations. Two new named responses, InvalidRequest (400) and InternalError (500). Every proof-bearing read now declares 401/403/413, every validating read declares 400 (all but GET /protocol), 415 is declared on every credential-gated path, and 500 is declared on all 43 operations. These only add keys to each operation's responses map. No success shape, parameter, or security declaration changed.
  • Comment example ids are now post_… (doc-only).

Nothing else removed. Every pre-existing schema other than FeedSpaceRefOutput is byte-identical apart from description prose.

Version

Minor per the repo rule: additive type surface, pre-1.0. Tag v0.13.0 to release after merge.

Checks

pnpm typecheck, pnpm test, pnpm build green locally; pnpm generate leaves a clean diff. pnpm lint is clean on tracked files (its only local warning is the gitignored .claude/settings.local.json).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rpq64ASTsKJ3xc2DVoQMjh
https://claude.ai/code/session_01RZp1dfTwdX8x3dVE4236Rk

bvalosek and others added 3 commits September 9, 2026 09:23
…se v0.13.0

Re-sync from metalabel-dfos dd3f3f7 (#3286). Adds the media namespace
(POST /spaces/{space}/media, GET /spaces/{space}/media/{mediaId}),
attachments on createPost/editPost/createComment/editComment inputs,
attachments on PublicCommentOutput, and makes comment body optional.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rpq64ASTsKJ3xc2DVoQMjh
…/403/413/415/500 rows

Re-sync from metalabel-dfos cc34e1e (#3289) on top of dd3f3f7. FeedSpaceRefOutput.id
is now the space entity id with a new did field (wire-level change, same TS type).
Every proof-bearing read declares 401/403/413, every validating read declares 400,
415 on every credential-gated path, 500 InternalError on all 43 operations.
PublicMediaUploadOutput.media is now a $ref.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rpq64ASTsKJ3xc2DVoQMjh
…ription follows #3295

Regenerated from the platform checkout at f91497523 (main). The only
compiled-document change since cc34e1e is the FeedSpaceRefOutput.id
description: a private space now resolves on the credential-aware routes
(posts, comments, media) for a live member with a covering credential or
identity proof; the anonymous routes still need a public profile. No shape
change. Platform #3291, #3294, #3296, #3297 moved nothing in the document.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZp1dfTwdX8x3dVE4236Rk
@bvalosek
bvalosek merged commit 179a834 into main Sep 9, 2026
1 check passed
@bvalosek
bvalosek deleted the spec/media-upload-attachments branch September 9, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant