Skip to main content

internal/infra/pg/factreceipt.go

internal/infra/pg · 223 lines · 8 declarations · source

Declarations​

const MaxRecoveryPage​

const MaxRecoveryPage = 100

source

var ErrInvalidRecovery​

var ErrInvalidRecovery = errors.New("recovery requires a valid cursor, source and page size")

source

var ErrInvalidReceipt​

var ErrInvalidReceipt = errors.New("formation receipt no longer matches its surviving source")

source

type RecoveryPage​

type RecoveryPage struct {
Examined int `json:"examined"`
Restored int `json:"restored"`
Repaired int `json:"repaired"`
Next string `json:"next,omitempty"`
}

RecoveryPage is a live UUID page. Repeating a page preserves retained records, and an interrupted transaction advances nothing. A new full pass finds concurrent additions below a previous cursor.

source

method FactStore.RecoverFacts​

func (s *FactStore) RecoverFacts(ctx context.Context, schema Schema, scope, source, after, principal string, limit int) (RecoveryPage, error)

RecoverFacts restores one bounded page without a model call or a delete of available memory. It does not claim to regenerate embeddings, summaries, or interpretations under new model rules.

source

func restoreFactReceiptTx​

func restoreFactReceiptTx(ctx context.Context, tx pgx.Tx, schema Schema, scope, id string) (bool, error)

Receipt state is a typed PostgreSQL row, not a model response. Source byte verification prevents recovery from a changed transcript. Existing rows win; recovery never restamps current memory.

source

const retainFactReceiptSQL​

const retainFactReceiptSQL = `INSERT INTO {schema}.fact_receipt(scope,fact_id,source_observation_id,source_ordinal,state,evidence,subject_identity,object_identity,pipeline_version,supersession_source,superseded_by)
SELECT f.scope,f.fact_id,e.source_observation_id,e.source_ordinal,to_jsonb(f),to_jsonb(e),
to_jsonb(l)-'aliases'-'normalized_aliases',to_jsonb(r)-'aliases'-'normalized_aliases',d.pipeline_version,f.supersession_source,f.superseded_by
FROM {schema}.fact f JOIN {schema}.fact_evidence e ON e.scope=f.scope AND e.fact_id=f.fact_id
JOIN {schema}.projection_dependency d ON d.scope=f.scope AND d.fact_ref=f.fact_id AND d.source_observation_id=e.source_observation_id
LEFT JOIN {schema}.entity l ON l.scope=f.scope AND l.entity_id=f.subject_entity_id
LEFT JOIN {schema}.entity r ON r.scope=f.scope AND r.entity_id=f.object_entity_id
WHERE f.scope=$1 AND f.fact_id=$2::uuid ON CONFLICT(scope,fact_id) DO NOTHING`

source

func receiptOwnershipSQLFor​

func receiptOwnershipSQLFor(table, owned string) string

receiptOwnershipSQLFor is the ownership predicate over any subquery of owned observation ids, so an erasure by source counts receipts exactly as an erasure by subject does, and both governance readers — the export and the erasure — ask the question in exactly one way. The table names are a fixed internal set.

source