AppSurface Search
API Reference

Intelligence

Type

AppSurfaceProductEventContract

Source

Describes a registered AppSurface product-event contract.

Property

Name

string Name { get; } Source

Gets the stable event name.

Property

Lifecycle

AppSurfaceProductEventLifecycle Lifecycle { get; } Source

Gets the current lifecycle state.

Property

Purpose

string Purpose { get; } Source

Gets the decision the event is meant to support.

Property

Owner

string Owner { get; } Source

Gets the owning AppSurface component or package.

Property

RetentionExpectation

string RetentionExpectation { get; } Source

Gets the expected retention class for downstream sinks.

Property

Properties

IReadOnlyList<AppSurfaceProductEventPropertyContract> Properties { get; } Source

Gets the allowed property schema.

Property

ForbiddenExamples

IReadOnlyList<string> ForbiddenExamples { get; } Source

Gets examples of values or property shapes that must not be captured.

Type

AppSurfaceProductEventMetadata

Source

Normalizes and sanitizes product-event metadata before registry validation or sink emission.

Remarks

This internal helper separates constructor-time normalization, which trims and rejects empty required values, from emission-time sanitization, which may return null for unsafe optional envelope values. Methods that validate required input throw for empty or duplicate values; methods named Sanitize* return null when values are too long, contain unsafe characters, or look like tokens, cookies, secrets, connection strings, bearer headers, stack traces, full URLs, query strings, or fragments.

Method

RequireIdentifier

string RequireIdentifier(string value, string parameterName) Source

Trims and requires a non-empty identifier-like value.

Remarks

This method is for event and property names. It does not apply the stricter route or envelope sanitizers. Callers receive an ArgumentException for null, empty, or whitespace-only input.

Method

RequireText

string RequireText(string value, string parameterName) Source

Trims and requires non-empty text.

Remarks

Use this for registry descriptions, owners, examples, and allowed values. It throws for null, empty, or whitespace-only values, and otherwise returns the trimmed text unchanged.

Method

NormalizeOptionalText

string? NormalizeOptionalText(string? value) Source

Trims optional text and normalizes null, empty, or whitespace-only values to null.

Method

NormalizeProperties

IReadOnlyDictionary<string, string> NormalizeProperties(IReadOnlyDictionary<string, string>? properties, string parameterName) Source

Copies property keys and values into an ordinal, read-only dictionary.

Remarks

Property names are required and trimmed through RequireIdentifier. Property values are trimmed, with null or whitespace-only values normalized to an empty string so optional string properties can still be represented. Later duplicate keys replace earlier values according to dictionary assignment semantics.

Method

NormalizeContracts

IReadOnlyList<AppSurfaceProductEventPropertyContract> NormalizeContracts(IEnumerable<AppSurfaceProductEventPropertyContract> contracts, string parameterName) Source

Copies and validates a required property-contract sequence.

Remarks

The returned list is a read-only wrapper over a private copy. Empty sequences and duplicate property names throw because every event contract must publish an explicit schema.

Method

NormalizeTextList

IReadOnlyList<string> NormalizeTextList(IEnumerable<string> values, string parameterName) Source

Copies and validates a required list of non-empty text values.

Remarks

Values are trimmed with RequireText and returned as a read-only wrapper over a private copy. Duplicate handling is left to callers because some lists may allow duplicates while others do not.

Method

NormalizeOptionalTextList

IReadOnlyList<string> NormalizeOptionalTextList(IEnumerable<string>? values, string parameterName) Source

Copies and validates an optional list of unique non-empty text values.

Remarks

Null input becomes an empty read-only list. Non-null input is trimmed, duplicate values throw, and the returned value should be treated as immutable by registry contracts.

Method

SanitizeEnvelopeIdentifier

string? SanitizeEnvelopeIdentifier(string? value) Source

Filters optional actor, session, or correlation identifiers for sink-safe emission.

Remarks

Safe identifiers are short ASCII tokens containing only letters, digits, -, _, ., :, or |. Values with whitespace, PII-shaped punctuation, bearer headers, tokens, cookies, secrets, connection strings, or stack-trace text are dropped by returning null.

Method

SanitizeRoute

