-
Notifications
You must be signed in to change notification settings - Fork 0
Observability
The primitives that make a session visible — correlation IDs, spans, audit events — and how extensions (especially Loggers) hook into them. Observability is a core surface; Loggers are the extension category that plugs sinks into it.
flowchart LR
Turn[turn starts] --> Cor[correlationId<br/>assigned]
Cor --> Span[spans opened<br/>per stage / tool / request]
Span --> Events[events published<br/>to bus]
Events --> Audit[audit records<br/>persisted]
Events --> Logger[loggers subscribe<br/>and fan out]
| Primitive | Purpose |
|---|---|
| Correlation ID | Threads one logical operation (a turn, a tool call, an approval exchange) across many events. |
| Span | Bounded interval with start / end / result used by tracers to reconstruct timing. |
| Event | Typed record published on the Event Bus. |
| Audit record | Typed record persisted durably. See Audit Trail. |
Correlation IDs and spans are core-emitted. Extensions consume them.
Every logical operation has a correlation ID. Common ancestors:
| Operation | Correlation root |
|---|---|
| Turn | One turnId per turn; every event in the turn carries it. |
| Tool call | A new correlation ID for the call; child of the turn. |
| Approval exchange | Child of the tool call. |
| Provider request | Child of the turn. |
| Reload | Session-scoped correlation ID for the reload event family. |
| Session resume | Session-scoped. |
Correlation IDs nest. A subscriber can thread a tool call and every related event (approval request, hook fires, post-tool transform, result) into one view by filtering on correlationId.
The session's Audit Trail uses the same correlation IDs. An operator who sees ToolCallApproved in audit can pull every related event from the bus (or durable audit log) by correlation.
Spans wrap bounded operations with start and end timestamps:
- Per-stage spans (
StagePreFired→StagePostFired). - Per-tool-call spans.
- Per-provider-request spans.
- Per-hook spans (observer and transform hooks).
Spans are visible via their corresponding …Started / …Completed / …Failed events on the bus. There is no separate SpanRecord shape in v1; the bus events carry the timing information needed to reconstruct spans externally.
Tracers that want OTLP / OpenTelemetry shape implement that mapping in a Logger extension. Core does not ship an OTLP exporter.
The primary observability surface is the Event Bus. Loggers, UIs, and debuggers subscribe to it. Filters let a subscriber take only what it needs:
| Subscriber intent | Filter |
|---|---|
| "Show me everything about turn X" | correlationId = turnId |
| "Warn on deprecations" | kinds = [DeprecationWarning] |
| "Alert on security events" | kinds = [ProjectTrusted, MCPServerTrusted, ToolCallDenied, ...] |
| "Measure tool durations" | kinds = [ToolInvocationStarted, ToolInvocationSucceeded, ToolInvocationFailed] |
Filters are declared in the logger's contract. See Loggers.
| Concern | Event Bus | Audit Trail |
|---|---|---|
| Reliability | Lossy (overflow drops). | Durable. |
| Shape | Broad (many event kinds). | Narrow (security / change / lifecycle). |
| Consumers | UIs, loggers, debuggers. | Operators, reviewers. |
| Retention | Session only. | Per session store policy. |
Events describe. Audit records. Many events produce an audit record; not all. See Audit Trail.
The set of things core instruments is fixed in v1. Extensions do not add new spans to the kernel; they may emit their own observational events through the Host API:
| Core-instrumented | Not extensible? |
|---|---|
| Session lifecycle | Yes — extensions cannot replace session stages. |
| Turn + stage spans | Yes — the stage set is core. |
| Tool calls | Yes — core wraps every dispatch. |
| Provider requests | Yes — core wraps every provider call. |
| Hook invocations | Yes — core fires hooks and records. |
| Interaction Protocol exchanges | Yes — core routes requests / responses. |
An extension may emit a typed observational event through the Host API:
-
ObserverEvent{kind, payload}published to the bus. - Subject to filter rules on subscribing loggers.
- Not audited by default — extensions that want durability promote via a Logger, or the core audit emitter with audit class.
Extension events must not imply control. The bus is projection only. See Event Bus.
Resolved secrets — env values, keyring values, decrypted credentials — are never carried by events or audit records. They appear only as references (envName, secretRef). This is invariant across LLM Context Isolation, Secrets Hygiene, and the Session Manifest.
Transcript content (user input, provider request and response bodies, tool args and results) is recorded verbatim by the bundled file logger because stud-cli is a local-only tool — see Audit Trail § Content vs references. Loggers with redactSecrets: true apply best-effort token-shape redaction as a second line of defense, in case an API key leaks into a model response or a tool result.
A logger that wants unredacted output (debug logger on disk, never shipped) opts in explicitly. That choice is recorded in the session manifest for the logger's origin entry.
Correlation IDs and spans are generated at emission time; they are non-deterministic (time-based / random). Workflows relying on deterministic replays should treat observability output as non-essential — the determinism tests cover behavior, not trace content.
Extensions report health via Health and Diagnostics — a concrete event shape the loader and runtime emit for startup and runtime issues. Every reload, capability mismatch, validation diagnostic, dependency resolution failure, and trust decision is observable through the bus.
- Execution Model
- Message Loop
- Concurrency and Cancellation
- Error Model
- Event and Command Ordering
- Event Bus
- Command Model
- Interaction Protocol
- Hook Taxonomy
- Host API
- Extension Lifecycle
- Env Provider
- Prompt Registry
- Resource Registry
- Session Lifecycle
- Session Manifest
- Persistence and Recovery
- Stage Executions
- Subagent Sessions
- Contract Pattern
- Versioning and Compatibility
- Deprecation Policy
- Capability Negotiation
- Dependency Resolution
- Validation Pipeline
- Cardinality and Activation
- Extension State
- Conformance and Testing
- Providers
- Provider Params
- Tools
- Hooks
- UI
- Loggers
- State Machines
- SM Stage Lifecycle
- Stage Definitions
- Commands
- Session Store
- Context Providers
- Settings Shape
- Trust Model
- Project Trust
- Extension Isolation
- Extension Integrity
- LLM Context Isolation
- Secrets Hygiene
- Security Modes
- Tool Approvals
- MCP Trust
- Sandboxing
- Configuration Scopes
- Project Root
- Extension Discovery
- Extension Installation
- Extension Reloading
- Headless and Interactor
- Determinism and Ordering
- Launch Arguments
- Network Policy
- Platform Integration
Tools
UI
Session Stores
Loggers
Providers
Hooks
Context Providers
Commands
- First Run
- Default Chat
- Tool Call Cycle
- Hook Interception
- Guard Deny Reproposal
- State Machine Workflow
- SM Stage Retry
- Hot Model Switch
- Capability Mismatch Switch
- Session Resume
- Session Resume Drift
- Approval and Auth
- Interaction Timeout
- Headless Run
- Parallel Tool Approvals
- Subagent Delegation
- Scope Layering
- Project First-Run Trust
- Reload Mid-Turn
- Compaction Warning
- MCP Remote Tool Call
- MCP Prompt Consume
- MCP Resource Bind
- MCP Reconnect