b5wal

package
v1.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package b5wal contains the feature-off B5 emergency-WAL contracts and the S7b production persistence/service boundary. No MCP or HTTP entry point imports this package; the future S6 coordinator is its intended caller.

This is deliberately not the auditchain V1 canonical encoder. Callers pass already-canonical agentsql.audit.event.v4 bytes and the encoder binds those bytes, their schema identifier, and their digest into an encrypted record. The event-v4 and PostgreSQL receipt schemas are the frozen S1b definitions.

Index

Constants

View Source
const (
	RecordAlignment       = 4096
	RecordHeaderSize      = 512
	MaxCanonicalEventSize = 16 * 1024
	AEADTagSize           = 16 // stored separately from ciphertext
	RecordTrailerSize     = 32
	AccountingSize        = 512 // physically stored inside the same extent

	MaxEventSchemaIDSize = 64
	MaxKeyIDSize         = 96
	MaxHeaderExtension   = 212

	MaxPathRecordCount = 6
)
View Source
const (
	DurabilityUnspecified  = b5.DurabilityUnspecified
	DurabilityDurable      = b5.DurabilityDurable
	DurabilityAuditPending = b5.DurabilityAuditPending
	DurabilityLost         = b5.DurabilityLost
)
View Source
const (
	AppendUnknown       = b5.AppendUnknown
	AppendTimeout       = b5.AppendTimeout
	AppendLateConfirmed = b5.AppendLateConfirmed
	AppendRecovered     = b5.AppendRecovered
)
View Source
const (
	ReconciliationNone           = b5.ReconciliationNone
	ReconciliationReplayStaged   = b5.ReconciliationReplayStaged
	ReconciliationPrimaryDurable = b5.ReconciliationPrimaryDurable
)
View Source
const (
	ResponsePrepared      = b5.DeliveryPrepared
	ResponseSendStarted   = b5.DeliverySendStarted
	ResponseSendCompleted = b5.DeliverySendComplete
)
View Source
const (
	WALFormatVersion  = uint16(1)
	TrailerVersion    = uint16(1)
	AccountingVersion = uint16(1)
)
View Source
const DefaultFsyncTimeout = 250 * time.Millisecond

Variables

View Source
var (
	ErrReceiptConflict   = errors.New("b5wal: result receipt immutable conflict")
	ErrReceiptNotFound   = errors.New("b5wal: result receipt not found")
	ErrReceiptTransition = errors.New("b5wal: invalid result receipt transition")
)
View Source
var (
	ErrInvalidRecord     = errors.New("b5wal: invalid record")
	ErrAuthentication    = errors.New("b5wal: authentication failed")
	ErrEventDigest       = errors.New("b5wal: event digest mismatch")
	ErrNonCanonicalField = errors.New("b5wal: non-canonical header field")
)
View Source
var (
	ErrEventUUIDConflict = errors.New("b5wal: AUDIT_EVENT_UUID_CONFLICT")
	ErrTransactionChain  = errors.New("b5wal: transaction chain violation")
	ErrGlobalChain       = errors.New("b5wal: global chain violation")
)
View Source
var (
	ErrWriterNotOpen     = errors.New("b5wal: writer is not open")
	ErrRotationExhausted = errors.New("b5wal: reservation already used its one post-wedge rotation")
	ErrSyncTimeout       = errors.New("b5wal: fsync confirmation timed out")
)
View Source
var ErrKeyUnavailable = errors.New("b5wal: segment key unavailable")
View Source
var ErrReservationExhausted = errors.New("b5wal: reservation exhausted")

Functions

func ComputedMaxPathRecordCount

func ComputedMaxPathRecordCount() int

func EncodeRecord

func EncodeRecord(key []byte, record Record) ([]byte, error)

EncodeRecord encrypts a record with AES-256-GCM. GCM's 16-byte tag is split from the ciphertext and placed immediately after it. The complete 512-byte header is AAD. The returned slice is one full physical extent.

func EncodedRecordCharge

func EncodedRecordCharge() int

EncodedRecordCharge is the maximum and actual physical extent occupied by every encoded record. AccountingSize is not an additional allocation: the accounting block occupies the final 512 bytes of the record's aligned extent. At the maximum input size the byte account is:

512 header + 16,384 ciphertext + 16 tag + 32 trailer = 16,944 frame bytes
align_up(16,944, 4,096) = 20,480 extent bytes
the last 512 bytes are accounting metadata; 3,024 bytes remain zero padding

func PersistThenSend

func PersistThenSend(ctx context.Context, store ReceiptStore, receipt ResultReceipt, send func(ResultReceipt) error) error

PersistThenSend is the mandatory response fence. A Put or SendStarted update failure prevents send. A post-send completion-write failure is returned, but the immutable prepared result remains reproducible on retry.

func ReservationCharge

func ReservationCharge() int

ReservationCharge is the maximum physical WAL reservation for one path.

func SyncDirectory

func SyncDirectory(path string) error

SyncDirectory fsyncs a directory so that recently created, renamed or unlinked directory entries are durable.

func VerifyGlobalChain

func VerifyGlobalChain(entries []GlobalEntry) error

func WALAppendReceiptDigest

func WALAppendReceiptDigest(identity AppendIdentity) [32]byte

WALAppendReceiptDigest binds the business result receipt to the exact local append identity. It is separate from the business event digest.

Types

type AppendConfirmationState

type AppendConfirmationState = b5.AppendConfirmation

type AppendIdentity

type AppendIdentity struct {
	SegmentID     [16]byte
	RecordOrdinal uint64
	Nonce         [12]byte
	EventUUID     [16]byte
	EventDigest   [32]byte
	ExtentDigest  [32]byte
}

type AppendResult

type AppendResult struct {
	Identity AppendIdentity
	Late     <-chan error
}

AppendResult returns a buffered Late channel only on timeout. Exactly one fsync result will arrive. A late success never reopens this writer.

type ContextKeyWrapper

type ContextKeyWrapper interface {
	WrapSegmentKey(ctx context.Context, keyID string, segmentID [16]byte, segmentKey [32]byte) ([]byte, error)
}

ContextKeyWrapper is the production envelope-encryption surface. The legacy KeyWrapper method remains for isolated S7a tests; production wrappers bind ciphertext to the immutable key and segment identity as authenticated data.

type DBOutcome

type DBOutcome string
const (
	OutcomeNotCommitted DBOutcome = "NOT_COMMITTED"
	OutcomeCommitted    DBOutcome = "COMMITTED"
	OutcomeUnknown      DBOutcome = "UNKNOWN"
)

type DecodedRecord

type DecodedRecord struct {
	Record
	EventPayloadDigest [32]byte
	FrameLength        uint32
	ChargedBytes       uint32
}

DecodedRecord is returned only after length, commit marker, CRC32C, AEAD, event digest, zero padding, and accounting metadata have all verified.

func DecodeRecord

func DecodeRecord(key, extent []byte) (DecodedRecord, error)

DecodeRecord verifies and decrypts one complete physical extent.

type DurabilityAttestor

type DurabilityAttestor interface {
	Attest(context.Context, string) error
}

DurabilityAttestor represents the deployment-specific destructive power-loss qualification that fsync alone cannot prove (for example, volatile device caches that acknowledge barriers). A production file manager is not created unless the target volume's attestation is currently valid.

type EmissionPath

type EmissionPath struct {
	State                            LastSuccessState
	Transition                       Transition
	Records                          []RecordKind
	Rotation                         bool
	PermanentLossIfReplacementWedges []RecordKind
}

EmissionPath is one complete path after the named primary last-success point. Multiplicity is len(Records): each semantic kind is emitted at most once. A post-timeout rotation creates no record, the diagnostic coalesces all failures for the reservation, and recovery is a single coalesced record.

func EmissionPaths

func EmissionPaths() []EmissionPath

type EmissionReservation

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

EmissionReservation combines the executable emission path with the physical 120KiB reservation. Facts must arrive once and in frozen table order.

func NewEmissionReservation

func NewEmissionReservation(id [16]byte, state LastSuccessState, transition Transition) (*EmissionReservation, error)

func (*EmissionReservation) Emitted

func (reservation *EmissionReservation) Emitted() int

func (*EmissionReservation) RemainingBytes

func (reservation *EmissionReservation) RemainingBytes() int

type EnvelopeKMS

type EnvelopeKMS interface {
	Encrypt(ctx context.Context, masterRevision string, plaintext, aad []byte) ([]byte, error)
	Decrypt(ctx context.Context, masterRevision string, ciphertext, aad []byte) ([]byte, error)
}

EnvelopeKMS is intentionally independent of the B3 redaction registry. It follows the same revisioned-key/envelope style but never shares key material or activation state with redaction keys.

type Extension

type Extension struct {
	Tag   uint16
	Value []byte
}

Extension is a canonical binary header extension. Tags must be non-zero, strictly increasing, and unique. Each entry is encoded as uint16 tag, uint16 value length, then value bytes. The aggregate encoding is capped at MaxHeaderExtension bytes and unused header bytes are zero.

type ExtentSink

type ExtentSink interface {
	WriteExtent(extent []byte) error
	Sync() error
	Close() error
}

ExtentSink writes exactly one aligned extent and durably syncs it.

type FileExtentSink

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

func NewFileExtentSink

func NewFileExtentSink(path string) (*FileExtentSink, error)

NewFileExtentSink always creates a new file. There is intentionally no API for reopening an old segment for append.

func (*FileExtentSink) Close

func (sink *FileExtentSink) Close() error

func (*FileExtentSink) Sync

func (sink *FileExtentSink) Sync() error

func (*FileExtentSink) WriteExtent

func (sink *FileExtentSink) WriteExtent(extent []byte) error

type FileKeyRegistry

type FileKeyRegistry struct{ Directory string }

FileKeyRegistry is a durable, process-shared CAS registry for a WAL volume. Create-exclusive files provide the CAS; file and parent directory fsync make a successful reservation survive restart. The registry stores only a digest of KMS ciphertext, never plaintext segment keys.

func (FileKeyRegistry) Reserve

func (registry FileKeyRegistry) Reserve(ctx context.Context, keyID string, segmentID [16]byte, wrappedKey []byte) (bool, error)

type FileManifestStore

type FileManifestStore struct{ Directory string }

FileManifestStore is the local manifest implementation. Each manifest is create-exclusive, mode 0600, file-synced, then its parent directory is synced.

func (FileManifestStore) Persist

func (store FileManifestStore) Persist(ctx context.Context, manifest SegmentManifest) error

type FileQuarantineStore

type FileQuarantineStore struct{ Directory string }

func (FileQuarantineStore) Quarantine

func (store FileQuarantineStore) Quarantine(ctx context.Context, source string, cause error) error

type FileScanner

type FileScanner struct {
	Directory  string
	Unwrapper  SegmentKeyUnwrapper
	Quarantine QuarantineStore
}

FileScanner accepts only complete authenticated extents. A torn tail, manifest mismatch, ordinal gap/reorder, bad AEAD/digest, or duplicate nonce quarantines the whole segment; no prefix is replayed from that segment.

func (FileScanner) Scan

func (scanner FileScanner) Scan(ctx context.Context) (ScanResult, error)

type GlobalEntry

type GlobalEntry struct {
	Position       uint64
	PreviousDigest [32]byte
	Digest         [32]byte
	EventUUID      [16]byte
	PayloadDigest  [32]byte
}

type HistoricalResponseState

type HistoricalResponseState uint8
const (
	HistoricalResponseUnknown HistoricalResponseState = iota
	HistoricalResponsePrepared
)

type IdentityKeyWrapper

type IdentityKeyWrapper struct{}

IdentityKeyWrapper is only a test implementation. Production wiring must provide an authenticated KMS-backed wrapper before this package is enabled.

func (IdentityKeyWrapper) Wrap

func (IdentityKeyWrapper) Wrap(_ context.Context, segmentKey [32]byte) ([]byte, error)

type IngestResult

type IngestResult struct {
	Durability ReportedDurability
	Append     AppendResult
	Primary    bool
}

type KMSKeyWrapper

type KMSKeyWrapper struct {
	KMS            EnvelopeKMS
	MasterRevision string
}

KMSKeyWrapper wraps one independently generated key per segment. A KMS outage is returned as ErrKeyUnavailable; callers must fail closed.

func (KMSKeyWrapper) UnwrapSegmentKey

func (wrapper KMSKeyWrapper) UnwrapSegmentKey(ctx context.Context, manifest SegmentManifest) ([32]byte, error)

func (KMSKeyWrapper) Wrap

func (wrapper KMSKeyWrapper) Wrap(context.Context, [32]byte) ([]byte, error)

func (KMSKeyWrapper) WrapSegmentKey

func (wrapper KMSKeyWrapper) WrapSegmentKey(ctx context.Context, keyID string, segmentID [16]byte, key [32]byte) ([]byte, error)

type KeyRegistry

type KeyRegistry interface {
	Reserve(ctx context.Context, keyID string, segmentID [16]byte, wrappedKey []byte) (bool, error)
}

KeyRegistry reserves key identities by compare-and-set. A false result means the key ID already exists; callers must discard the candidate key and ID.

type KeyWrapper

type KeyWrapper interface {
	Wrap(ctx context.Context, segmentKey [32]byte) ([]byte, error)
}

KeyWrapper represents the external master-key operation. The raw segment key is never written to the manifest by SegmentFactory.

type LastSuccessState

type LastSuccessState string
const (
	LastBeforeBeginBarrier      LastSuccessState = "before_begin_barrier"
	LastActiveBeforeEffect      LastSuccessState = "active_before_statement_effect"
	LastAfterStatementEffect    LastSuccessState = "after_statement_effect"
	LastRollbackOnly            LastSuccessState = "rollback_only"
	LastBeforeCommitIntent      LastSuccessState = "before_commit_intent_durable"
	LastIntentDurableBeforeSend LastSuccessState = "intent_durable_before_commit_send"
	LastPositiveCommitACK       LastSuccessState = "positive_commit_ack"
	LastUnknownCommitOutcome    LastSuccessState = "unknown_commit_outcome"
	LastRollbackACK             LastSuccessState = "rollback_ack"
)

type Manager

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

Manager creates a fresh segment on startup and supports at most one rotation after a wedge for each reservation. Rotation itself emits no WAL record. If the replacement segment wedges on the same reservation, no second rotation, diagnostic, or retry is allowed; remaining facts are LOST and are represented only by the durable result receipt plane.

func NewFileManager

func NewFileManager(ctx context.Context, factory SegmentFactory, owner uint64, directory string, attestor DurabilityAttestor) (*Manager, error)

func NewManager

func NewManager(ctx context.Context, factory SegmentFactory, owner uint64, newSink func(Segment) (ExtentSink, error)) (*Manager, error)

func (*Manager) ChangeOwnership

func (manager *Manager) ChangeOwnership(ctx context.Context, owner uint64) error

ChangeOwnership seals the current writer and creates a fresh segment, key, nonce domain, and ordinal space. The old segment is never reopened.

func (*Manager) Close

func (manager *Manager) Close() error

Close seals the active writer and every retired writer exactly once. It is the final step after transaction drain and before metadata storage closes.

func (*Manager) Current

func (manager *Manager) Current() *Writer

func (*Manager) RotateAfterWedge

func (manager *Manager) RotateAfterWedge(ctx context.Context, reservationID [16]byte) error

type ManifestStore

type ManifestStore interface {
	Persist(ctx context.Context, manifest SegmentManifest) error
}

ManifestStore must make the manifest durable, including its parent directory, before Persist returns nil.

type MemoryKeyRegistry

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

MemoryKeyRegistry is a concurrency-safe contract implementation for tests. It models durable CAS state only; it is not a production registry.

func NewMemoryKeyRegistry

func NewMemoryKeyRegistry() *MemoryKeyRegistry

func (*MemoryKeyRegistry) Reserve

func (registry *MemoryKeyRegistry) Reserve(_ context.Context, keyID string, segmentID [16]byte, _ []byte) (bool, error)

type MemoryManifestStore

type MemoryManifestStore struct {
	Manifests []SegmentManifest
	Err       error
	// contains filtered or unexported fields
}

MemoryManifestStore is a test implementation that records the persist order.

func (*MemoryManifestStore) Persist

func (store *MemoryManifestStore) Persist(_ context.Context, manifest SegmentManifest) error

type MemoryReceiptStore

type MemoryReceiptStore struct {
	PutErr     error
	AdvanceErr error
	// contains filtered or unexported fields
}

func NewMemoryReceiptStore

func NewMemoryReceiptStore() *MemoryReceiptStore

NewMemoryReceiptStore is a test contract implementation. Keeping the same instance across a simulated service restart models an external durable store; it is not the production PostgreSQL schema, which remains frozen for S1b.

func (*MemoryReceiptStore) Advance

func (*MemoryReceiptStore) FindByEventUUID