string? SanitizeRoute(string? value) Source

Filters optional route templates or surface names for sink-safe emission.

Remarks

Routes may contain path separators and route-template braces, but full URLs, protocol-relative URLs, query strings, fragments outside route tokens, unsafe characters, high-risk value shapes, and overlong routes are dropped. Do not pass concrete route values that contain user, tenant, object, or channel identifiers.

Method

ContainsForbiddenValueShape

bool ContainsForbiddenValueShape(string value) Source

Returns whether a value looks like a secret, credential, connection string, bearer header, or stack trace.

Method

ContainsQueryOrFragment

bool ContainsQueryOrFragment(string value) Source

Returns whether a route-like value contains a query string or fragment outside a route token.

Type

AppSurfaceProductIntelligenceDispatcher

Source

Default product-intelligence dispatcher registered by AppSurface.

Method

CaptureAsync

ValueTask CaptureAsync(AppSurfaceProductEvent productEvent, CancellationToken cancellationToken = default) Source

Remarks

Invalid events are discarded silently after AppSurfaceProductEventRegistry.Validate(AppSurfaceProductEvent). Experimental contracts are also ignored unless AppSurfaceProductIntelligenceOptions.ExperimentalEventsEnabled enables the whole experimental surface or AppSurfaceProductIntelligenceOptions.IsExperimentalEventEnabled(string) enables that specific event name through the per-event allowlist. Registered sinks run sequentially, and non-cancellation sink failures are swallowed so product-intelligence capture cannot break request paths. Callers should treat this method as best-effort delivery and should not rely on it to surface sink errors or guarantee that a downstream analytics provider accepted the event.

Type

AppSurfaceProductEventPropertyContract

Source

Describes one allowed property on a registered AppSurface product event.

Property

Name

string Name { get; } Source

Gets the stable property name accepted in event payloads.

Property

Description

string Description { get; } Source

Gets the human-readable purpose and expected value shape.

Property

Sensitivity

AppSurfaceProductEventSensitivity Sensitivity { get; } Source

Gets the privacy sensitivity classification.

Property

Cardinality

AppSurfaceProductEventCardinality Cardinality { get; } Source

Gets the expected cardinality budget.

Property

Required

bool Required { get; } Source

Gets a value indicating whether capture should drop the event when the property is absent.

Property

AllowedValues

IReadOnlyList<string> AllowedValues { get; } Source

Gets the optional bounded set of allowed values for low-cardinality dimensions.

Property

MaxLength

int MaxLength { get; } Source

Gets the maximum allowed emitted value length.

Enum

AppSurfaceProductEventCardinality

Source

Describes the expected cardinality budget for a product-event property.

Remarks

The numeric values are explicit because this public enum may be serialized, persisted, or used in generated registry documentation. New values should be appended without changing the values documented here.

Type

AppSurfaceProductIntelligenceOptions

Source

Configures AppSurface product-intelligence capture.

Method

EnableExperimentalEvents

2 overloads
AppSurfaceProductIntelligenceOptions EnableExperimentalEvents() Source

Allows experimental event contracts to be emitted.

Returns

The same options instance for fluent configuration.

Remarks

This method is a one-way toggle on the same options instance: it sets ExperimentalEventsEnabled to true and does not provide a matching disable operation. Avoid sharing and mutating one options instance across unrelated components when that one-way behavior would be surprising.

AppSurfaceProductIntelligenceOptions EnableExperimentalEvents(params string[] eventNames) Source

Allows selected experimental event contracts to be emitted.

Parameters

  • eventNamesRegistered experimental event names to allow.

Returns

The same options instance for fluent configuration.

Remarks

Use this when a host or package wants a narrow product-intelligence surface without enabling every experimental AppSurface event. Blank names are rejected during configuration so typos do not silently widen or narrow capture. Registered sinks still receive only events that pass AppSurfaceProductEventRegistry.Validate(AppSurfaceProductEvent).

Method

IsExperimentalEventEnabled

bool IsExperimentalEventEnabled(string eventName) Source

Determines whether one experimental event name is allowed by this options instance.

Parameters

  • eventNameThe experimental event name to test.

Returns

true when all experimental events or the specific event name are enabled.

Property

ExperimentalEventsEnabled

bool ExperimentalEventsEnabled { get; set; } Source

Gets a value indicating whether experimental event contracts may be emitted.

Remarks

The default is false. Keep this disabled for hosts that have not yet chosen product-event sinks, retention rules, and access controls. Enable it only during explicit dogfooding or host configuration where experimental AppSurface event contracts are expected to flow.

Property

EnabledExperimentalEventNames

IReadOnlySet<string> EnabledExperimentalEventNames { get; } Source

Gets experimental event names that are enabled without enabling every experimental contract.

Remarks

This allowlist lets package integrations enable one product area, such as AppSurface Docs search-quality metrics, without turning on unrelated experimental dogfood events. Values are event names from AppSurfaceProductEventRegistry. The returned set is a copy so callers cannot mutate options state after configuration.

Type

AppSurfaceProductIntelligenceModule

Source

Registers the surface-neutral AppSurface product-intelligence composition boundary.

Remarks

The module registers a passive dispatcher and options type. It does not configure PostHog, OpenTelemetry, cookies, JavaScript autocapture, persistence, retention, access control, dashboards, or session replay.

Method

ConfigureServices

void ConfigureServices(StartupContext context, IServiceCollection services) Source

Registers product-intelligence services for the current startup graph.

Parameters

  • contextStartup context for the current AppSurface composition pass.
  • servicesService collection that receives product-intelligence services.
Method

RegisterDependentModules

void RegisterDependentModules(ModuleDependencyBuilder builder) Source

Registers dependent modules required by product intelligence.

Parameters

  • builderThe module dependency builder for the current startup graph.
Type

IAppSurfaceProductIntelligence

Source

Captures AppSurface-owned product-intelligence events.

Remarks

Implementations validate against AppSurfaceProductEventRegistry before forwarding events to any host-owned transport. The interface is intentionally vendor-neutral and must not require PostHog, OpenTelemetry, or a browser analytics SDK.

Method

CaptureAsync

ValueTask CaptureAsync(AppSurfaceProductEvent productEvent, CancellationToken cancellationToken = default) Source

Captures a product-intelligence event if the registry and options allow it.

Parameters

  • productEventProduct event to capture.
  • cancellationTokenCancellation token for the capture path.

Returns

A task that completes when registered sinks have accepted or skipped the event.

Type

IAppSurfaceProductIntelligenceSink

Source

Receives validated AppSurface product-intelligence events for host-owned transport.

Remarks

Sinks are optional. AppSurface does not configure persistence, retention, access control, dashboards, or vendor libraries. Register a sink only after deciding which host-owned analytics system should receive the sanitized event stream.

Method

CaptureAsync

ValueTask CaptureAsync(AppSurfaceProductEvent productEvent, CancellationToken cancellationToken = default) Source

Receives one sanitized product-intelligence event.

Parameters

  • productEventSanitized product event with only registry-allowed properties and safe envelope fields.
  • cancellationTokenCancellation token for the capture path.

Returns

A task that completes when the sink has accepted the event.

Type

AppSurfaceProductIntelligenceServiceCollectionExtensions

Source

Registers AppSurface product-intelligence services.

Method

AddAppSurfaceProductIntelligence

IServiceCollection AddAppSurfaceProductIntelligence(this IServiceCollection services, Action<AppSurfaceProductIntelligenceOptions>? configure = null) Source

Adds the AppSurface product-intelligence dispatcher and options.

Parameters

  • servicesService collection to configure.
  • configureOptional options callback. Call AppSurfaceProductIntelligenceOptions.EnableExperimentalEvents() to emit dogfood events.

Returns

The original service collection.

Remarks

Hosts own IAppSurfaceProductIntelligenceSink registration, transport, retention, and vendor setup. This extension registers the default dispatcher with TryAddScoped, so repeated calls do not replace an existing IAppSurfaceProductIntelligence registration. Repeated calls can still accumulate options configuration delegates, so callers should avoid duplicate configure actions. Call AppSurfaceProductIntelligenceOptions.EnableExperimentalEvents() only when experimental dogfood events should be emitted to host-owned sinks.

Enum

AppSurfaceProductEventSensitivity

Source

Classifies the privacy sensitivity of a product-event property.

Remarks

The numeric values are explicit because this public enum may be serialized, persisted, or used in generated registry documentation. New values should be appended without changing the values documented here.

Type

AppSurfaceProductEvent

Source

Describes one AppSurface product-intelligence event instance.

Remarks

AppSurface product events are semantic product signals, not logs, traces, request captures, or vendor-specific analytics payloads. Hosts own transport, retention, access control, and downstream product analytics setup.

Method

WithSanitizedEnvelope

AppSurfaceProductEvent WithSanitizedEnvelope(IReadOnlyDictionary<string, string> properties) Source

Creates a new event with sanitized envelope metadata and replacement properties.

Parameters

  • propertiesReplacement event properties that have already passed registry sanitization.

Returns

A new event with sanitized envelope metadata.

Remarks

This internal API does not mutate the current event. The supplied properties replace the original property set, while ActorId, SessionId, and CorrelationId are filtered through AppSurfaceProductEventMetadata.SanitizeEnvelopeIdentifier and Route is filtered through AppSurfaceProductEventMetadata.SanitizeRoute. Sanitization may drop optional envelope values by returning null when they are too long, contain unsafe characters, or look like secrets, PII, bearer headers, query strings, fragments, full URLs, or concrete high-cardinality route values. Callers must supply an already-sanitized property dictionary and must not assume original envelope values survive this step.

Property

Name

string Name { get; } Source

Gets the registered event name.

Property

Timestamp

DateTimeOffset Timestamp { get; } Source

Gets the timestamp supplied by the caller.

Property

Properties

IReadOnlyDictionary<string, string> Properties { get; } Source

Gets property values copied with ordinal keys.

Property

ActorId

string? ActorId { get; } Source

Gets the optional host-normalized actor identifier.

Property

SessionId

string? SessionId { get; } Source

Gets the optional host-normalized session identifier.

Property

CorrelationId

string? CorrelationId { get; } Source

Gets the optional low-cardinality correlation identifier for trace or request joins.

Property

Route

string? Route { get; } Source

Gets the optional route template or surface name.

Enum

AppSurfaceProductEventLifecycle

Source

Describes the lifecycle promise attached to an AppSurface product event contract.

Remarks

The numeric values are explicit because this public enum may be serialized, persisted, or used in generated registry documentation. New values should be appended without changing the values documented here.

Type

AppSurfaceProductEventRegistry

Source

Source-of-truth registry for AppSurface product-intelligence event contracts.

Method

Find

AppSurfaceProductEventContract? Find(string name) Source

Finds a registered contract by event name.

Parameters

  • nameEvent name to look up.

Returns

The matching contract, or null when no contract is registered.

Method

Validate

AppSurfaceProductEventValidationResult Validate(AppSurfaceProductEvent productEvent) Source

Validates and sanitizes a product event against the typed registry.

Parameters

  • productEventEvent instance to validate.

Returns

Validation result with safe diagnostics and sanitized properties.

Property

All

IReadOnlyList<AppSurfaceProductEventContract> All { get; } Source

Gets every registered AppSurface product event contract.

Property

ForbiddenProperties

IReadOnlySet<string> ForbiddenProperties { get; } Source

Gets globally forbidden property names that are always dropped from emitted payloads.

Type

AppSurfaceProductEventValidationResult

Source

Describes registry validation and sanitization for one product event.

Property

Contract

AppSurfaceProductEventContract? Contract { get; } Source

Gets the matched event contract, or null when the event is not registered.

Property

IsValid

bool IsValid { get; } Source

Gets a value indicating whether the event may be emitted after sanitization.

Property

SanitizedProperties

IReadOnlyDictionary<string, string> SanitizedProperties { get; } Source

Gets properties that may be emitted to a sink.

Property

RejectedProperties

IReadOnlyList<string> RejectedProperties { get; } Source

Gets property names rejected during validation.

Property

Diagnostics

IReadOnlyList<string> Diagnostics { get; } Source

Gets safe diagnostics that describe rejected schema decisions without echoing rejected values.