cadrumo.adapters.persistence.storage.custody.capsule_discovery module

Anchored discovery and retired-layout refusal for profile custody.

The discovery boundary deliberately has two, non-overlapping outcomes:

  • only a final UUID directory with an authentic current commit marker is a discoverable capsule; and

  • a member of the closed retired-layout inventory is an explicit refusal.

The latter is an existence-only detector. It never opens, reads, parses, or otherwise interprets a retired member. Keeping that distinction here gives every application projection the same rooted, no-follow inventory rather than letting workflow code rediscover buckets or manifests independently.

class AnchoredCurrentCapsuleCommit(capsule_path, commit, label_payload=None, label_requested=False)[source]

Bases: object

One current-marker observation, optionally carrying its anchored label bytes.

Parameters:
  • capsule_path (Path)

  • commit (_CommitIdentity)

  • label_payload (bytes | None)

  • label_requested (bool)

capsule_path: Path
commit: _CommitIdentity
label_payload: bytes | None
label_requested: bool

Whether the caller asked for label provenance at all.

Separating “not asked for” from “asked for and absent” is what lets a summary reader tell a programming error from a capsule that changed generation between the marker parse and the label read.

property profile_id: UUID

Return the UUID proved by the canonical directory and parsed marker.

PROFILE_CUSTODY_RETIRED_BUCKET_MEMBER_PATHS: tuple[str, ...]

Closed, exact retired members checked below every bucket candidate.

The former plaintext profile authority. Current capsules have no manifest member: their only discovery authority is the commit marker and their label is a non-authoritative current projection.

The name is read from the core storage taxonomy rather than re-typed, because this detector is the load-bearing reader of it and a second literal here could drift silently – recognising nothing while still looking correct. If the taxonomy member is ever deleted outright, this import fails loudly at module load, which is the right failure for a refusal path.

PROFILE_CUSTODY_RETIRED_KEYSTORE_MEMBER_PATHS: tuple[str, ...]

Closed, exact retired members checked below every keystore candidate.

bucket.dek.json was the shared-master-wrapped bucket data-encryption key. Its writer is gone, so no current-format store can produce one, and a store still carrying it holds ciphertext whose only key route is the retired shared-master schedule. That is a re-enrolment case, never a read: the detector recognises the name and nothing else.

The keystore root is a SIBLING of the buckets root, never nested inside a bucket, so a store can carry retired key material with an entirely current buckets tree. Checking only below the buckets root left exactly that store undetected.

refuse_retired_profile_custody_paths(capsules_root, *, keystore_root)[source]

Raise the one destructive-reset refusal when a retired member exists.

The detector intentionally reports no parsed attributes and no candidate identity. A caller can act only on the stable refusal and its explicit reset/re-enrol guidance, never on an inferred retired profile.

Both scanned roots are reported alongside the member names because the only sanctioned remedy is a destructive reset of that store, and an operator cannot reset a location the refusal withholds. Retired key material lives outside the buckets tree, so naming only the buckets root would point the operator at a directory whose removal leaves the refusal standing. Each names a directory, never a bucket or an identity, so the refusal discloses nothing the detector declined to infer and requires reading no retired content.

Those two roots are the REMEDY, and both are always named for that reason. Which root each member was found under is a separate question – the CAUSE – and a flat union of member names across both roots answers it only by accident, when a single member is detected. A store carrying both members reported two names and two roots with no pairing, and a store carrying only retired key material reported a buckets root that has nothing wrong with it. So each firing arm additionally contributes a root-relative search pattern under its own key, and an arm that did not fire contributes none. Both facts are pure existence: which member name matched, below which named root, at the one depth the scan looks.

Return type:

None

Parameters:
  • capsules_root (Path)

  • keystore_root (Path)

anchored_current_capsule_commits(capsules_root, *, parse_commit, commit_filename, maximum_bytes, label_filename=None, label_maximum_bytes=None)[source]

Discover current capsules while retaining anchored marker observations.

An identity-only caller leaves the label arguments absent. A summary caller supplies both and receives the label’s bounded bytes from the same candidate anchor as the parsed commit, so a directory replacement cannot splice one generation’s marker to another generation’s provenance.

Return type:

tuple[AnchoredCurrentCapsuleCommit, ...]

Parameters:
  • capsules_root (Path)

  • parse_commit (Callable[[bytes], _CommitIdentity])

  • commit_filename (str)

  • maximum_bytes (int)

  • label_filename (str | None)

  • label_maximum_bytes (int | None)