|
|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
English | [中文](telemetry.zh.md)
|
|
|
|
|
|
-Outbound session reporting is one [capability seam](../capability-seams.md): its Service Definition ([dsh-session-telemetry](../../packages/session/session-telemetry), `ctx.telemetry`) declares the minimal backend contract, and its capture coordinator owns the capture points, fixed chunk projection, `telemetry/record` redaction waterfall, and handoff cursor; the Service provider a deployment loads ([dsh-session-telemetry-otel](../../packages/session/session-telemetry-otel)) uses the OpenTelemetry JS SDK's log pipeline with its configuration unchanged. This optional capability is not part of the agent loop, and nothing here reaches a model request. The harness stops after it calls `emit()`; the reporting SDK owns batching, retry, queueing, and loss policy. The [revival Agent Note](../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md) records that rule and the rejected alternatives. The [Service Definition README](../../packages/session/session-telemetry/README.md) defines the capture-point, cursor, and projection contracts.
|
|
|
+Outbound session reporting is split as a [capability seam](../capability-seams.md): the Service Definition and capture coordinator ([dsh-session-telemetry](../../packages/session/session-telemetry), `ctx.telemetry`) own the capture points, fixed chunk projection, `telemetry/record` redaction waterfall, handoff cursor, and minimal backend contract; the Service provider a deployment loads ([dsh-session-telemetry-otel](../../packages/session/session-telemetry-otel)) is the OpenTelemetry JS SDK's log pipeline configured verbatim. It is one optional capability, not part of the agent-loop spine, and nothing here reaches a model request. The boundary axiom — the harness's aspect ends at `emit()`; batching, retry, queueing, and loss policy belong to the reporting SDK — and the rejected alternatives are pinned in the [revival Agent Note](../../.agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md); the capture points, cursor, and projection contracts live in the [Service Definition README](../../packages/session/session-telemetry/README.md).
|
|
|
|
|
|
Source: [`packages/session/session-telemetry/src/index.ts`](../../packages/session/session-telemetry/src/index.ts)
|
|
|
|
|
|
@@ -56,12 +56,28 @@ interface TelemetryRecord {
|
|
|
|
|
|
Only the first `assistant/chunk` of each `(turn, step)` ships — the stream-started signal; the rest drop at capture, so `seq` gaps are routine on the wire and never a loss signal. Every other [session event](session.md) type, including plugin-merged ones the seam never heard of, passes through whole. Delivery is best-effort: the cursor marks handed-off, not delivered, records can be lost (crash, reload window) and duplicated (cursor-less re-adoption, SDK retries), so receivers dedupe ledger records on `(session.id, event.seq)`; ops records deliberately omit that identity — they are signals to alert on, not entries to sum, and tolerate duplicates instead.
|
|
|
|
|
|
+## The sharing disclosure
|
|
|
+
|
|
|
+The seam's acknowledgement contract (owned by the [Service Definition README's sharing-disclosure section](../../packages/session/session-telemetry/README.md#the-sharing-disclosure)): every backend discloses its deployment-selected sharing policy through the required abstract `sharing` member on `ctx.telemetry`, and consumers render "not configured" only when no telemetry service is mounted. The disclosure states the current policy, never delivery or retention — handoff is the non-blocking enqueue, and batching, retry, and loss policy stay the reporting SDK's.
|
|
|
+
|
|
|
+```ts type-equiv
|
|
|
+/**
|
|
|
+ * Deployment-selected session-sharing policy disclosed by a mounted
|
|
|
+ * {@link Telemetry} backend to human-facing acknowledgement surfaces (the
|
|
|
+ * `/feedback` command's confirmation text). The seam owns the vocabulary so
|
|
|
+ * any backend can disclose a policy without depending on the OTel package;
|
|
|
+ * the values mirror the OTel backend's serialized `TelemetryMode` choices.
|
|
|
+ */
|
|
|
+type TelemetrySharingStatus = 'full' | 'feedback-only' | 'disabled'
|
|
|
+```
|
|
|
+
|
|
|
## The backend contract
|
|
|
|
|
|
```ts type-equiv
|
|
|
/**
|
|
|
- * The minimum backend contract the coordinator requires. {@link Telemetry} is
|
|
|
- * its service-registered form; tests compose the coordinator with a bare
|
|
|
+ * The backend contract the coordinator hands records to — the minimum any
|
|
|
+ * reporting SDK satisfies with zero bending. {@link Telemetry} is its
|
|
|
+ * service-registered form; tests compose the coordinator with a bare
|
|
|
* implementation of this interface.
|
|
|
*/
|
|
|
interface TelemetryBackend {
|
|
|
@@ -76,8 +92,8 @@ interface TelemetryBackend {
|
|
|
*/
|
|
|
emit(record: TelemetryRecord): void
|
|
|
/**
|
|
|
- * Optional hint that a turn ended. A backend may forward it to its SDK's
|
|
|
- * flush so records are exported after each turn. Called
|
|
|
+ * Optional hint that a natural boundary (turn end) passed — a backend may
|
|
|
+ * forward it to its SDK's flush so records land at turn boundaries. Called
|
|
|
* fire-and-forget; implementations must not block and must not throw
|
|
|
* meaningfully (the coordinator contains exceptions). Most backends should
|
|
|
* leave this unimplemented and let their SDK's own batching cadence govern
|
|
|
@@ -104,7 +120,7 @@ interface TelemetryBackend {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-`Telemetry` (`ctx.telemetry`, [signatures](#ctxtelemetry--telemetry-abstract-seam)) is the loadable form of this contract: each context accepts one implementation and throws on a duplicate. A backend constructs `TelemetryCoordinator` in its constructor to install capture.
|
|
|
+`Telemetry` (`ctx.telemetry`, [signatures](#ctxtelemetry--telemetry-abstract-seam)) is the contract's loadable form — one implementation per context, duplicate load throws — and a backend composes the seam's `TelemetryCoordinator` in its constructor to install the capture side.
|
|
|
|
|
|
## The redact waterfall: `telemetry/record`
|
|
|
|
|
|
@@ -122,7 +138,7 @@ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnp
|
|
|
|
|
|
### `ctx.telemetry` — `Telemetry` (abstract seam)
|
|
|
|
|
|
-Loadable form of the backend contract: one implementation per context — the cordis `Service` registration under the `telemetry` key throws on a duplicate, cordis' standard behavior. A backend composes a TelemetryCoordinator in its constructor to install the capture side.
|
|
|
+The backend contract in its loadable form: one implementation per context — the cordis `Service` registration under the `telemetry` key throws on a duplicate, cordis' standard behavior. A backend composes a TelemetryCoordinator in its constructor to install the capture side.
|
|
|
|
|
|
```ts cordis-catalog
|
|
|
/**
|
|
|
@@ -141,7 +157,7 @@ flush?(): void
|
|
|
abstract shutdown(): Promise<void>
|
|
|
```
|
|
|
|
|
|
-Source: [`packages/session/session-telemetry/src/index.ts:139`](../../packages/session/session-telemetry/src/index.ts)
|
|
|
+Source: [`packages/session/session-telemetry/src/index.ts:149`](../../packages/session/session-telemetry/src/index.ts)
|
|
|
|
|
|
<a id="telemetry-events"></a>
|
|
|
|