cadrumo.application.storage.sync_runs.records module¶
Local typed record of one completed synchronisation run, and its store.
The provenance authority for “when was this last synchronised”. Before this
store, no such authority existed anywhere in the source tree – a searched
absence, not an assumed one: there is no last_sync, synced_at or
last_synced field in production code, so the only signal an operator had was
whatever the remote surface happened to stamp on itself. A remote stamp answers
“when did the far side last change”, which is a different question and is
unavailable at all when the run fails partway.
Why a second run-record store rather than an existing one¶
LLMRunRecord is a shipped local encrypted
run-record store, and it is deliberately not extended here. Its fields are
provider-call accounting – caller, provider, model, duration, succeeded,
error kind – and not one of them carries a SUBJECT. It cannot express what was
synchronised, and a sync run has no provider or model to record. That store is a
latency-and-failure shape; this one is a coverage shape, and substitutability
fails in both directions. Its package documents that it admits no parallel
capture path, which is an invariant about its own projections rather than a
prohibition on any second run record in the tree.
What a record claims, and what it does not¶
A record is written on completion of a run over ONE surface, on partial failure as well as on success. That is deliberate and it is the half most easily dropped: a record written only on success makes every truncated sweep invisible, which is precisely the state a reader would otherwise mistake for complete coverage. Partial failure means a run that TRIED to write and got partway – a different event from a run that declined to write by design.
A DRY RUN WRITES NO RECORD, and the absence is declared rather than accidental. A preview reads the remote surface and persists nothing, so it has no last-sync provenance: nothing was synced. A provenance record is itself a persist, so writing one from the preview branch would defeat the guard whose entire purpose is that a preview leaves no trace. A reader finding no record after a dry run is seeing the contract, not a gap.
unit_count and divergence_count describe what the run actually reached,
never what it intended to reach. A run that swept three of ten periods records
three, and its resolved_scope says which three. The pair is what lets a
later reader distinguish a clean full sweep from a clean partial one – two runs
that are identical in every other field and mean entirely different things.
- class SyncRunCoverageSource(*args, **kwargs)[source]¶
Bases:
ProtocolOne object that knows BOTH what a run reached and what diverged.
The whole point of the protocol is that it is a single object. A run’s two coverage counts have to be drawn from one population, and the way they stop being drawn from one population is a caller reading each from a different place – which is not a hypothetical. The filed sweep once paired advisories raised per observation ABSORBED against the count of observations successfully ENROLLED, two populations that narrow apart under a latest-per-period collapse and under a best-effort enrolment failure. The record refused the impossible pair at the very end of a real run, after every unit had already been fetched and written.
Passing counts as two integers makes that mistake expressible at every call site. Passing one source makes it expressible only by writing an object that lies about itself, which is a far higher bar and one a reviewer can see.
The member names are deliberately surface-neutral rather than borrowed from the filed sweep’s own vocabulary, because the second surface has to satisfy the same contract without renaming it.
- class SyncRunCoverage(**data)[source]¶
Bases:
BaseModelWhat one run covered: units reached, and how many of them diverged.
Built only through
coverage_of(), so the two counts always come from one source. The bound below is therefore a backstop against a lying source rather than the primary defence – the primary defence is that there is nowhere to pass two unrelated numbers in.- Parameters:
data (Any)
- unit_count: NonNegativeInt¶
- divergence_count: NonNegativeInt¶
- coverage_of(source)[source]¶
Derive both coverage counts from one source, which is the entire contract.
Read both numbers off
sourceand nothing else. A caller that wants to record a run over a surface teaches that surface’s own accumulator to answerSyncRunCoverageSource.reached_countandSyncRunCoverageSource.divergences, rather than picking two counts at the call site and hoping they describe the same population.- Parameters:
source (
SyncRunCoverageSource) – The run’s own accumulator, or anything else that can answer for one population.- Return type:
- Returns:
The validated pair, ready to hand to
record_sync_run().
- class SyncRunRecord(**data)[source]¶
Bases:
BaseModelOne completed synchronisation run over one surface, in full.
Carries the surface, the scope the run actually resolved, the instant it finished, how many units it reached and how many of those diverged, plus the id of the bucket event it is co-written with. Read
SyncSurfacefor why the surface axis is a closed set and why it has exactly two members.succeededis not redundant againstdivergence_count. A run can finish cleanly having found divergences – that is the normal outcome the store exists to record – and a run can fail partway having found none, because it never got far enough to look. Reading failure off the divergence count would invert both cases.- Variables:
bucket_event_id – Id of the co-written sync-run bucket event. Also the trailing segment of this record’s storage key, so record and event are joined by identity rather than by a field that could drift.
bucket_id – Profile bucket the run belongs to.
surface – Which external surface this run covered.
resolved_scope – What the run actually resolved its scope to, as the operator-facing description of the covered set. Empty only when the run failed before a scope could be resolved at all.
succeeded – Whether the run completed without a refusal. False for a partial run, which is still recorded rather than dropped.
unit_count – How many units the run REACHED. Never the intended total – a sweep that covered three of ten periods records three.
divergence_count – How many of those reached units diverged. Bounded by
unit_count, because a unit that was never reached cannot have been found to diverge.completed_at – UTC instant the run finished, successfully or not.
- Parameters:
data (Any)
- bucket_event_id: BucketEventId¶
- bucket_id: BucketId¶
- surface: SyncSurface¶
- resolved_scope: str¶
What the run resolved its scope to, bounded so a wide sweep can persist.
The bound is a real constraint rather than a formality: a filed sweep with no explicit modelo list resolves to EVERY bundled modelo, which enumerates past a kilobyte. A caller with a scope that would overflow must summarise it through
bounded_scope_description()rather than truncate it, because a truncated enumeration reads as a complete list of a smaller set – which is the same class of lie as a partial sweep reading as a full one.
- succeeded: bool¶
- unit_count: int¶
- divergence_count: int¶
- completed_at: datetime¶
- bounded_scope_description(items, *, suffix='')[source]¶
Describe a scope within the record’s bound, summarising rather than truncating.
A truncated enumeration is worse than a summary: it reads as a COMPLETE list of a smaller set, which is the same lie a partial sweep tells when it reads as a full one, and this store exists to stop exactly that. So an oversized scope collapses to a count and a range rather than to a prefix.
- sync_run_record_key(*, surface, bucket_event_id)[source]¶
Return the storage key for one run over one surface.
Keyed
sync-run:{surface}:{bucket_event_id}, matching the namespace’s declared grammar. N records per surface rather than one: the store is the last-sync provenance authority, and a key scoped to the surface alone would make the last sync the only sync.The scope is deliberately absent from the key. A run’s resolved scope describes what it covered, not which run it was, so a truncated sweep and a full sweep over the same surface stay distinct records – the pair a reader needs in order to tell partial coverage from complete.
- Return type:
- Parameters:
surface (SyncSurface)
bucket_event_id (str)
- class SyncRunRecordRepositoryProtocol(*args, **kwargs)[source]¶
Bases:
ProtocolPersistence port for one sync-run record and its history event.
The concrete encrypted implementation lives in
adapters.persistence.profile.sync_runs. Application orchestration supplies the record and already-derived event; the adapter owns the shared secure-object transaction that makes the pair durable together.- save_with_bucket_event(record, event)[source]¶
Persist
recordandeventin one atomic storage transaction.- Return type:
- Parameters:
record (SyncRunRecord)
event (BucketEvent)