Task: Give every frame an identity, so a client can resume

Table of Contents

This page documents a task in the Stream the changes as they happen story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

(Describe what user-visible-or-internal change this task produces.)

2. Status

Field Value
State DONE
Parent story Stream the changes as they happen
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-11-01

3. Acceptance

4. Plan

  • The hub stamps the id, not the pump: it is the only place that sees every frame in one order, and the only place that can remember what it published.
  • The hub keeps the last 64 frames it published with their tenant attached, so a replay cannot cross tenants. A reconnecting client inside that window is given the frames it missed, in order, before it hears anything live.
  • Outside the window, or naming an id this process never issued, the client is sent one event: resync frame. Core NATS has no replay, so a silent gap would be indistinguishable from a quiet market, and the client would keep a stale screen forever.
  • The route reads Last-Event-ID, and a value that is not a number is logged and treated as a fresh stream rather than refused: a corrupt header must not cost the caller its stream.
  • The subscribe call takes the resume point under the hub's lock, so no frame is published between replay and live delivery and the client cannot miss one at the seam.

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
       

6. Notes

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

8. PRs

PR Title
#4460 [http] Complete the change stream: identity, party, conflation

9. Review

Comment summary File Decision Notes
       

10. Measurements

What Value Command Commit
Core suite cases 52 ores.http.core.tests this branch
Core suite assertions 206 ores.http.core.tests this branch
IAM suite assertions 290 ores.http.iam.tests this branch

11. Result

A frame now carries id: <n>, numbered by the hub, so a client can say which frame it last saw. The hub keeps the last 64 frames with their tenant, and a reconnecting client that names an id inside that window is given the frames it missed, in order and filtered by tenancy, before it hears anything live. A client whose id is outside the window, or names one this process never issued, is sent one event: resync frame: core NATS has no replay, and a silent gap would look exactly like a quiet market.

The route honours Last-Event-ID, and a header that is not a number is logged and treated as a fresh stream rather than refused.

Four cases prove it: ids ascend, a resuming client gets what it missed, a replay cannot cross tenants, and an unknown id is answered with a resync. The two cases that asserted raw frame text now assert the stamped form.

Emacs 29.3 (Org mode 9.6.15)