Skip to main content

internal/infra/pg/recordretraction.go

internal/infra/pg · 295 lines · 17 declarations · source

Declarations

const MaxRecordMutations

const MaxRecordMutations = 20

source

const MaxRetractionSources

const MaxRetractionSources = 128

source

var ErrInvalidRecordMutation, ErrRecordConflict, ErrRecordMutationLimit and 1 more

var (
ErrInvalidRecordMutation = errors.New("invalid record mutation")
ErrRecordConflict = errors.New("record version changed or is already withdrawn")
ErrRecordMutationLimit = errors.New("record mutation exceeds its source bound")
ErrRetractedClaim = errors.New("claim was withdrawn for this source message")
)

source

type RecordMutation

type RecordMutation struct {
ID string `json:"id"`
ExpectedVersion string `json:"expected_version"`
}

source

type RetractionDetails

type RetractionDetails struct {
OperationID string `json:"operation_id"`
PrincipalID string `json:"principal_id"`
RetractedAt time.Time `json:"retracted_at"`
ReplacementObservationID *string `json:"replacement_source_observation_id,omitempty"`
ReplacementFactID *string `json:"replacement_record_id,omitempty"`
}

source

type RecordRetraction

type RecordRetraction struct {
ID string `json:"id"`
Version string `json:"version"`
RetractionDetails
}

source

type RetractionBatch

type RetractionBatch struct {
Records []RecordRetraction `json:"records"`
}

source

type retractionSource

type retractionSource struct {
FactID string
ObservationID string
Ordinal int
}

source

func claimSignature

func claimSignature(predicate, subjectKind, subjectKey, objectKind, objectKey string) []byte

The source message and structural identity define the instruction. A paraphrased statement or a different valid-from date cannot undo withdrawal; an independent later message can assert it. Hashes here are matching keys, not anonymization. Their source ownership governs erasure.

source

func claimEndpoint

func claimEndpoint(name, subject string, speaker bool) (string, string)

source

func sourceClaimID

func sourceClaimID(scope, observationID, subject string, claim domain.Claim, leftSpeaker, rightSpeaker bool) (uuid.UUID, error)

Identity follows the source assertion, so replay and derived-row recovery do not invent a new citation. Reinterpreting a retained source is an explicit generation operation, never a retry.

source

func lockClaimSource

func lockClaimSource(ctx context.Context, tx pgx.Tx, schema Schema, scope, observationID string) error

Formation and retraction serialize only when they address the same source. A hash collision delays unrelated work but cannot change its identity or project predicates.

source

func readRetraction

func readRetraction(ctx context.Context, tx pgx.Tx, schema Schema, scope, id string) (*RetractionDetails, error)

source

func refuseRetractedClaim

func refuseRetractedClaim(ctx context.Context, tx pgx.Tx, schema Schema, scope, observationID, subject string, claim domain.Claim, leftSpeaker, rightSpeaker bool) error

source

func retractionSources

func retractionSources(ctx context.Context, tx pgx.Tx, schema Schema, scope string, ids []string) ([]retractionSource, error)

source

method RecordStore.Retract

func (s *RecordStore) Retract(ctx context.Context, scope, principal string, requests []RecordMutation) (RetractionBatch, error)

Retract is an atomic bounded batch. Source instructions, closed knowledge, report invalidation, new versions and an attributable content-free audit entry either all commit or all roll back.

source

method RecordStore.retractTx

func (s *RecordStore) retractTx(ctx context.Context, tx pgx.Tx, scope, principal string, requests []RecordMutation) (RetractionBatch, error)

The caller owns commit so a correction can withdraw its target and assert its replacement together.

source