b2bua

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package b2bua holds core-owned B2BUA session store contracts: A-leg resolution, B-leg allocation, attempt lineage rows, and in-memory TTL semantics.

The exported Store shape and ALegRecord/BLegRecord rows are mirrored in `pkg/lipsdk/continuity` for external documentation and tooling. Parity is enforced by store_contract_test.go in this package (run with `internal/core/b2bua` tests).

Index

Constants

View Source
const DefaultMemoryStoreMaxLegsWithoutTTL = 100_000

DefaultMemoryStoreMaxLegsWithoutTTL is applied when TTL is disabled and MaxLegs is zero, preventing unbounded growth of anonymous sessions in long-lived processes.

Variables

View Source
var (
	ErrALegNotFound         = errors.New("b2bua: a-leg not found")
	ErrInvalidContinuityKey = errors.New("b2bua: continuity key required for resolve")
	ErrInvalidAttempt       = errors.New("b2bua: invalid attempt record")
	ErrInvalidMaxLegs       = errors.New("b2bua: max_legs must be non-negative")
	// ErrInterleavedStateUnsupported is returned when an operation targets a
	// store that does not implement InterleavedStateStore and the requested
	// state is non-empty. Empty state remains a no-op so callers can treat
	// unsupported lineage as a new-session equivalent.
	ErrInterleavedStateUnsupported = errors.New("b2bua: interleaved state not supported by store")
)

Sentinel errors for A-leg continuity and validation.

Functions

func RandomALegID

func RandomALegID() (string, error)

RandomALegID returns an opaque A-leg identifier (prefix "a_" + 32 hex chars).

func RandomBLegID

func RandomBLegID() (string, error)

RandomBLegID returns an opaque B-leg identifier (prefix "b_" + 32 hex chars).

Types

type ALegRecord

type ALegRecord struct {
	ALegID                string
	ContinuityKey         string
	CreatedAt             time.Time
	LastSeenAt            time.Time
	WeightedFirstConsumed bool
}

ALegRecord is the core-owned logical session row for routing and lineage.

type ALegRetirementObserver

type ALegRetirementObserver interface {
	SetALegRetirementObserver(func(string))
}

InterleavedStateStore is the narrow optional contract for persisting thinker cycle state and memo references under A-leg continuity authority.

It is intentionally separate from Store so pkg/lipsdk/continuity can mirror only the base continuity contract without importing internal/core/interleavedstate (archtests forbid pkg/lipsdk from depending on internal/). Durable and in-memory stores implement this in addition to Store; callers type-assert or accept this interface explicitly. A zero-value state is valid and means "no thinker state", which is backward-compatible with A-legs created before interleaved thinking. ALegRetirementObserver is an optional lifecycle seam. Stores call the observer only after completing the eviction mutation and releasing their own locks.

type BLegRecord

type BLegRecord struct {
	BLegID string
	ALegID string
	Seq    int
}

BLegRecord identifies one backend attempt slot within an A-leg.

type ContinuityScenarioSpec

type ContinuityScenarioSpec struct {
	ID               string
	InvariantSummary string
	TestName         string // exists in internal/core/b2bua/*_test.go
}

ContinuityScenarioSpec links a stable scenario identifier to continuity/B2BUA store behavior and the primary regression test that exercises it (specification bundle).

func SpecBundleContinuityScenarios

func SpecBundleContinuityScenarios() []ContinuityScenarioSpec

SpecBundleContinuityScenarios lists memory-store and continuity invariants. Keep aligned with .kiro/steering/routing-and-orchestration.md and the referenced tests.

type InterleavedStateStore

type InterleavedStateStore interface {
	SetInterleavedState(ctx context.Context, aLegID string, state interleavedstate.State) error
	FetchInterleavedState(ctx context.Context, aLegID string) (interleavedstate.State, error)
}

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

MemoryStore is a mutex-protected in-memory Store with lazy TTL eviction.

func NewMemoryStore

func NewMemoryStore(opts MemoryStoreOptions) (*MemoryStore, error)

NewMemoryStore returns an empty store. opts may be zero-valued defaults.

func (*MemoryStore) Clear

func (s *MemoryStore) Clear(ctx context.Context, aLegID string, now time.Time) (routeoverride.State, error)

Clear deactivates the A-leg override. Already-inactive state is a no-op.

func (*MemoryStore) CreateALeg

func (s *MemoryStore) CreateALeg(ctx context.Context, continuityKey string) (ALegRecord, error)

CreateALeg allocates a new A-leg. Empty continuityKey skips key registration (always-new session).