func (store *MemoryReceiptStore) FindByEventUUID(_ context.Context, eventUUID [16]byte) ([]ResultReceipt, error)

func (*MemoryReceiptStore) Get

func (*MemoryReceiptStore) PutWriteOnce

func (store *MemoryReceiptStore) PutWriteOnce(_ context.Context, receipt ResultReceipt) (ResultReceipt, bool, error)

type PGPrimaryStore

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

PGPrimaryStore writes canonical v4 facts into the frozen b5_tx_events table. It is named for production use but is dialect-neutral for SQLite tests.

func NewPGPrimaryStore

func NewPGPrimaryStore(repository store.B5TxEventStore) (*PGPrimaryStore, error)

func (*PGPrimaryStore) Put

func (primary *PGPrimaryStore) Put(ctx context.Context, event PrimaryEvent) (bool, error)

func (*PGPrimaryStore) Snapshot

func (primary *PGPrimaryStore) Snapshot(ctx context.Context, limit int) ([]PrimaryEvent, error)

Snapshot supplies the durable primary side of restart reconstruction before WAL-only records are joined. Canonical payloads are returned for digest and UUID verification; DBOutcome is intentionally not inferred from bytes.

type PGReceiptStore

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

PGReceiptStore adapts the frozen b5_result_receipts repository to the WAL receipt contract. Despite the name it deliberately works with the SQLite repository too, so the exact persistence semantics can be tested cheaply. Production construction supplies Store.B5ResultReceipts(), backed by PG.

func NewPGReceiptStore

func NewPGReceiptStore(repository store.B5ResultReceiptStore) (*PGReceiptStore, error)

func (*PGReceiptStore) Advance

func (adapter *PGReceiptStore) Advance(ctx context.Context, key ReceiptKey, update ReceiptAdvance) (ResultReceipt, error)

func (*PGReceiptStore) FindByEventUUID

func (adapter *PGReceiptStore) FindByEventUUID(ctx context.Context, eventUUID [16]byte) ([]ResultReceipt, error)

FindByEventUUID is used only by recovery. An empty result means the scanner must report HistoricalResponseUnknown and must not invent AUDIT_PENDING.

func (*PGReceiptStore) Get

func (adapter *PGReceiptStore) Get(ctx context.Context, key ReceiptKey) (ResultReceipt, bool, error)

func (*PGReceiptStore) PutWriteOnce

func (adapter *PGReceiptStore) PutWriteOnce(ctx context.Context, receipt ResultReceipt) (ResultReceipt, bool, error)

type PrimaryEvent

type PrimaryEvent struct {
	ReplayEvent
	Kind           RecordKind
	Outcome        DBOutcome
	SchemaID       string
	SchemaVersion  uint16
	CanonicalEvent []byte
}

PrimaryEvent is the already-canonical fact presented to the durable primary audit plane. Put must be idempotent for equal UUID+PayloadDigest and fail closed with ErrEventUUIDConflict for an unequal digest.

type PrimarySnapshot

type PrimarySnapshot interface {
	Snapshot(context.Context, int) ([]PrimaryEvent, error)
}

type PrimaryStore

type PrimaryStore interface {
	Put(context.Context, PrimaryEvent) (alreadyPresent bool, err error)
}

type QuarantineStore

type QuarantineStore interface {
	Quarantine(context.Context, string, error) error
}

type ReceiptAdvance

type ReceiptAdvance struct {
	Append         *AppendConfirmationState
	Reconciliation *ReconciliationState
	Delivery       *ResponseDeliveryState
}

type ReceiptFinder

type ReceiptFinder interface {
	FindByEventUUID(context.Context, [16]byte) ([]ResultReceipt, error)
}

type ReceiptKey

type ReceiptKey struct {
	SessionID         string
	RequestID         string
	EventUUID         [16]byte
	AttemptGeneration uint64
}

type ReceiptStore

type ReceiptStore interface {
	PutWriteOnce(ctx context.Context, receipt ResultReceipt) (ResultReceipt, bool, error)
	Get(ctx context.Context, key ReceiptKey) (ResultReceipt, bool, error)
	Advance(ctx context.Context, key ReceiptKey, update ReceiptAdvance) (ResultReceipt, error)
}

type Reconciler

type Reconciler struct {
	Primary  PrimaryStore
	Receipts ReceiptStore
	Finder   ReceiptFinder
}

Reconciler replays verified records in double-chain order and durably joins them to the result-receipt plane. The returned ledger is an operational view; receipt updates and primary rows are the durable recovery ledger.

func (Reconciler) Reconcile

func (reconciler Reconciler) Reconcile(ctx context.Context, records []RecoveredRecord) ([]RecoveryLedgerEntry, error)

type ReconciliationState

type ReconciliationState = b5.Reconciliation

type Record

type Record struct {
	SegmentID          [16]byte
	RecordOrdinal      uint64
	ReservationID      [16]byte
	EventUUID          [16]byte
	EventSchemaID      string
	EventSchemaVersion uint16
	KeyID              string
	Nonce              [12]byte
	CanonicalEvent     []byte
	Extensions         []Extension
}

Record identifies and carries one already-canonical event-v4 payload.

type RecordKind

type RecordKind string

RecordKind is an event-v4 semantic kind. Result receipts are deliberately absent: they live in ReceiptStore and do not consume WAL record slots.

const (
	RecordStatement            RecordKind = "tx_statement"
	RecordRollback             RecordKind = "tx_rollback"
	RecordTerminalOutcome      RecordKind = "tx_terminal_outcome"
	RecordSessionTerminal      RecordKind = "session_terminal"
	RecordDurabilityDiagnostic RecordKind = "durability_diagnostic"
	RecordRecovery             RecordKind = "tx_durability_recovered"
	RecordCommitIntent         RecordKind = "tx_commit_intent"
)

type RecoveredRecord

type RecoveredRecord struct {
	Decoded  DecodedRecord
	Identity AppendIdentity
	Event    PrimaryEvent
	Source   string
}

type RecoveryClassification

type RecoveryClassification string
const (
	RecoveryHistoricalUnknown        RecoveryClassification = "HISTORICAL_RESPONSE_UNKNOWN"
	RecoveryCommittedAuditPending    RecoveryClassification = "COMMITTED_AUDIT_PENDING"
	RecoveryNotCommittedAuditPending RecoveryClassification = "NOT_COMMITTED_AUDIT_PENDING"
	RecoveryDBOutcomeUnknown         RecoveryClassification = "UNKNOWN"
	RecoveryPrimaryDurable           RecoveryClassification = "PRIMARY_DURABLE"
)

type RecoveryLedgerEntry

type RecoveryLedgerEntry struct {
	EventUUID          [16]byte
	TransactionID      string
	TransactionSeq     uint64
	Classification     RecoveryClassification
	HistoricalResponse HistoricalResponseState
	ReportedDurability ReportedDurability
	AppendConfirmation AppendConfirmationState
	Reconciliation     ReconciliationState
	Replayed           bool
}

type ReplayEvent

type ReplayEvent struct {
	EventUUID        [16]byte
	PayloadDigest    [32]byte
	TransactionID    string
	TransactionSeq   uint64
	PreviousTxDigest [32]byte
}

type ReplayVerifier

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

func NewReplayVerifier

func NewReplayVerifier() *ReplayVerifier

func (*ReplayVerifier) GlobalChain

func (verifier *ReplayVerifier) GlobalChain() []GlobalEntry

func (*ReplayVerifier) Ingest

func (verifier *ReplayVerifier) Ingest(event ReplayEvent) (GlobalEntry, bool, error)

Ingest validates the caller-supplied per-transaction predecessor and builds the independent global chain in actual ingestion order. Same UUID + same payload is idempotent; same UUID + different payload fails closed.

type ReportedDurability

type ReportedDurability = b5.AuditDurability

type Reservation

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

Reservation accounts physical extents, not plaintext bytes. A normal B5 path is created with MaxPathRecordCount and therefore exactly 120 KiB.

func NewReservation

func NewReservation(recordCount int) (*Reservation, error)

func (*Reservation) ConsumeEncodedRecord

func (reservation *Reservation) ConsumeEncodedRecord(extent []byte) error

func (*Reservation) Remaining

func (reservation *Reservation) Remaining() int

type ResponseDeliveryState

type ResponseDeliveryState = b5.DeliveryStatus

type RestartView

type RestartView struct {
	HistoricalResponse HistoricalResponseState
	Receipt            ResultReceipt
	RecordValid        bool
}

func RestartJoin

func RestartJoin(ctx context.Context, store ReceiptStore, key ReceiptKey, recordValid, primaryDurable bool) (RestartView, error)

RestartJoin never derives a historical AUDIT_PENDING/LOST value from WAL. Without a durable receipt, the historical response is unknown/unreported. With one, its reported value is immutable while append/reconciliation may advance monotonically based on verified scan and replay facts.

type ResultReceipt

type ResultReceipt struct {
	SchemaID                     string
	SchemaVersion                uint16
	Key                          ReceiptKey
	BusinessEventDigest          [32]byte
	WALAppendReceiptDigest       [32]byte
	ReportedDurabilityAtResponse ReportedDurability
	AppendConfirmation           AppendConfirmationState
	Reconciliation               ReconciliationState
	Delivery                     ResponseDeliveryState
}

ResultReceipt is write-once for Key, both digests, and ReportedDurabilityAtResponse. Mutable state advances only through the transition functions below. Persisting Prepared before sending makes the exact terminal result reproducible even if the process dies before or during network delivery; SendStarted cannot prove that a peer received the bytes.

type ScanResult

type ScanResult struct {
	Records     []RecoveredRecord
	Quarantined []string
}

type Segment

type Segment struct {
	Manifest SegmentManifest
	Key      [32]byte
}

type SegmentFactory

type SegmentFactory struct {
	Random         io.Reader
	MasterRevision string
	Registry       KeyRegistry
	Wrapper        KeyWrapper
	Manifests      ManifestStore
}

func (SegmentFactory) Create

func (factory SegmentFactory) Create(ctx context.Context, ownerGeneration uint64) (Segment, error)

type SegmentKeyUnwrapper

type SegmentKeyUnwrapper interface {
	UnwrapSegmentKey(context.Context, SegmentManifest) ([32]byte, error)
}

type SegmentManifest

type SegmentManifest struct {
	FormatVersion   uint16   `json:"format_version"`
	SegmentID       [16]byte `json:"segment_id"`
	KeyID           string   `json:"key_id"`
	WrappedKey      []byte   `json:"wrapped_key"`
	NonceDomain     [4]byte  `json:"nonce_domain"`
	OwnerGeneration uint64   `json:"owner_generation"`
}

type Service

type Service struct {
	Primary     PrimaryStore
	Receipts    ReceiptStore
	WAL         *Manager
	SyncTimeout time.Duration
}

Service is the flag-off production boundary intended for S6. It owns primary-first ingestion, emergency staging, the response receipt fence, and one post-wedge rotation. It has no dependency on MCP or HTTP packages.

func (*Service) IngestAndRespond

func (service *Service) IngestAndRespond(ctx context.Context, reservation *EmissionReservation, event ServiceEvent, send func(ResultReceipt) error) (IngestResult, error)

type ServiceEvent

type ServiceEvent struct {
	Kind              RecordKind
	Outcome           DBOutcome
	TransactionID     string
	TransactionSeq    uint64
	PreviousTxDigest  [32]byte
	EventUUID         [16]byte
	SchemaID          string
	SchemaVersion     uint16
	CanonicalEvent    []byte
	SessionID         string
	RequestID         string
	AttemptGeneration uint64
}

type Transition

type Transition string
const (
	TransitionPrimaryFailure Transition = "primary_failure"
	TransitionFsyncTimeout   Transition = "wal_fsync_timeout"
	TransitionLateRecovery   Transition = "late_or_restart_recovery"
)

type Writer

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

func NewWriter

func NewWriter(segment Segment, sink ExtentSink) (*Writer, error)

func (*Writer) Append

func (writer *Writer) Append(ctx context.Context, record Record) (AppendResult, error)

func (*Writer) AppendReserved

func (writer *Writer) AppendReserved(ctx context.Context, reservation *Reservation, record Record) (AppendResult, error)

AppendReserved charges the complete physical extent before any bytes are written. A failed or ambiguous append does not refund capacity: retrying the same fact under a reused nonce is forbidden and the six-record bound must remain conservative.

func (*Writer) Seal

func (writer *Writer) Seal() error

func (*Writer) Segment

func (writer *Writer) Segment() Segment

func (*Writer) State

func (writer *Writer) State() WriterState

type WriterState

type WriterState uint8
const (
	WriterOpen WriterState = iota
	WriterWedgedUnconfirmed
	WriterSealed
)

Jump to

Keyboard shortcuts

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