aeat.core._bucket_pointer_io module¶
Atomic IO and selector resolution for the active-profile pointer file.
The pointer file lives at <aeat-root>/active-profile and is the on-disk
default after the per-invocation / per-shell override path. The CLI --profile
flag is normalised into Settings.aeat_active_profile, so this module’s
runtime branches are settings override first and pointer file second. The write
path uses the write-then-rename pattern so a crashed switch never produces a
truncated pointer; the read path returns None only when the pointer is
absent.
The IO helpers serialise BucketPointer records and feed
resolve_active_bucket_id(), the central core resolver consumed by storage
and CLI startup flows. The resolver returns the selected bucket id string; it
does not prove a buckets/<id>/manifest.toml exists, scan profile display
labels, or open encrypted state. Those registry/existence checks belong to
application-layer manifest scanners that return
ProfileBucketPointer.
Repository factories that need a hard bucket id use
resolve_repository_bucket_id() so each domain can raise its own error type
while sharing the same pointer precedence.
- pointer_path(root)[source]¶
Return the canonical
active-profilepointer path under the AEAT root.- Parameters:
root (
Path) – AEAT local storage root.- Return type:
Path- Returns:
root / "active-profile"without touching the filesystem.
- read_pointer(root)[source]¶
Read and strict-validate the pointer file.
Present files are parsed by
from_toml(); invalid TOML, unknown keys, and invalid scalar values propagate instead of being reclassified as an absent pointer.- Parameters:
root (
Path) – AEAT local storage root directory that contains theactive-profilepointer file.- Return type:
- Returns:
The parsed
BucketPointer, orNonewhen the pointer file is absent. The higher-level resolver treatsNoneas “fall through to the next precedence rung”.- Raises:
OSError – If the present pointer file cannot be read.
tomllib.TOMLDecodeError – If the present file is not valid TOML.
pydantic.ValidationError – If the present TOML violates the strict
BucketPointerschema.
- resolve_active_bucket_id()[source]¶
Resolve the active bucket id via the operator-facing precedence chain.
Precedence, highest wins:
Settings.aeat_active_profile— surfaced from theAEAT_ACTIVE_PROFILEenvironment variable (or an activeoverride_settings()block in tests). Per-shell override useful for CI, headless invocations, and the CLI--profileflag.<aeat-root>/active-profileplaintext pointer file written byprofile create/config switch. This is the canonical default for interactive sessions and resolves the chicken-and-egg defect where an encrypted state row could not be read without first knowing which bucket to unlock.
The CLI
--profileflag, when supplied per-invocation, runs the process under anoverride_settings()block that setsaeat_active_profileso rung one handles it without a fourth precedence rung.This resolver lives in the core layer: it reads only the settings
Settingsobject and the plaintext pointer file, both core-layer concerns. The at-rest crypto substrate (master-key provider) resolves the active bucket through this function, so it must sit at or below the adapter layer to keep the dependency direction acyclic.
- require_active_bucket_id()[source]¶
Resolve the active bucket id via the precedence chain, or raise.
Companion to
resolve_active_bucket_id()for call sites that require a selected profile rather than tolerating its absence. Operator-initiated auth session paths, the Cl@ve Móvil persistence path, the SEDE declarations-register profile name, and bucket-scoped repositories all sit on flows that require a profile to be selected; a missing profile is a genuine refusal, not a degraded read. Reads env var > pointer file; raisesNoActiveProfileErrorif neither rung resolves.Diagnostic surfaces (browser-connectivity probe, status flows) MUST NOT call this helper — they call
resolve_active_bucket_id()and supply their own fallback label so a missing profile stays diagnosable.- Return type:
- Returns:
The selected active bucket id.
- Raises:
aeat.core.errors.NoActiveProfileError – If neither settings nor the pointer file selects a bucket id.
- write_pointer(root, pointer)[source]¶
Atomically write the pointer file via write-then-rename.
The payload is staged at a
.tmpsibling and renamed viaos.replace(); a crashed process therefore leaves either the previous good pointer or the new good pointer on disk, never a torn intermediate. The payload comes fromto_toml(), and the AEAT root is created lazily if absent.- Parameters:
root (
Path) – AEAT local storage root that will contain the pointer file.pointer (
BucketPointer) – Validated pointer record to serialise.
- Raises:
OSError – If the parent directory cannot be created, the temporary file cannot be written, or the atomic replacement fails.
- Return type:
- resolve_repository_bucket_id(bucket_id, *, error_type)[source]¶
Resolve an explicit-or-active profile bucket id for a runtime repository.
Single canonical home for the per-domain repository bucket-id resolution that the
domain.modelos,domain.filing, andapplication.filingruntime-repository modules each previously copied verbatim, differing only in the domain error they raise. An explicit, non-blankbucket_idis returned trimmed; a blank explicit id or an absent active profile both raiseerror_type(the caller’s domain error) carrying the sharedno_active_profile_bucketmessage and a structured reason. This is the repository-facing companion torequire_active_bucket_id().- Parameters:
- Return type:
- Returns:
The resolved bucket id.
- Raises:
AeatError – The supplied
error_typewhenbucket_idis blank or no active profile bucket can be resolved.