func (*MemoryStore) FetchALeg

func (s *MemoryStore) FetchALeg(ctx context.Context, aLegID string) (ALegRecord, error)

FetchALeg loads an A-leg by id (for clients that already hold ALegID).

func (*MemoryStore) FetchInterleavedState

func (s *MemoryStore) FetchInterleavedState(ctx context.Context, aLegID string) (interleavedstate.State, error)

FetchInterleavedState returns the thinker cycle state and memo reference for an A-leg. A leg with no stored state returns the zero value, which is a harmless "new session" state for cycle purposes.

func (*MemoryStore) Get

func (s *MemoryStore) Get(ctx context.Context, aLegID string) (routeoverride.State, error)

Get uses the same read semantics as Snapshot.

func (*MemoryStore) LoadAttempts

func (s *MemoryStore) LoadAttempts(ctx context.Context, aLegID string) ([]lipapi.AttemptRecord, error)

LoadAttempts returns attempt rows for an A-leg ordered by ascending Seq.

func (*MemoryStore) NextBLeg

func (s *MemoryStore) NextBLeg(ctx context.Context, aLegID string) (BLegRecord, error)

NextBLeg allocates the next monotonic B-leg id and sequence for the A-leg.

func (*MemoryStore) RecordAttempt

func (s *MemoryStore) RecordAttempt(ctx context.Context, rec lipapi.AttemptRecord) error

RecordAttempt upserts one lineage row for (ALegID, Seq). BLegID must match the allocation from NextBLeg.

func (*MemoryStore) Replace

func (s *MemoryStore) Replace(ctx context.Context, aLegID, selector string, now time.Time) (routeoverride.State, error)

Replace activates or replaces the A-leg override selector.

func (*MemoryStore) ResolveALeg

func (s *MemoryStore) ResolveALeg(ctx context.Context, continuityKey string) (ALegRecord, error)

ResolveALeg returns the active A-leg for a non-empty continuity key, refreshing LastSeenAt.

func (*MemoryStore) SetALegRetirementObserver

func (s *MemoryStore) SetALegRetirementObserver(observer func(string))

SetALegRetirementObserver binds the process-owned session retirement callback.

func (*MemoryStore) SetInterleavedState

func (s *MemoryStore) SetInterleavedState(ctx context.Context, aLegID string, state interleavedstate.State) error

SetInterleavedState stores the thinker cycle state and memo reference for an A-leg. An empty state is permitted and clears any previously stored state. The state is validated before storage; invalid state is rejected without mutating the stored value.

func (*MemoryStore) SetWeightedFirstConsumed

func (s *MemoryStore) SetWeightedFirstConsumed(ctx context.Context, aLegID string, consumed bool) error

SetWeightedFirstConsumed updates session first-request routing state (idempotent).

func (*MemoryStore) Snapshot

func (s *MemoryStore) Snapshot(ctx context.Context, aLegID string) (routeoverride.State, error)

Snapshot returns a complete value copy of the A-leg override state.

type MemoryStoreOptions

type MemoryStoreOptions struct {
	// TTL after LastSeenAt after which an A-leg is lazily evicted. Zero disables expiry.
	// Non-zero TTL also enables a sweep on CreateALeg so idle sessions that are never
	// touched again (e.g. anonymous one-shot A-legs) are still reclaimed.
	TTL time.Duration
	// MaxLegs caps how many concurrent A-leg rows may be retained. Zero selects
	// DefaultMemoryStoreMaxLegsWithoutTTL (including when TTL-based expiry is enabled).
	// Negative values are rejected by NewMemoryStore.
	MaxLegs int
	// Now returns the current time; when nil, NewMemoryStore uses time.Now.
	Now func() time.Time
}

MemoryStoreOptions configures the in-memory implementation.

type Store

type Store interface {
	ResolveALeg(ctx context.Context, continuityKey string) (ALegRecord, error)
	CreateALeg(ctx context.Context, continuityKey string) (ALegRecord, error)
	FetchALeg(ctx context.Context, aLegID string) (ALegRecord, error)
	SetWeightedFirstConsumed(ctx context.Context, aLegID string, consumed bool) error
	NextBLeg(ctx context.Context, aLegID string) (BLegRecord, error)
	RecordAttempt(ctx context.Context, rec lipapi.AttemptRecord) error
	LoadAttempts(ctx context.Context, aLegID string) ([]lipapi.AttemptRecord, error)
}

Store persists A-leg continuity, allocates B-leg sequence numbers, and records attempt lineage.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL