cadrumo.application.user_profile.registration module¶
Credential-first profile registration.
This is the door behind the terminal’s first screen. It exists because
profile creation used to be split across two surfaces that never met: the
operator’s chosen label arrived as a shell argument to
config profile create, while the passphrase that actually protects the
bucket was only ever collected later, by config login, through a
separate command. Nothing in the setup flow collected a credential at all.
The contract here is deliberately minimal: a profile exists the moment a
label and a passphrase are supplied. No tax id, no régimen, no activity —
those are profile completeness, filled in afterwards against a live
record, not preconditions for the record existing. The profile is therefore
born SETUP_INCOMPLETE: real, addressable, and writable, while modelo
work stays refused until the facts that filing depends on are present.
Registration is the sole creation path. It stages the first encrypted record and then commits the capsule, label projection, and pointer transaction. The bucket’s key-encryption key is derived from the credential the operator chose rather than from an ambient environment value.
See also
login_profile()The returning-operator counterpart; this module is the first-time path that has no key material to unwrap yet.
- exception ProfileRegistrationError(message=None, *, context=None, translated_message=None, password_refusal=None)[source]¶
Bases:
CadrumoErrorRaised when a registration request cannot be honoured as supplied.
- Parameters:
- Return type:
None
- property password_refusal: ProspectiveProfilePasswordRefusal | None¶
Retain the typed refusal for trusted in-process consumers only.
- code¶
- exception ProfileRegistrationConflictError(message=None, *, context=None, translated_message=None, password_refusal=None)[source]¶
Bases:
ProfileRegistrationErrorRaised when registration lost a race it can win by simply repeating.
A custody transaction refuses when the witness it captured no longer matches live state, which a re-read resolves – so the identical call may succeed. That is a different answer to the operator than “this label is taken”, which no retry can change, and the two arrive here as the same exception family because the permanent case is a SUBCLASS of the transient one.
Split as a subclass for the same reason that one was: every existing handler catching
ProfileRegistrationErrorkeeps catching this, and only the published code and its retryability differ.- Parameters:
- Return type:
None
- code¶
- class ProfileRegistrationOutcome(**data)[source]¶
Bases:
BaseModelTyped result of one successful registration.
Carries no key material. The created profile is left UNLOCKED: the create span publishes its live bucket session and record authority process-wide through
publish_created_profile_session(), exactly aslogin_profile()leaves them, so the operator is not asked for the passphrase they just chose. No acceleration receipt is minted, so the next process authenticates normally.- Parameters:
data (Any)
- profile_id: ProfileId¶
- bucket_id: BucketId¶
- label: str¶
- setup_state: ProfileSetupState¶
- register_profile_with_credentials(*, label, passphrase, facts=(), profile_create_context, profile_decode_context)[source]¶
Create a profile from a label and a passphrase, and unlock it.
The profile is born
ProfileSetupState.INCOMPLETE: it is a real, writable record from this moment, and the operator completes it afterwards against a live profile rather than through a gated wizard.Recovery is not part of creation. A profile is born with its passphrase as its only door; the operator may enrol a recovery code afterwards through
enroll_profile_recovery(), and every surface that creates a profile offers that step as an explicit, skippable follow-up rather than a precondition.- Parameters:
label (
str) – Operator-chosen display name. Must be non-blank and must not collide with an existing profile’s label.passphrase (
str) – The credential protecting the bucket. Must satisfy the canonical profile-password contract; never logged, never echoed, and held only for the duration of the create span.facts (
tuple[UserProfileFact,...]) – Optional initial facts. Empty by default — the whole point of this door is that a profile needs no tax data to exist.profile_create_context (
ProfileCreateContext) – Schema context pinned for the new record.profile_decode_context (
ProfileDecodeContext) – Schema context pinned for the authenticated record session. It must share the authority generation withprofile_create_context.
- Return type:
The created profile is left unlocked for this process: its live bucket session and record authority are published exactly as a login publishes them. The operator has just chosen and proven this passphrase, so asking for it again before the profile can be used answers a question they have already answered.
- Return type:
- Returns:
A
ProfileRegistrationOutcomefor the newly-live profile.- Raises:
ProfileRegistrationError – When the label is blank or the passphrase does not satisfy the canonical profile-password contract.
ProfileRegistrationError – When the label is already bound.
ProfileSchemaValidationError – When an initial fact names an unknown or engine-derived path, or carries a value its field will not take. Missing filing fields are not refused: the profile is born incomplete on purpose.
- Parameters:
label (str)
passphrase (str)
facts (tuple[UserProfileFact, ...])
profile_create_context (ProfileCreateContext)
profile_decode_context (ProfileDecodeContext)