Skip to content

Support for stream forking (Stream-Forked-From / Stream-Fork-Offset) per the Durable Streams protocol #16

Description

@dkachur1

The base Durable Streams protocol defines stream forking via PUT with Stream-Forked-From and Stream-Fork-Offset headers (copy-on-write, refcounted soft-delete on the source when forks are still active). This server doesn't implement it, and it isn't listed as a known gap anywhere I could find � not in FEATURES.md, and the vendored docs/durable-streams-spec.md doesn't include the fork section at all (its own §4.2 is "List streams").

Use case: we run per-conversation durable streams for a chat agent (StreamDB/state-protocol on top of prisma/streams). When a user edits an earlier message or regenerates a reply, the natural model is a branch: fork the conversation stream at the edited turn's offset, keep the original branch addressable, and let the new branch diverge. Without server-side fork support, we're limited to destructive supersede (delete-and-rewrite rows in place), which loses the ability to keep multiple branches alive or let a user switch back to an earlier one.

Proposed behavior (matching the protocol spec):

  • PUT /v1/stream/{name} with Stream-Forked-From: and Stream-Fork-Offset: creates a new stream that inherits all data from the source up to that offset.
  • Source and fork may implement inheritance via copy-on-write or pointer-stitching â�� implementation detail, not prescribed by the protocol.
  • Deleting a stream with active forks soft-deletes it (410 Gone to direct access) while forks can still read the inherited range; GC once the last referencing fork is deleted.

Alternatives considered: row-level supersede (what we do today) � works, but is destructive and can't represent multiple live branches of the same conversation, which is the actual UX we're after.

Happy to help test against a real implementation, or contribute if there's appetite for a PR � wanted to check whether this is a deliberate scope exclusion before writing one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions