Table of Contents

Namespace Typhon.Profiler

Classes

AppendOnlyChunkSink

ICacheChunkSink implementation for live sessions: writes LZ4-compressed chunk bytes back-to-back to a caller-provided Stream (typically a temp file). No headers, no section table, no trailer — chunks only. The owning AttachSessionRuntime keeps the manifest in memory and serves chunks via offset+length lookups.

ArchetypeClusterInfoRecord

Inline cluster-layout descriptor for an archetype's SoA chunk format. Mirrors ArchetypeClusterInfo; serialised inline with each ArchetypeDefinitionRecord when the archetype is cluster-eligible.

ArchetypeDefinitionRecord

Rich archetype definition stored in the v7+ ArchetypeDefinitions table of a .typhon-trace file. Carries the parent/child graph, slot-ordered component IDs, storage-mode bitmasks, cascade-delete edges, and (when cluster-eligible) the inline cluster layout. Drives the Workbench ArchetypeBrowser and relationship view for trace sessions.

ArchetypeRecord

Describes an archetype registered with the engine's ArchetypeRegistry. Stored in a table near the start of a .typhon-trace file so the viewer can map ArchetypeId numbers in typed events (EcsSpawn, ClusterMigration, etc.) back to human-readable names without the wire format having to carry strings for every event.

CacheHeaderFlags

Flag bits for Flags. The struct is 16 bits wide; bit 0 is currently the only assigned flag.

ComponentDefinitionRecord

Rich component-type definition stored in the v7+ ComponentDefinitions table of a .typhon-trace file. Carries the full schema (fields with name + type + offset + size + index flags), storage mode, and per-component aggregates so the Workbench schema panels can render trace sessions with the same fidelity as live engine sessions.

ComponentTypeRecord

Describes a component type registered with the engine. Stored in a table near the start of a .typhon-trace file so the viewer can map ComponentTypeId numbers in typed events (e.g. TransactionCommitComponent) back to human-readable names without the wire format carrying strings per event.

DagRecord

