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
- Variables
- func ComputedMaxPathRecordCount() int
- func EncodeRecord(key []byte, record Record) ([]byte, error)
- func EncodedRecordCharge() int
- func PersistThenSend(ctx context.Context, store ReceiptStore, receipt ResultReceipt, ...) error
- func ReservationCharge() int
- func SyncDirectory(path string) error
- func VerifyGlobalChain(entries []GlobalEntry) error
- func WALAppendReceiptDigest(identity AppendIdentity) [32]byte
- type AppendConfirmationState
- type AppendIdentity
- type AppendResult
- type ContextKeyWrapper
- type DBOutcome
- type DecodedRecord
- type DurabilityAttestor
- type EmissionPath
- type EmissionReservation
- type EnvelopeKMS
- type Extension
- type ExtentSink
- type FileExtentSink
- type FileKeyRegistry
- type FileManifestStore
- type FileQuarantineStore
- type FileScanner
- type GlobalEntry
- type HistoricalResponseState
- type IdentityKeyWrapper
- type IngestResult
- type KMSKeyWrapper
- func (wrapper KMSKeyWrapper) UnwrapSegmentKey(ctx context.Context, manifest SegmentManifest) ([32]byte, error)
- func (wrapper KMSKeyWrapper) Wrap(context.Context, [32]byte) ([]byte, error)
- func (wrapper KMSKeyWrapper) WrapSegmentKey(ctx context.Context, keyID string, segmentID [16]byte, key [32]byte) ([]byte, error)
- type KeyRegistry
- type KeyWrapper
- type LastSuccessState
- type Manager
- type ManifestStore
- type MemoryKeyRegistry
- type MemoryManifestStore
- type MemoryReceiptStore
- func (store *MemoryReceiptStore) Advance(_ context.Context, key ReceiptKey, update ReceiptAdvance) (ResultReceipt, error)
- func (store *MemoryReceiptStore) FindByEventUUID(_ context.Context, eventUUID [16]byte) ([]ResultReceipt, error)
- func (store *MemoryReceiptStore) Get(_ context.Context, key ReceiptKey) (ResultReceipt, bool, error)
- func (store *MemoryReceiptStore) PutWriteOnce(_ context.Context, receipt ResultReceipt) (ResultReceipt, bool, error)
- type PGPrimaryStore
- type PGReceiptStore
- func (adapter *PGReceiptStore) Advance(ctx context.Context, key ReceiptKey, update ReceiptAdvance) (ResultReceipt, error)
- func (adapter *PGReceiptStore) FindByEventUUID(ctx context.Context, eventUUID [16]byte) ([]ResultReceipt, error)
- func (adapter *PGReceiptStore) Get(ctx context.Context, key ReceiptKey) (ResultReceipt, bool, error)
- func (adapter *PGReceiptStore) PutWriteOnce(ctx context.Context, receipt ResultReceipt) (ResultReceipt, bool, error)
- type PrimaryEvent
- type PrimarySnapshot
- type PrimaryStore
- type QuarantineStore
- type ReceiptAdvance
- type ReceiptFinder
- type ReceiptKey
- type ReceiptStore
- type Reconciler
- type ReconciliationState
- type Record
- type RecordKind
- type RecoveredRecord
- type RecoveryClassification
- type RecoveryLedgerEntry
- type ReplayEvent
- type ReplayVerifier
- type ReportedDurability
- type Reservation
- type ResponseDeliveryState
- type RestartView
- type ResultReceipt
- type ScanResult
- type Segment
- type SegmentFactory
- type SegmentKeyUnwrapper
- type SegmentManifest
- type Service
- type ServiceEvent
- type Transition
- type Writer
- func (writer *Writer) Append(ctx context.Context, record Record) (AppendResult, error)
- func (writer *Writer) AppendReserved(ctx context.Context, reservation *Reservation, record Record) (AppendResult, error)
- func (writer *Writer) Seal() error
- func (writer *Writer) Segment() Segment
- func (writer *Writer) State() WriterState
- type WriterState
Constants ¶
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 )
const ( DurabilityUnspecified = b5.DurabilityUnspecified DurabilityDurable = b5.DurabilityDurable DurabilityAuditPending = b5.DurabilityAuditPending DurabilityLost = b5.DurabilityLost )
const ( AppendUnknown = b5.AppendUnknown AppendTimeout = b5.AppendTimeout AppendLateConfirmed = b5.AppendLateConfirmed AppendRecovered = b5.AppendRecovered )
const ( ReconciliationNone = b5.ReconciliationNone ReconciliationReplayStaged = b5.ReconciliationReplayStaged ReconciliationPrimaryDurable = b5.ReconciliationPrimaryDurable )
const ( ResponsePrepared = b5.DeliveryPrepared ResponseSendStarted = b5.DeliverySendStarted ResponseSendCompleted = b5.DeliverySendComplete )
const ( WALFormatVersion = uint16(1) TrailerVersion = uint16(1) AccountingVersion = uint16(1) )
const DefaultFsyncTimeout = 250 * time.Millisecond
Variables ¶
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") )
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") )
var ( ErrEventUUIDConflict = errors.New("b5wal: AUDIT_EVENT_UUID_CONFLICT") ErrTransactionChain = errors.New("b5wal: transaction chain violation") ErrGlobalChain = errors.New("b5wal: global chain violation") )
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") )
var ErrReservationExhausted = errors.New("b5wal: reservation exhausted")
Functions ¶
func ComputedMaxPathRecordCount ¶
func ComputedMaxPathRecordCount() int
func EncodeRecord ¶
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 ¶
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 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 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 ¶
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 ¶
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 ¶
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.
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 ¶
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 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.
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) WrapSegmentKey ¶
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 ¶
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 ¶
ChangeOwnership seals the current writer and creates a fresh segment, key, nonce domain, and ordinal space. The old segment is never reopened.
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
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 (store *MemoryReceiptStore) Advance(_ context.Context, key ReceiptKey, update ReceiptAdvance) (ResultReceipt, error)
func (*MemoryReceiptStore) FindByEventUUID ¶
func (store *MemoryReceiptStore) FindByEventUUID(_ context.Context, eventUUID [16]byte) ([]ResultReceipt, error)
func (*MemoryReceiptStore) Get ¶
func (store *MemoryReceiptStore) Get(_ context.Context, key ReceiptKey) (ResultReceipt, bool, error)
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 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 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 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
}
type SegmentKeyUnwrapper ¶
type SegmentKeyUnwrapper interface {
UnwrapSegmentKey(context.Context, SegmentManifest) ([32]byte, error)
}
type SegmentManifest ¶
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 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 (*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) State ¶
func (writer *Writer) State() WriterState
type WriterState ¶
type WriterState uint8
const ( WriterOpen WriterState = iota WriterWedgedUnconfirmed WriterSealed )