Help us shape the future of Go! Take the 2026 Go Developer Survey

capability

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: GPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package capability contains shared capability storage.

Index

Constants

View Source
const HeaderBatchMax = 40

HeaderBatchMax bounds work per call; it is not a storage quota or a fence against old writers. Adapters must enforce their own durable admission limits.

View Source
const HeaderShardCount int64 = 64

HeaderShardCount is the stable shard modulus used by domain adapters when coordinating admission. Changing it requires a migration and writer fence.

View Source
const RetirementOwnerClaim = "retirement-owner"

RetirementOwnerClaim reserves a header while a typed domain owner still protects an acquired resource. Domains create it atomically with header issuance and their typed owner, and remove it atomically with that owner. It must not be attached after an unprotected header becomes visible. Expiry maintenance skips it; expiry alone must never authorize retirement. Admission continues to charge the header.

Variables

View Source
var ErrInvalidHeader = errors.New("capability: invalid header or scope")

Functions

func AdmissionLockSQL

func AdmissionLockSQL(namespace, viewerSQL string) string

AdmissionLockSQL returns a PostgreSQL advisory-lock expression matching the Go admission lock. Inputs must be trusted migration constants, never request text. Keeping both forms here prevents domain triggers taking a different lock.

func AdmitHeadersInTx

func AdmitHeadersInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, headers []Header, limits Limits) error

AdmitHeadersInTx reserves bounded storage in the domain transaction. A batch has one namespace/viewer/surface, but may contain different devices. The caller authorizes and inserts its typed records in this same transaction and must roll back on any error. Existing rows (including pre-cutover headers) count toward admission. This does not fence direct SQL or old binaries.

func BindHeadersInTx

func BindHeadersInTx(ctx context.Context, tx *sql.Tx, headers []Header) error

BindHeadersInTx inserts headers on the caller's transaction. The caller owns scope authorization, per-domain quota, timestamp selection and atomic domain insertion; tx must come from the same database as the domain operation. Duplicate namespace/digest fails and must cause the caller to roll back.

func ClaimHeaderInTx

func ClaimHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, purpose string, nowMillis int64) (bool, error)

ClaimHeaderInTx atomically claims one purpose on a reusable handle. A false result is an already-claimed purpose; absent, foreign or expired handles fail closed. Typed domain authorization must be checked in this transaction.

func ConsumeHeaderInTx

func ConsumeHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, nowMillis int64) (bool, error)

ConsumeHeaderInTx removes exactly one live, scoped reservation. The domain must revalidate authorization and consume its typed payload in this same transaction. A false result never authorizes a fallback. Reusable handles should be revoked with this operation only when their domain lifetime ends.

func DropHeadersInTx

func DropHeadersInTx(ctx context.Context, tx *sql.Tx, scope HeaderScope, digests []string) error

DropHeadersInTx removes only exact scope matches. Unknown or foreign headers are left untouched. Callers must authorize their corresponding domain deletion in the same transaction and not infer authorization from this operation.

func LockHeaderScopeInTx

func LockHeaderScopeInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, scope HeaderScope) error

LockHeaderScopeInTx acquires the admission shard lock before a domain touches typed rows. Maintenance and issuance use the same header-first order.

func PruneExpired

func PruneExpired(ctx context.Context, db *sql.DB, now time.Time) (int64, error)

PruneExpired performs bounded maintenance independently of issuance. Only expired rows are deleted; the outer predicate protects concurrent renewal. Failure leaves the remaining work for the next pass.

func PruneHeadersInTx

func PruneHeadersInTx(ctx context.Context, tx *sql.Tx, namespace string, cutoffMillis int64, limit int) (int64, error)

PruneHeadersInTx deletes at most limit expired headers in one namespace. cutoffMillis must come from the same trusted clock used for domain expiry; callers must account for any authority lifetime extending beyond the header. This only removes mirror bookkeeping; domain retention and active-session retirement remain the caller's responsibility. No capability, including one considered live by its domain, may rely on this header surviving beyond the supplied cutoff. The caller commits or rolls back.

func PruneScopedHeadersInTx

func PruneScopedHeadersInTx(ctx context.Context, tx *sql.Tx, namespace string, viewerID int64, surface string, cutoffMillis int64, limit int) (int64, error)

PruneScopedHeadersInTx deletes expired headers for one viewer and surface. It takes no advisory lock; callers serialize it with their domain writers. The trusted cutoff must use the domain expiry clock. No domain rows are deleted.

func RenewHeaderInTx

func RenewHeaderInTx(ctx context.Context, db *sql.DB, tx *sql.Tx, h Header, nowMillis int64) (bool, error)

RenewHeaderInTx extends one live, exact-scoped header under the admission lock without adding a reservation. Existing active lifetimes remain renewable when migrated state is over quota; fresh admission still fails closed. The domain must authorize renewal and update its typed payload in the same tx.

Types

type CapacityError

type CapacityError struct{ Scope string }

func (*CapacityError) Error

func (e *CapacityError) Error() string
type Header struct {
	HeaderScope
	Digest        string
	ExpiresMillis int64
}

Header is non-secret bookkeeping; Digest is the domain's existing token hash. ExpiresMillis is an absolute Unix timestamp in milliseconds. Domain payloads and authorization remain in the domain's own table.

type HeaderScope

type HeaderScope struct {
	Namespace string
	ViewerID  int64
	Surface   string
	DeviceID  string
}

HeaderScope binds a header to its owning domain and authenticated subject. The calling adapter must authorize this scope against its domain authority.

type Limits

type Limits struct{ PerScope, PerShard int }

Limits are fixed by the issuing domain, never by a request. All writers for a namespace must use the same limits. Expired rows remain charged until the domain safely retires them; admission never evicts a live resource.

type Ticket

type Ticket struct {
	ViewerID               int64
	DeviceJSON, SourceHash string
}

type TicketEntry

type TicketEntry struct{ Digest, Purpose string }

type TicketScope

type TicketScope struct {
	ViewerID                                  int64
	Surface, DeviceID, SourceHash, DeviceJSON string
}

type Tickets

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

func NewTickets

func NewTickets(db *sql.DB) (*Tickets, error)

func NewTicketsWithClock

func NewTicketsWithClock(db *sql.DB, clock func() time.Time) (*Tickets, error)

NewTicketsWithClock preserves a service-owned trusted clock contract. The clock is injected by the host, never by a front-end request.

func (*Tickets) Consume

func (s *Tickets) Consume(ctx context.Context, surface, purpose, digest string) (Ticket, error)

Consume uses a guarded DELETE as the linearization point; selection alone never authorizes consumption.

func (*Tickets) IssueBatch

func (s *Tickets) IssueBatch(ctx context.Context, scope TicketScope, entries []TicketEntry) (int64, error)

IssueBatch authorizes and admits typed tickets atomically.

Jump to

Keyboard shortcuts

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