Documentation
¶
Overview ¶
Package controlplane owns the core control-plane normalization, recording policy, query semantics, status state, validation, and runtime policy for the LLM Interactive Proxy.
Core ownership rules (enforced by architecture tests):
- This package must not import provider SDKs, concrete plugins, frontend wire packages, SQL/Bun, net/http, or internal/stdhttp.
- It depends on the stable public contract in pkg/lipsdk/controlplane and on pkg/lipsdk/scope for safe attribution.
- Storage, transport, and provider translation stay in adapters; this package defines ports consumed by those adapters.
Index ¶
- Constants
- Variables
- func Classify(err error) cp.ErrorCode
- func DualPlaneReportInputsFromMetering(ctx context.Context, q metering.Querier, query metering.Query) (cp.DualPlaneReportInputs, metering.Page, error)
- func DualPlaneReportInputsFromMeteringBounded(ctx context.Context, q metering.Querier, query metering.Query, ...) (cp.DualPlaneReportInputs, metering.Page, error)
- func ListUsageRowsFromMetering(ctx context.Context, q metering.Querier, query metering.Query) ([]cp.UsageRow, metering.Page, error)
- func ListUsageRowsFromMeteringBounded(ctx context.Context, q metering.Querier, query metering.Query, ...) ([]cp.UsageRow, metering.Page, error)
- func NewUnsupportedFilterError(fields []string) error
- func ProjectMeteringFact(f metering.Fact) cp.UsageDetail
- func ProjectObservedStreamUsage(in ObservedStreamUsageInput) cp.UsageDetail
- func ProjectUsageDetail(in UsageDetailFromEventInput) cp.UsageDetail
- func UnsupportedFilterFields(err error) []string
- func UsageRowFromEvent(ev cp.Event) cp.UsageRow
- func UsageRowFromMeteringFact(f metering.Fact) cp.UsageRow
- func UsageRowsFromMeteringFacts(facts []metering.Fact) []cp.UsageRow
- func ValidateEvent(ev cp.Event) error
- func VersionRefFromPolicy(ref economics.PolicySnapshotRef) cp.VersionRef
- func VersionRefFromRating(ref economics.RatingSnapshotRef) cp.VersionRef
- type AttemptSourceRecord
- type AuditSourceRecord
- type Clock
- type EventAppender
- type EventIDGenerator
- type MeteringDrainBound
- type MonotonicIDGenerator
- type Normalizer
- func (n *Normalizer) FromAttempt(rec AttemptSourceRecord) (cp.Event, error)
- func (n *Normalizer) FromAudit(rec AuditSourceRecord) (cp.Event, error)
- func (n *Normalizer) FromAuthDecision(ev auth.AuthDecisionEvent) (cp.Event, error)
- func (n *Normalizer) FromPolicyDecision(rec policydecision.Record) (cp.Event, error)
- func (n *Normalizer) FromSessionRecord(rec SessionSourceRecord) (cp.Event, error)
- func (n *Normalizer) FromSessionStart(ev auth.SessionStartEvent) (cp.Event, error)
- func (n *Normalizer) FromUsage(ev usage.Event) (cp.Event, error)
- func (n *Normalizer) FromUsageRecord(rec UsageSourceRecord) (cp.Event, error)
- type ObservedStreamUsageInput
- type QueryService
- func (s *QueryService) Attempts(ctx context.Context, q cp.AttemptQuery) (cp.Page[cp.AttemptRow], error)
- func (s *QueryService) Events(ctx context.Context, q cp.EventQuery) (cp.Page[cp.Event], error)
- func (s *QueryService) PolicyAudit(ctx context.Context, q cp.EvidenceQuery) (cp.Page[cp.PolicyAuditRow], error)
- func (s *QueryService) Sessions(ctx context.Context, q cp.SessionQuery) (cp.Page[cp.SessionSummary], error)
- func (s *QueryService) Status(context.Context) (cp.CapabilityStatus, error)
- func (s *QueryService) Usage(ctx context.Context, q cp.UsageQuery) (cp.Page[cp.UsageRow], error)
- func (s *QueryService) UsageAggregate(ctx context.Context, q cp.UsageAggregateQuery) (cp.Page[cp.UsageAggregate], error)
- type QueryServiceConfig
- type QuerySource
- type ReadinessProbe
- type ReadinessReportService
- type ReadinessReportSources
- type ReadinessStoreBackings
- type RecorderConfig
- type RecorderService
- type RetentionApplier
- type RetentionCommand
- type RetentionController
- type RetentionControllerConfig
- type RetentionProfile
- type RetentionResult
- type ScopeFlattener
- type SessionSourceRecord
- type Status
- type Store
- type SystemClock
- type UsageDetailFromEventInput
- type UsageSourceRecord
Constants ¶
const ( MaxSummaryBytes = 4096 MaxScopeMapEntries = 64 MaxScopeMapValue = 512 MaxSourceNameLen = 128 )
Bounded invariant constants for control-plane evidence. These keep stored summaries and scope maps bounded so a malicious or runaway source cannot inflate event records (requirement 4.7, 4.8, performance & scalability).
const DefaultMeteringDrainMaxFacts = 10_000
Variables ¶
var ( ErrDisabled = errors.New("controlplane: capability disabled") ErrDegraded = errors.New("controlplane: capability degraded") ErrInvalidQuery = errors.New("controlplane: invalid query") ErrTooBroad = errors.New("controlplane: query too broad") ErrUnsupportedFilter = errors.New("controlplane: unsupported filter") ErrUnsafeEvidence = errors.New("controlplane: unsafe evidence") )
Stable sentinel errors for the control-plane capability (requirement 7.4, 9.4). Adapters and HTTP routes map these to safe client/operator shapes without leaking raw infrastructure details.
var ( ErrMeteringCursorFault = errors.New("controlplane: metering cursor fault") ErrMeteringDrainBoundExceeded = errors.New("controlplane: metering drain bound exceeded") )
Functions ¶
func Classify ¶
Classify returns the stable ErrorCode for an error chain, or empty when the error is nil or does not match a control-plane sentinel. It is the single authoritative mapping from internal errors to the SDK error classification (requirement 7.4, 9.4).
func NewUnsupportedFilterError ¶
NewUnsupportedFilterError wraps ErrUnsupportedFilter with the named filter fields that recorded evidence cannot apply.
func ProjectMeteringFact ¶
func ProjectMeteringFact(f metering.Fact) cp.UsageDetail
ProjectMeteringFact projects a metering journal fact onto UsageDetail while preserving explicit token/cost presence (requirements 2.9, 5.5-5.7).
func ProjectObservedStreamUsage ¶
func ProjectObservedStreamUsage(in ObservedStreamUsageInput) cp.UsageDetail
ProjectObservedStreamUsage builds a UsageDetail with independent dual-plane fields while preserving legacy observed plane/availability projections.
func ProjectUsageDetail ¶
func ProjectUsageDetail(in UsageDetailFromEventInput) cp.UsageDetail
ProjectUsageDetail merges optional dual-plane overrides onto the legacy observed-stream defaults.
func UnsupportedFilterFields ¶
UnsupportedFilterFields returns the named fields carried by an unsupported filter error, or nil when the error is not an unsupported filter error.
func UsageRowFromEvent ¶
UsageRowFromEvent projects a usage query row from a normalized usage event.
func UsageRowFromMeteringFact ¶
UsageRowFromMeteringFact projects metering fact correlation and usage detail onto a query row without inventing missing identifiers.
func UsageRowsFromMeteringFacts ¶
UsageRowsFromMeteringFacts projects a fact set onto usage rows. Customer facts without frontend ingress and operator facts without backend ingress are marked EvidencePartial; quantities are not invented.
func ValidateEvent ¶
ValidateEvent performs the core-level invariant checks for an Event before it can be persisted or returned (requirement 1.7, 1.8, 3.4, 3.5, 3.6, 4.4, 4.5, 4.6, 4.7, 9.4). It delegates structural checks to the SDK Event.Validate and adds core-owned scope bounding and unsafe-content rejection.
func VersionRefFromPolicy ¶
func VersionRefFromPolicy(ref economics.PolicySnapshotRef) cp.VersionRef
VersionRefFromPolicy maps economics policy snapshot refs onto control-plane version refs.
func VersionRefFromRating ¶
func VersionRefFromRating(ref economics.RatingSnapshotRef) cp.VersionRef
VersionRefFromRating maps economics rating snapshot refs onto control-plane version refs.
Types ¶
type AttemptSourceRecord ¶
type AttemptSourceRecord struct {
SourceEventKey string
OccurredAt time.Time
TraceID string
RequestID string
SessionID string
ALegID string
BLegID string
AttemptSeq int
FrontendID string
BackendID string
Model string
RouteOutcome string
Surfaced cp.AttemptSurfaced
Outcome cp.AttemptOutcome
ErrorClass string
StartedAt time.Time
FinishedAt time.Time
Scope *scope.PrincipalScopeView
}
AttemptSourceRecord is the source DTO for backend attempt evidence projected from B2BUA continuity and secure-session attempt records (requirement 1.3, 3.2, 3.3). It carries only safe correlation, attribution, and outcome fields; raw payloads, headers, and provider wire data must never be placed here.
type AuditSourceRecord ¶
type AuditSourceRecord struct {
SourceEventKey string
OccurredAt time.Time
TraceID string
RequestID string
SessionID string
ALegID string
BLegID string
AttemptSeq int
Action string
Result string
ReasonCode string
Scope *scope.PrincipalScopeView
Visibility cp.Visibility
RedactionState cp.RedactionState
}
AuditSourceRecord is the source DTO for audit evidence projected from secure-session audit rows and operator-visible lifecycle events (requirement 1.6, 9.3). Action and Result are safe summaries; privileged audit evidence is marked via Visibility and RedactionState, not raw fields.
type Clock ¶
Clock is the consumer-owned time port so tests can drive deterministic time without real sleeps (requirement 1.7, testing steering).
type EventAppender ¶
EventAppender is the recorder-owned port for appending normalized control-plane evidence (requirement 1.7, 1.8). Append is single-event and returns the stable identity assigned by the backing store.
type EventIDGenerator ¶
EventIDGenerator produces stable opaque EventID values for a store-local sequence (requirement 1.7, 2.7). The store assigns the monotonic sequence; the generator binds it to a stable store id so consumers can page, deduplicate, and correlate deterministically.
type MeteringDrainBound ¶
type MeteringDrainBound struct {
MaxFacts int
}
type MonotonicIDGenerator ¶
type MonotonicIDGenerator struct {
StoreID string
}
MonotonicIDGenerator is a deterministic EventIDGenerator that pairs a stable store id with the store-assigned sequence. It is safe for concurrent use only when callers do not mutate StoreID after construction.
func NewMonotonicIDGenerator ¶
func NewMonotonicIDGenerator(storeID string) *MonotonicIDGenerator
NewMonotonicIDGenerator returns a MonotonicIDGenerator bound to storeID.
func (*MonotonicIDGenerator) NewEventID ¶
func (g *MonotonicIDGenerator) NewEventID(sequence int64) cp.EventID
NewEventID returns the stable EventID for the supplied store-local sequence.
type Normalizer ¶
type Normalizer struct {
// contains filtered or unexported fields
}
Normalizer converts safe auth, session, attempt, usage, policy, and audit source DTOs into one validated cp.Event shape (requirements 1.1–1.6, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 4.1, 4.4, 4.5, 4.6, 4.7, 4.8, 5.3, 9.2, 9.3, 10.5, 10.7).
The normalizer enforces:
- exactly one typed detail block per event (delegated to cp.Event.Validate);
- shared trace/request/session/A-leg/B-leg/attempt correlation without inventing identifiers that the source did not supply (requirement 3.6);
- safe scope attribution through ScopeFlattener, preserving unknown vs known-empty values (requirement 4.1, 4.2, 4.3);
- rejection of raw credentials, headers, and payload content in any free- text field carried into a normalized event (requirement 4.4, 4.5);
- privileged audit/policy evidence is marked privileged + redacted so default-visibility queries do not surface it (requirement 4.6, 9.3).
It does not change source decision outcomes (requirement 1.5, 10.7) and does not start goroutines or perform I/O.
func NewNormalizer ¶
func NewNormalizer(clock Clock, source cp.SourceRef, scopes *ScopeFlattener) *Normalizer
NewNormalizer returns a Normalizer that uses clock for RecordedAt when a source DTO does not supply its own time, source to stamp every produced event, and scopes to flatten safe attribution.
func (*Normalizer) FromAttempt ¶
func (n *Normalizer) FromAttempt(rec AttemptSourceRecord) (cp.Event, error)
FromAttempt converts a safe backend attempt record into an attempt-category control-plane event (requirement 1.3, 3.2, 3.3, 3.7, 5.3).
func (*Normalizer) FromAudit ¶
func (n *Normalizer) FromAudit(rec AuditSourceRecord) (cp.Event, error)
FromAudit converts a safe audit record into an audit-category control-plane event (requirement 1.6, 9.3). Privileged audit evidence is marked privileged + redacted so default-visibility queries return redacted evidence state rather than privileged raw content.
func (*Normalizer) FromAuthDecision ¶
func (n *Normalizer) FromAuthDecision(ev auth.AuthDecisionEvent) (cp.Event, error)
FromAuthDecision converts a safe auth decision event into an auth-category control-plane event (requirement 1.1, 3.1, 4.1).
func (*Normalizer) FromPolicyDecision ¶
func (n *Normalizer) FromPolicyDecision(rec policydecision.Record) (cp.Event, error)
FromPolicyDecision converts a safe policy decision record into a policy- category control-plane event (requirement 1.5, 3.4, 3.5, 9.3). The original decision outcome is preserved and never changed by normalization.
func (*Normalizer) FromSessionRecord ¶
func (n *Normalizer) FromSessionRecord(rec SessionSourceRecord) (cp.Event, error)
FromSessionRecord converts a safe session lifecycle record (secure-session create/touch) into a session-category control-plane event with an explicit source event key (design "Source Event Mapping"; task 4.3). It reuses the same scope flattening, unsafe-text rejection, and validation as FromSessionStart.
func (*Normalizer) FromSessionStart ¶
func (n *Normalizer) FromSessionStart(ev auth.SessionStartEvent) (cp.Event, error)
FromSessionStart converts a safe session-start event into a session-category control-plane event (requirement 1.2, 3.1).
func (*Normalizer) FromUsage ¶
FromUsage converts a safe usage observation into a usage-category control- plane event (requirement 1.4, 9.2). Raw usage JSON from upstream sources is never carried into the normalized event; only typed safe token/cost fields and explicit availability state are projected.
func (*Normalizer) FromUsageRecord ¶
func (n *Normalizer) FromUsageRecord(rec UsageSourceRecord) (cp.Event, error)
FromUsageRecord converts a safe usage record (secure-session usage delta) into a usage-category control-plane event with an explicit source event key (design "Source Event Mapping"; task 4.3). Raw usage JSON is never carried; only typed safe token/cost fields and explicit observed availability are projected.
type ObservedStreamUsageInput ¶
type ObservedStreamUsageInput struct {
InputTokens int
OutputTokens int
CacheReadTokens int
CacheWriteTokens int
ReasoningTokens int
TotalTokens int
CostNanoUnits int64
CostPresent bool
Currency string
CostSource string
}
ObservedStreamUsageInput is the safe usage observation projected from the usage observer or secure-session usage delta paths (requirements 1.4, 14.1, 14.2, 17.4).
func ObservedStreamInputFromUsageEvent ¶
func ObservedStreamInputFromUsageEvent(ev usage.Event) ObservedStreamUsageInput
ObservedStreamInputFromUsageEvent extracts token/cost fields from a usage observer event. CostPresent stays false until the observer event carries an explicit presence bit; nonzero cost alone is not treated as present.
type QueryService ¶
type QueryService struct {
// contains filtered or unexported fields
}
QueryService serves bounded cross-session read views with stable continuation and unsupported-filter reporting (requirements 2.1–2.9, 3.4, 3.5, 3.6, 6.3, 6.4, 7.1, 7.4, 9.1, 9.4, 9.5).
Bounds validation (limit, time window, cursor syntax, visibility) happens before any store access. Unsupported-filter reporting and shape-bound cursor validation are delegated to the store, which owns the cursor envelope and the recorded-evidence filter capabilities (design "Query Flow").
func NewQueryService ¶
func NewQueryService(store QuerySource, status *Status, cfg QueryServiceConfig) *QueryService
NewQueryService constructs a QueryService bound to the supplied store and status. status may be nil; in that case Status reports the configured enabled/disabled state without consulting shared status state.
func (*QueryService) Attempts ¶
func (s *QueryService) Attempts(ctx context.Context, q cp.AttemptQuery) (cp.Page[cp.AttemptRow], error)
Attempts serves bounded backend attempt rows (requirement 2.2, 3.2).
func (*QueryService) Events ¶
func (s *QueryService) Events(ctx context.Context, q cp.EventQuery) (cp.Page[cp.Event], error)
Events serves bounded raw control-plane events (requirement 9.1).
func (*QueryService) PolicyAudit ¶
func (s *QueryService) PolicyAudit(ctx context.Context, q cp.EvidenceQuery) (cp.Page[cp.PolicyAuditRow], error)
PolicyAudit serves bounded policy and audit evidence rows (requirement 2.4, 9.3).
func (*QueryService) Sessions ¶
func (s *QueryService) Sessions(ctx context.Context, q cp.SessionQuery) (cp.Page[cp.SessionSummary], error)
Sessions serves bounded session summaries (requirement 2.1).
func (*QueryService) Status ¶
func (s *QueryService) Status(context.Context) (cp.CapabilityStatus, error)
Status reports the current capability state (requirement 7.1, 2.9).
func (*QueryService) Usage ¶
func (s *QueryService) Usage(ctx context.Context, q cp.UsageQuery) (cp.Page[cp.UsageRow], error)
Usage serves bounded usage rows (requirement 2.3, 9.2).
func (*QueryService) UsageAggregate ¶
func (s *QueryService) UsageAggregate(ctx context.Context, q cp.UsageAggregateQuery) (cp.Page[cp.UsageAggregate], error)
UsageAggregate serves bounded usage aggregates (requirement 2.3, 6.4). Aggregate rows are logically distinct from detailed usage rows; the store projects them separately so aggregates are never presented as detailed raw records (requirement 6.4).
type QueryServiceConfig ¶
type QueryServiceConfig struct {
// Enabled reports whether the protected query surface is exposed. When
// false, every read view returns [ErrDisabled] and Status reports the
// capability as disabled, rather than returning a misleading empty page
// (requirement 2.9, 7.5).
Enabled bool
// DefaultPageSize is applied when a query omits Limit. Defaults to 100.
DefaultPageSize int
// MaxPageSize is the upper bound for any query page. Limits above this
// are rejected as too broad before store access (requirement 2.6, 7.4).
MaxPageSize int
// MaxTimeWindow bounds the time range of broad event queries. Zero means
// no bound. Ranges wider than this are rejected as too broad before store
// access (requirement 2.6, 7.4).
MaxTimeWindow time.Duration
}
QueryServiceConfig configures a QueryService (requirement 2.6, 7.4).
type QuerySource ¶
type QuerySource interface {
Sessions(ctx context.Context, q cp.SessionQuery) (cp.Page[cp.SessionSummary], error)
Attempts(ctx context.Context, q cp.AttemptQuery) (cp.Page[cp.AttemptRow], error)
Usage(ctx context.Context, q cp.UsageQuery) (cp.Page[cp.UsageRow], error)
UsageAggregate(ctx context.Context, q cp.UsageAggregateQuery) (cp.Page[cp.UsageAggregate], error)
PolicyAudit(ctx context.Context, q cp.EvidenceQuery) (cp.Page[cp.PolicyAuditRow], error)
Events(ctx context.Context, q cp.EventQuery) (cp.Page[cp.Event], error)
}
QuerySource is the query-service-owned port for bounded control-plane read views (requirement 2.1-2.9, 9.1, 9.5). Query methods return bounded pages and report unsupported filters explicitly.
type ReadinessProbe ¶
ReadinessProbe reports backing capability availability without leaking raw infrastructure errors (requirement 7.1, 7.3).
type ReadinessReportService ¶
type ReadinessReportService struct {
// contains filtered or unexported fields
}
ReadinessReportService aggregates independent readiness components.
func NewReadinessReportService ¶
func NewReadinessReportService(src ReadinessReportSources) *ReadinessReportService
NewReadinessReportService returns a readiness report reader.
func (*ReadinessReportService) Report ¶
func (s *ReadinessReportService) Report(ctx context.Context) (cp.ReadinessReport, error)
Report returns independent component rows and aggregate protected-traffic posture (15.7).
type ReadinessReportSources ¶
type ReadinessReportSources struct {
Now func() time.Time
ControlPlane func(context.Context) (cp.CapabilityStatus, error)
UsageAuthority func(context.Context) (cp.AccountingAuthorityStatus, error)
ConcurrencyAuthority func(context.Context) (cp.ConcurrencyAuthorityStatus, error)
MeteringJournal func(context.Context) (cp.ReadinessComponentStatus, error)
BillingSpool func(context.Context) (cp.ReadinessComponentStatus, error)
SnapshotStates func() (usage, concurrency, rating cp.CapabilityState)
ExecutableGeneration func() cp.ExecutableGenerationStatus
RequestCoordinatorEnabled bool
AttemptCoordinatorEnabled bool
RequestCoordinatorIDs []string
AttemptCoordinatorIDs []string
SecretGuardQuarantine func(context.Context) (cp.ReadinessComponentStatus, error)
TerminalRecovery func(context.Context) (cp.ReadinessComponentStatus, error)
StoreBackings ReadinessStoreBackings
}
ReadinessReportSources supplies optional readiness probes for independent components (15.7). Nil callbacks mean the component is disabled.
type ReadinessStoreBackings ¶
type ReadinessStoreBackings struct {
ControlPlane string
Metering string
Usage string
Concurrency string
}
ReadinessStoreBackings names configured store backings for readiness scope classification (15.8).
type RecorderConfig ¶
type RecorderConfig struct {
// Policy is the global recording policy applied to every Record call.
Policy cp.RecordingPolicy
// Required is the set of lifecycle categories that fail closed before
// protected upstream work when Policy is required_pre_work. Categories not
// listed here remain best-effort (design "Configuration and Readiness
// Contract").
Required []cp.Category
// Clock supplies RecordedAt and last-failure timestamps. Defaults to
// SystemClock when nil.
Clock Clock
}
RecorderConfig configures a RecorderService (requirement 5.4, 5.5, 7.6).
type RecorderService ¶
type RecorderService struct {
// contains filtered or unexported fields
}
RecorderService applies recording policy, appends validated events to the store, and maintains capability status without altering normal runtime outcomes (requirements 1.7, 1.8, 5.1–5.7, 7.1, 7.2, 7.3, 7.5, 7.6, 10.7).
Behavior:
- When Policy is disabled, Record returns ErrDisabled and does not touch the store or status (design: disabled capability preserves current runtime behavior).
- When a category is in Required and Policy is required_pre_work, a store append failure fails closed: the error is returned to the caller so protected upstream work does not begin, and status is degraded.
- Otherwise (best-effort, or non-required categories), a store append failure degrades status with cp.ReasonRecordingFailure and returns nil to the caller so the request outcome is preserved (requirement 5.2, 5.3).
- RecorderService.RecordBestEffort always treats the call as best-effort regardless of category or policy. Source adapters use it for post-output and non-protected paths so post-output recording failures never trigger retry, failover, or replacement (requirement 5.3, 10.7).
- Unsafe evidence (ErrUnsafeEvidence) is always returned to the caller regardless of policy: it is a programmer error, not a transient store failure.
func NewRecorderService ¶
func NewRecorderService(store EventAppender, status *Status, cfg RecorderConfig) *RecorderService
NewRecorderService constructs a RecorderService. status must be non-nil; the service updates it on best-effort and required-pre-work failures.
func (*RecorderService) Record ¶
func (s *RecorderService) Record(ctx context.Context, ev cp.Event) (cp.RecordResult, error)
Record appends one event through the configured store, applying per-category recording policy (requirement 5.4, 5.5). It implements cp.Recorder.
func (*RecorderService) RecordBestEffort ¶
func (s *RecorderService) RecordBestEffort(ctx context.Context, ev cp.Event) (cp.RecordResult, error)
RecordBestEffort appends one event without fail-closed semantics, regardless of category or policy. Source adapters use it for post-output and non-protected paths so post-output recording failures never trigger retry, failover, or replacement (requirement 5.3, 10.7). It still rejects unsafe evidence and disabled policy.
func (*RecorderService) Status ¶
func (s *RecorderService) Status(context.Context) (cp.CapabilityStatus, error)
Status returns the current capability status snapshot (requirement 7.1).
type RetentionApplier ¶
type RetentionApplier interface {
ApplyRetention(ctx context.Context, cmd RetentionCommand) (RetentionResult, error)
}
RetentionApplier is the retention-controller-owned port for mutating only control-plane evidence outside the retention window (requirement 6.1, 6.2, 6.6). It never mutates in-flight runtime stores.
type RetentionCommand ¶
type RetentionCommand struct {
Cutoff time.Time
Profile RetentionProfile
Visibility cp.Visibility
}
RetentionCommand is the batch input for retention/redaction processing (requirement 6.1, 6.2, 6.6). It mutates only control-plane evidence and never routing, policy, usage, or session outcomes for active requests.
type RetentionController ¶
type RetentionController struct {
// contains filtered or unexported fields
}
RetentionController applies configured retention and redaction commands through the store with safe status updates, without mutating routing, policy, usage, or session outcomes for active requests (requirements 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 7.2, 10.7).
It runs only from runtime-owned lifecycle paths, startup maintenance, or explicit operator action. It does not start hidden goroutines. Detailed records, summaries, privileged evidence, and aggregate usage views remain distinct after retention or redaction changes visibility: the controller delegates all data-layer mutation to the store, which preserves allowed safe correlation metadata while withholding redacted fields (requirement 6.2, 6.4).
func NewRetentionController ¶
func NewRetentionController(store RetentionApplier, status *Status, cfg RetentionControllerConfig) *RetentionController
NewRetentionController constructs a RetentionController bound to the supplied store and status. status may be nil.
func (*RetentionController) Apply ¶
func (c *RetentionController) Apply(ctx context.Context, cutoff time.Time, visibility cp.Visibility) (RetentionResult, error)
Apply runs one retention/redaction pass against the store. If cutoff is zero, the controller derives it from Clock.Now() - Window (requirement 6.1). visibility selects the query visibility profile applied to redacted rows. On store failure the controller degrades status with a bounded cp.ReasonRetentionFailure reason and returns a wrapped ErrDegraded error without leaking raw infrastructure details (requirement 7.2, 7.3).
type RetentionControllerConfig ¶
type RetentionControllerConfig struct {
// Profile is the retention/redaction profile applied to evidence outside
// the retained window.
Profile RetentionProfile
// Window is the retention duration. The controller derives the cutoff
// from Clock.Now() - Window when the caller does not supply an explicit
// cutoff.
Window time.Duration
// Clock supplies the current time for cutoff derivation and last-failure
// timestamps. Defaults to SystemClock when nil.
Clock Clock
}
RetentionControllerConfig configures a RetentionController (requirement 6.1, 6.2, 6.6).
type RetentionProfile ¶
type RetentionProfile string
RetentionProfile names a retention/redaction profile applied to control-plane evidence (requirement 6.1, 6.2).
const ( RetentionProfileStandard RetentionProfile = "standard" RetentionProfileStrict RetentionProfile = "strict" )
func (RetentionProfile) IsKnown ¶
func (p RetentionProfile) IsKnown() bool
IsKnown reports whether p is one of the documented retention profiles.
type RetentionResult ¶
type RetentionResult struct {
Marked int
Pruned int
Status cp.CapabilityStatus
}
RetentionResult is the batch output of a retention/redaction run. Aggregate counts are bounded safe integers; status carries any degradation reason.
type ScopeFlattener ¶
type ScopeFlattener struct{}
ScopeFlattener converts a safe scope.PrincipalScopeView into a presence-aware cp.ScopeSnapshot for storage and query filtering, and reconstructs a safe view from a stored snapshot (requirement 4.1, 4.2, 4.3, 4.7, 4.8, 9.1).
It preserves unknown vs known-empty values for every filterable dimension, deep-clones roles, safe claims, and policy labels at the boundary so query results cannot expose unsafe or mutable caller-owned data, and enforces bounded map/slice sizes before persistence (requirement 4.8, performance & scalability).
func NewScopeFlattener ¶
func NewScopeFlattener() *ScopeFlattener
NewScopeFlattener returns a stateless ScopeFlattener safe for concurrent use.
func (*ScopeFlattener) FlattenE ¶
func (f *ScopeFlattener) FlattenE(view scope.PrincipalScopeView) (cp.ScopeSnapshot, error)
FlattenE converts a safe view into a presence-aware snapshot and returns an error when the view carries oversized roles, safe claims, or policy labels (requirement 4.7, 4.8). The returned snapshot always carries deep-cloned slices and maps so the caller cannot mutate the source view through the snapshot or vice versa.
func (*ScopeFlattener) MustFlatten ¶
func (f *ScopeFlattener) MustFlatten(view scope.PrincipalScopeView) cp.ScopeSnapshot
MustFlatten converts a safe view into a presence-aware snapshot. It panics only if the view carries oversized roles/claims/labels maps; callers that handle untrusted input should use ScopeFlattener.FlattenE instead.
func (*ScopeFlattener) Reconstruct ¶
func (f *ScopeFlattener) Reconstruct(snap cp.ScopeSnapshot) scope.PrincipalScopeView
Reconstruct rebuilds a safe scope.PrincipalScopeView from a stored snapshot, deep-cloning roles, safe claims, and policy labels so callers cannot mutate the stored snapshot through the returned view (requirement 4.2, 4.7, 9.1).
type SessionSourceRecord ¶
type SessionSourceRecord struct {
SourceEventKey string
OccurredAt time.Time
TraceID string
SessionID string
ClientSessionRef string
ALegID string
Action cp.SessionAction
Certainty string
Scope *scope.PrincipalScopeView
}
SessionSourceRecord is the source DTO for session lifecycle evidence projected from secure-session store events (design "Source Event Mapping"; task 4.3). It carries an explicit SourceEventKey so secure-session decorators can deduplicate repeated projections independently of the auth session-start path. Raw credentials, headers, and payloads must never be placed here.
type Status ¶
type Status struct {
// contains filtered or unexported fields
}
Status tracks the operator-visible capability state for the control-plane capability (requirement 7.1, 7.2, 7.3). It stores only bounded safe reason codes and timestamps, never raw infrastructure errors.
State transition rules enforced here:
- Disabled always wins: once disabled, failure reports do not revive or degrade the capability until SetReady/SetUnavailable is called.
- RecordFailure on a ready capability transitions to degraded with the supplied bounded reason code and last failure time.
- SetUnavailable transitions to unavailable regardless of prior degraded state, because a missing backing capability is more severe than a partial failure.
func NewStatus ¶
func NewStatus(initial cp.CapabilityStatus) *Status
NewStatus returns a Status seeded with the supplied initial snapshot.
func (*Status) Disable ¶
Disable transitions the capability to disabled and clears prior failure reason. Disabled is terminal until an explicit SetReady/SetUnavailable call.
func (*Status) RecordFailure ¶
func (s *Status) RecordFailure(reason cp.ReasonCode, at time.Time)
RecordFailure transitions a ready capability to degraded with the supplied bounded reason code and last failure time. It does not override disabled or unavailable states (requirement 7.5).
func (*Status) SetReady ¶
func (s *Status) SetReady(policy cp.RecordingPolicy, at time.Time)
SetReady transitions the capability to ready with the supplied recording policy and clears any prior failure reason.
func (*Status) SetUnavailable ¶
func (s *Status) SetUnavailable(reason cp.ReasonCode, at time.Time)
SetUnavailable transitions the capability to unavailable with the supplied bounded reason code and last failure time.
func (*Status) Snapshot ¶
func (s *Status) Snapshot() cp.CapabilityStatus
Snapshot returns a defensive copy of the current capability status.
type Store ¶
type Store interface {
EventAppender
QuerySource
RetentionApplier
ReadinessProbe
}
Store is the composed adapter contract for persistence implementations that provide append, query, retention, and readiness capabilities. Core services consume the narrower interfaces above; runtime wiring and store contract tests use Store when they need the complete backing capability. SQL, Bun, HTTP, transport, and provider SDK types never cross this boundary.
type SystemClock ¶
type SystemClock struct{}
SystemClock is the production Clock backed by time.Now.
type UsageDetailFromEventInput ¶
type UsageDetailFromEventInput struct {
ObservedStreamUsageInput
Perspective cp.UsagePerspective
Boundary cp.UsageBoundary
LifecycleScope cp.UsageLifecycleScope
Provenance cp.UsageProvenance
FactKind cp.UsageFactKind
Surfaced cp.UsageSurfaced
Plane cp.UsagePlane
Availability cp.UsageAvailability
PolicyVersion cp.VersionRef
RatingVersion cp.VersionRef
}
UsageDetailFromEventInput carries optional dual-plane overrides for usage evidence projected from metering facts or other rich sources.
type UsageSourceRecord ¶
type UsageSourceRecord struct {
SourceEventKey string
OccurredAt time.Time
TraceID string
SessionID string
ALegID string
BLegID string
AttemptSeq int
FrontendID string
BackendID string
Model string
InputTokens int
OutputTokens int
CacheReadTokens int
CacheWriteTokens int
ReasoningTokens int
TotalTokens int
CostNanoUnits int64
Currency string
CostSource string
Scope *scope.PrincipalScopeView
}
UsageSourceRecord is the source DTO for usage evidence projected from secure-session usage deltas (design "Source Event Mapping"; task 4.3). It carries an explicit SourceEventKey so the secure-session decorator can deduplicate repeated projections independently of the usage observer path. Raw usage JSON, raw payloads, headers, and tokens must never be placed here.