Describes a DAG — the third level of the runtime partitioning hierarchy (Engine → Track → DAG → Phase → System) — stored in the DagsTable of a .typhon-trace file (format v11+, #354). Phases are DAG-local: each DAG carries its own ordered phase-name list. Variable-length record (name + phase-name strings are UTF-8 encoded).

EventQueueRecord

One entry in the v7+ EventQueueCatalog table — describes a single registered event queue's static schema (capacity, event-type name, display name). Augments the existing thin queue-name table with capacity / type info so the Workbench queue panel can display capacity utilisation in % terms against per-tick depth.

FieldDefinitionRecord

One field of a ComponentDefinitionRecord. Mirrors DBComponentDefinition.Field but carries only what the offline Workbench needs for schema rendering — runtime-only fields (CLR Type handles, foreign-key target types) are not serialised.

FileCacheSink

ICacheChunkSink implementation backed by a TraceFileCacheWriter. Produces a complete .typhon-trace-cache sidecar file when WriteTrailer(IReadOnlyList<TickSummary>, in GlobalMetricsFixed, IReadOnlyList<SystemAggregateDuration>, IReadOnlyList<ChunkManifestEntry>, IReadOnlyDictionary<int, string>, ReadOnlySpan<byte>, in CacheHeader, IReadOnlyList<SystemTickSummary>, IReadOnlyList<QueueTickSummary>, IReadOnlyList<PostTickSummary>, IReadOnlyDictionary<ushort, string>, IReadOnlyList<SystemArchetypeTouchSummary>) is called.

IncrementalCacheBuilder

Incremental, instance-based variant of TraceFileCacheBuilder. The replay path constructs an instance, pumps the trace file's record bytes through FeedRawRecords(ReadOnlySpan<byte>), and disposes (which writes the trailer when the sink supports it). The live path constructs an instance from the engine's Init-frame metadata, pumps each Block frame's decompressed records through FeedRawRecords(ReadOnlySpan<byte>), calls FlushCurrentChunk() on a 200 ms timer for in-flight chunk visibility, and disposes when the engine sends Shutdown.

IndexCatalogEntry

One entry in the v7+ IndexCatalog table — a flat list of every B+Tree (or spatial) index defined on the schema, keyed by (ComponentTypeId, FieldId). Redundant with the per-field HasIndex flag in Fields but flat-listed here so the Workbench SchemaIndexes panel can iterate indexes without traversing every component.

LiveStreamProtocol

Frame envelope for the Tracy-style profiler's live TCP stream. Each frame: [u8 type][u32 length][payload length bytes].

MemoryAllocSource

Interned call-site tags for MemoryAllocEvent. The u16 sourceTag field of the record identifies which logical subsystem performed the allocation so the viewer can colour-code markers and compute per-subsystem aggregates.

PageCacheBackpressureCodec

Wire codec for PageCacheBackpressure. Payload: [i32 retryCount][i32 dirtyCount][i32 epochCount].

PageCacheEventCodec

Shared wire codec for all five page-cache event kinds. Every kind writes a 4-byte "primary value" slot (FilePageIndex for most, PageCount for Flush) plus a 1-byte optMask, plus optional trailing fields keyed by the mask bits.

PerTickSnapshotEventCodec

Wire-format codec for the PerTickSnapshot record — packed bundle of gauge values emitted at tick boundary.

QueryArgsEventCodec

Wire codec for QueryArgs (kind 248) — per-execution threshold arguments emitted once per QueryPlan when the plan carries at least one evaluator.

QueryDefinitionDescribeEventCodec

Wire codec for QueryDefinitionDescribe (kind 247) — one-shot definition descriptor emitted once per ViewId/EcsQueryId per profiling session. Wire format owned here.

QueueTickEndCodec

Wire codec for QueueTickEnd (kind 244) — per-(tick, queue) rollup emitted at end-of-tick. Surfaces queue-depth telemetry (peak, end-of-tick, overflow, produced, consumed) for the Workbench Data API queue/<name> tracks (#311).

ResourceGraphNodeRecord

One node in the v7+ ResourceGraphSnapshot table — pre-order tree walk of the engine's ResourceGraph at trace start. The tree is reconstructed by readers via ParentId; the root has ParentId == -1.

RuntimeConfigRecord

Runtime configuration snapshot captured at trace start (v7+). Single record (no count prefix in the wire format) — readers consume it once and bind to the runtime-config panel.

RuntimeEventCodec

Wire codec for Runtime events (kinds 161-164).

SchedulerMetronomeEventCodec

Wire codec for Scheduler:Metronome (kind 241) and Scheduler:Overload:Detector (kind 242). Issue #289 follow-up — surfaces the previously invisible inter-tick wait + per-tick detector state so the profiler can answer "why did the engine wait for nothing".

SystemDefinitionRecord

Describes a system in the DAG, stored in the system definition table of a .typhon-trace file. Variable-length record (name is UTF-8 encoded).

ThreadInfoEventCodec

Wire codec for ThreadInfo. Layout after the 12-byte common header:

offset 12..15  i32  ManagedThreadId
offset 16..17  u16  NameByteCount
offset 18+     byte[NameByteCount] NameUtf8
offset 18+N    u8   ThreadKind

Total wire size: 12 + 4 + 2 + NameByteCount + 1 bytes.

TraceBlockEncoder

Block encoder/decoder for the .typhon-trace on-disk format and the TCP live-stream protocol. Works on variable-size record byte streams (as produced by TraceRecordRing.Drain) — the old fixed-stride TraceEvent[] path was removed in the Phase 3 rewrite.

TraceEventKindExtensions

Helpers for TraceEventKind range classification. Used by readers and the consumer drain loop to decide which header shape to parse.

TraceFileCacheBuilder

Builds a .typhon-trace-cache sidecar by scanning a source .typhon-trace file in one linear pass. Implementation has been refactored to IncrementalCacheBuilder; this type now exists as a thin façade so existing callers (workbench replay path, Typhon.Engine tests, future tooling) continue to work without changes.

TraceFileCacheBuilder.BuildResult

High-level summary of a cache-build pass. Useful for logging and telemetry.

TraceFileCacheConstants

Compile-time constants for the cache format. Kept in one place so writer, reader, builder, and tests all agree.

TraceFileCacheReader

Opens and reads a .typhon-trace-cache sidecar file. Small sections (TickIndex, TickSummaries, ChunkManifest, GlobalMetrics, SpanNames) are loaded eagerly on construction — they're capped at tens of MB even for 500K-tick traces, and the server/client need random access to them anyway. The bulk FoldedChunkData section stays on disk; callers read chunks on demand via ReadChunkRaw(in ChunkManifestEntry, Span<byte>) or DecompressChunk(in ChunkManifestEntry, Span<byte>, Span<byte>).

TraceFileCacheWriter

Writes a .typhon-trace-cache sidecar file. Owns the underlying stream; not thread-safe.

TraceFileReader

Reads a .typhon-trace binary trace file — the variable-size typed-record layout (see CurrentVersion for the current format version; MinSupportedVersion is the oldest still accepted). Provides sequential block-by-block access, yielding a raw byte span that the caller walks as a sequence of size-prefixed records.

TraceFileWriter

Writes a .typhon-trace binary trace file — the variable-size typed-record layout introduced in the Tracy-style profiler rewrite (see CurrentVersion for the current format version). Owns the underlying stream; not thread-safe — callers must serialize writes (the profiler's exporter thread is the only writer).

TraceRecordHeader

Wire-format layout constants and encode/decode helpers for the common header (12 B, present on every record) and the span header extension (25 B, present on every span record, optionally followed by a 16 B trace context).

TrackRecord

Describes a Track — the top level of the runtime partitioning hierarchy (Engine → Track → DAG → Phase → System) — stored in the TracksTable of a .typhon-trace file (format v11+, #354). Variable-length record (name + tag strings are UTF-8 encoded).

Structs

CacheHeader

Fixed 128-byte header at the start of a .typhon-trace-cache file. Contains the source-file fingerprint (for invalidation), format versioning, and a pointer to the section table.

ChunkManifestEntry

One entry in the chunk manifest. Addresses a chunk's folded byte range inside the cache file's FoldedChunkData section. A chunk covers a half-open tick range [FromTick, ToTick). Both endpoints are stored explicitly so the manifest can be consumed in any order.

ChunkWireHeader

Wire envelope shipped at the start of each HTTP chunk response (uncompressed prefix, then the LZ4 payload). Identifies the chunk for the client's cache key without requiring a LZ4 decode first.

CpuFrameSymbol

One resolved frame symbol in the trailing CpuSampleSection of a .typhon-trace file (#351). Interned stacks reference frame symbols by FrameId; a frame symbol carries the display method name and, when the frame resolved to source, a FileId / Line.

CpuSampleRecord

One CPU stack sample in the trailing CpuSampleSection of a .typhon-trace file (#351). A sample is a single statistical capture of one thread's call stack (~1 kHz); its call stack is stored once in the section's interned stack table and referenced here by StackIndex.

GaugeValue

A single packed value inside a PerTickSnapshot record. Constructed via the typed factory helpers and encoded into the snapshot payload verbatim.

GlobalMetricsFixed

Fixed-size global metrics header. Followed in-section by a variable-length tail of per-system aggregates (SystemAggregateDuration[]), with count == SystemAggregateCount.

PageCacheBackpressureEventData

Decoded form of a PageCacheBackpressure event.

PageCacheEventData

Decoded form of any page-cache span event. Covers six page-cache kinds: PageCacheFetch, PageCacheDiskRead, PageCacheDiskWrite, PageCacheAllocatePage, PageCacheFlush, and PageEvicted (zero-duration marker span). Which of FilePageIndex and PageCount are set depends on the kind.

PerTickSnapshotData

Decoded form of a PerTickSnapshot record.

PostTickSummary

Per-tick post-tick serial markers in PostTickSummaries. One row per tick, capturing the duration of each TickPhase region that runs after the system DAG completes — wraps the existing InspectorPhase blocks in TyphonRuntime.OnTickEndInternal. Zero µs means the phase ran with no measurable work (e.g. no subscriptions active for SubscriptionOutputUs).

ProfilerHeader

Minimal subset of TraceFileHeader needed by IncrementalCacheBuilder — kept abstract so the live path can construct one from the engine's Init frame without owning a full TraceFileHeader.

QueryArgsData

Decoded form of a QueryArgs record.

QueryDefinitionDescribeData

Decoded form of a QueryDefinitionDescribe record.

QueueTickEndData

Decoded form of a QueueTickEnd record.

QueueTickSummary

Per-(tick, queue) rollup row in QueueTickSummaries. One row per queue per tick. Folded from the new QueueTickEnd wire event the engine emits at end-of-tick per active event queue.

RuntimePhaseUoWCreateData

Decoded Runtime UoWCreate instant. Payload: tick i64 (8 B).

RuntimePhaseUoWFlushData

Decoded Runtime UoWFlush instant. Payload: tick i64, changeCount i32 (12 B).

RuntimeSubscriptionOutputExecuteData

Decoded Runtime Subscription Output Execute span. Payload: tick i64, level u8, clientCount u16, viewsRefreshed u16, deltasPushed u32, overflowCount u16 (17 B).

RuntimeTransactionLifecycleData

Decoded Runtime Transaction Lifecycle span. Payload: sysIdx u16, txDurUs u32, success u8 (7 B).

SchedulerMetronomeWaitData

Decoded Scheduler Metronome Wait span. Payload: scheduledTimestamp i64, multiplier u8, intentClass u8, phaseFlags u8 (11 B).

SchedulerOverloadDetectorData

Decoded Scheduler OverloadDetector instant snapshot (per-tick gauge sample). Payload: tick i64, overrunRatio f32, consecutiveOverrun u16, consecutiveUnderrun u16, consecutiveQueueGrowth u16, queueDepth i32, level u8, multiplier u8 (24 B).

SectionTableEntry

One entry in the section table. Identifies a named section by SectionId and locates it by byte offset + length within the cache file. Sections are always written contiguously in the file; the table gives random access without requiring the reader to walk section headers.

SourceLocationManifestEntry

One entry in the trailing SourceLocationManifest of a .typhon-trace file. Maps a compile-time Id (the value carried in span records when SpanFlagsHasSourceLocation is set) to a source location: the file path (via FileId indexing into the parallel FileTable), the line number, the kind of factory the call site invoked, and the containing method name for display. See claude/design/Profiler/10-profiler-source-attribution.md §4.7.2.

SystemAggregateDuration

Aggregate duration for one system across the whole trace. Written after GlobalMetricsFixed in the GlobalMetrics section. Used by the viewer to color-rank systems in the legend or to compute "which system dominates the trace" queries without loading any chunks.

SystemArchetypeTouchSummary

Per-(tick, system, archetype) entity-touch rollup row in SystemArchetypeTouches. One row per active (system, archetype) pair per tick — sparse by definition (most systems target one archetype, callbacks emit no rows). Folded from the new SchedulerSystemArchetype wire event the engine emits at parallel-query completion. Sorted by (TickNumber, SystemIndex, ArchetypeId) for binary-search range scans. Wire size 16 bytes — packs tightly so a 100k-tick / 200-system trace at one row per (system, tick) lands at ~320 MB worst case (typical: ~30-50 MB after sparsity).

SystemTickSummary

Per-(tick, system) rollup row in SystemTickSummaries. One row per system per tick — dense across systems so binary-search by tick yields a contiguous slice of all systems for that tick. Skipped systems are present with SkipReasonCode != 0; consumers filter on that.

ThreadInfoEventData

Decoded form of a ThreadInfo record — per-slot thread identity (managed thread ID + UTF-8 name + ThreadKind) emitted once when a producer thread claims its slot. Lets the viewer label lanes and group them by kind in its filter UI.

TickIndexEntry

One entry in the tick index. Locates a given tick's byte range inside the source .typhon-trace file, for fast seek-to-tick during cache rebuild or future features (scrub-to-timestamp). Separate from the ChunkManifestEntry which addresses the cache file.

TickSummary

Per-tick rollup shipped to the client as the overview feed. Small enough that all ticks for a 500K-tick trace fit in ~16 MB (40 B × 400K), so the client fetches the entire summary on open and renders the timeline from it without any chunk loads.

TraceFileCacheBuilder.BuildProgress

Single progress snapshot emitted during a cache build. Emitted at tick boundaries, throttled to at most one per ~200 ms.

TraceFileHeader

Version-stamped header at the start of a .typhon-trace file. Contains session-wide metadata that lets the viewer decode the record stream that follows. The on-disk size grows with the format version as trailer-offset fields are appended — readers parse it version-conditionally.

Interfaces

ICacheChunkSink

Abstraction over "where flushed chunks go" for IncrementalCacheBuilder. Two implementations: FileCacheSink wraps TraceFileCacheWriter and produces a complete sidecar cache file (replay path); AppendOnlyChunkSink (live path) writes only chunk bytes to a temp file and skips the trailer.

Enums

AdaptiveWaiterTransitionKind

Variant of an ConcurrencyAdaptiveWaiterYieldOrSleep event.

CacheSectionId

Identifies each section in the cache file. Values are wire-stable; never renumber or reuse a retired ID — only append.

CheckpointReason

What triggered a checkpoint cycle. Carried as the reason byte on CheckpointCycle spans.

EcsQueryScanMode

Scan strategy the ECS query engine chose for a given Execute/Count/Any call. Mirrors the old string-valued typhon.ecs.query.scan_mode tag exactly — each numeric value corresponds to one of the five scan modes the old code could attach to an Activity.

EcsViewRefreshMode

Path the view refresh took this call. Covers the three mutually-exclusive branches in EcsView.Refresh.

GaugeId

Stable wire-contract identifier for a single gauge value carried inside a PerTickSnapshot record.

GaugeValueKind

On-wire representation selector for a single gauge value inside a PerTickSnapshot payload.

GcReason

Reason the CLR triggered a garbage collection. Values match GCStart_V2.Reason from the Microsoft-Windows-DotNETRuntime EventSource — do not renumber.

GcSuspendReason

Reason the CLR suspended the execution engine. Values match GCSuspendEEBegin_V1.Reason from the Microsoft-Windows-DotNETRuntime EventSource — do not renumber.

GcType

Type classification of a garbage collection. Values match GCStart_V2.Type from the Microsoft-Windows-DotNETRuntime EventSource — do not renumber.

LiveFrameType

Frame kinds in the live TCP stream.

MemoryAllocDirection

Direction of a MemoryAllocEvent: allocation or free.

ThreadKind

Categorizes a producer thread for the viewer's filter UI. Emitted as a 1-byte field on ThreadInfo records so the viewer can split threads into Main / Workers / Other groups in its lane filter without name pattern-matching on the client side.

ThreadWaitReason

Reason a thread left the CPU at a context-switch point. Hand-rolled mirror of Windows' KWAIT_REASON kernel enum (a.k.a. KTHREAD::WaitReason), captured by the ETW scheduling pump from CSwitchTraceData.OldThreadWaitReason and carried on ThreadContextSwitch records.

TickPhase

Identifies a phase within a tick's lifecycle. Used by the scheduler to drive execution and surfaced on the wire as the u8 phase payload of PhaseStart / PhaseEnd instant records.

TraceEventKind

Discriminant for a trace record. Every record starts with a 12-byte common header whose third byte carries this value; the kind determines how the bytes after the header are interpreted (span header or minimal instant header, then per-kind typed payload).

TransactionRollbackReason

Reason a transaction was rolled back. Carried on the wire for TransactionRollback.