3636```
3737
3838Tags on spans pass through a hard allowlist (` provider_id ` , ` model_id ` ,
39- ` transport ` , token/byte/count numbers, short opaque ids). Everything else is
40- stripped at write time — see ` src/perf/sanitize.ts ` .
39+ ` transport ` , ` decision ` allow/deny, token/byte/count numbers, short opaque ids).
40+ Everything else is stripped at write time — see ` src/perf/sanitize.ts ` .
41+
42+ ## Limits and concurrency
43+
44+ | Limit | Value | Behavior |
45+ | ---| ---| ---|
46+ | Completed ring | ` RING_CAPACITY ` (4096) | Oldest completed span dropped |
47+ | Open spans | ` OPEN_SPAN_CAPACITY ` (1024) | Oldest ** open** span dropped so a leaked ` start() ` cannot grow without bound |
48+ | Snapshot | — | Shallow copies of spans/tags; consumers cannot poison the ring |
49+
50+ ** Single-primary turn nesting:** ` permission.wait ` and ` subagent ` nest under the
51+ process-wide active turn id (` src/perf/active-turn.ts ` ). One run-sink reactor
52+ observer owns that slot. Concurrent multi-observer setups are unsupported —
53+ later observers overwrite the nesting parent. ` clear() ` , observer ` reset() ` , and
54+ turn close null the slot.
4155
4256## API surface
4357
@@ -53,7 +67,8 @@ import { dumpSpans } from "../src/perf/dump.js";
5367- ` dumpSpans(spans, { dir, sessionId }) ` — write a privacy-strict JSON file
5468
5569The ring holds ` RING_CAPACITY ` (4096) completed spans. Older entries are
56- evicted; open spans are not stored in the ring until they end.
70+ evicted; open spans live in a separate map capped at ` OPEN_SPAN_CAPACITY ` (1024)
71+ until they end (or are dropped if over cap).
5772
5873## Reading a dump after a slow run
5974
0 commit comments