You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: plans/external-events.md
+7-8Lines changed: 7 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,29 +43,28 @@ Accepts a JSON `events.Event` body and publishes it into the currently active `C
43
43
44
44
**Defaults applied server-side when caller omits them:**
45
45
46
-
-`category` — derived from `type` via `cdpmonitor.CategoryFor()`. Splits `type` on the first `_` and maps the prefix to a category.
47
46
-`source.kind` — stamped to `kernel_api` when absent, so downstream consumers can distinguish external traffic from CDP traffic.
48
47
49
48
**Validation and status codes:**
50
49
51
50
-`400` on invalid JSON body.
52
51
-`400` when `type` is empty.
53
-
-`400` when `category` is present but not in the known set (`events.ValidCategory`).
52
+
-`400` when `category` is absent or not in the known set (`events.ValidCategory`). External callers always know their category; derivation is not performed.
54
53
-`404` when no capture session is active (consistent with the resource model — publish has no implicit session).
55
54
-`200` on successful publish.
56
55
57
56
The handler does not take `monitorMu` — `CaptureSession.Publish` is serialised internally and guarantees monotonic seq delivery.
**Response**`200` — pipeline stamps `seq` and `capture_session_id`, returns the full `Envelope`:
@@ -133,7 +132,7 @@ data: {envelope-json}
133
132
## 3. Key Design Decisions
134
133
135
134
1.**Shared pipeline, not a new queue.** External events flow through the same `CaptureSession` as CDP events, so `seq` is globally monotonic across all sources. Consumers never have to merge streams.
136
-
2.`**source.kind` is the fan-out key.\*\*`kernel_api` for publish, `cdp` for the monitor, `extension` / `local_process` reserved for future producers. Category is a coarse bucket derived from `type`; source is the precise provenance.
135
+
2.`**source.kind` is the fan-out key.\*\*`kernel_api` for publish, `cdp` for the monitor, `extension` / `local_process` reserved for future producers. Category is a required caller-supplied field; source is the precise provenance.
137
136
3.**Publish does not honour**`CaptureConfig.Categories`**.** The config is a filter on what the CDP monitor records — an explicit publish is a deliberate caller action and bypasses it.
138
137
4.**SSE over WebSocket.** SSE is one-way, proxy-friendly, and has built-in reconnection semantics (`Last-Event-ID`) that map cleanly to our `seq` cursor. No extra framing library.
139
138
5.**Direct writes, no goroutine.**`StreamEvents` writes straight to the `ResponseWriter` from the request goroutine. No `io.Pipe`, no background worker — correct for HTTP/1.1 SSE and simpler to reason about on disconnect.
@@ -148,7 +147,7 @@ data: {envelope-json}
148
147
### Added
149
148
150
149
-`server/cmd/api/api/events.go` — `PublishEvent`, `StreamEvents`, `writeSSEEnvelope` helper. (Re-introduced; the base branch folded the prior `events.go` handlers into `capture_session.go`.)
0 commit comments