# Access profiles facade
This library is the synchronous KTO and Peering facade for saved authorization profiles and built-in, saved, or inline profile resolution. Its logical subsystem is exactly `k1-profile-subsystem`.
## Public API
```rust
pub use kcode_k1_access_profile_types::{
AuthorizationProfile, Authorizations, GroupId, ModelId, OwnerSubject, ProfileId,
ProfileOwner, ProfileRevision, ProfileSelection, ProfileSource, ProfileViewer,
RequestPrincipal, ResolvedProfile, TxId, UserId, ViewerSubject,
};
pub use kcode_k1_access_profile_store::SavedProfile;
pub struct K1AccessProfiles;
impl K1AccessProfiles {
pub fn open(
root: &Path,
ordering: Arc<K1TxnOrdering>,
peering: Arc<K1Peering>,
) -> Result<Self, String>;
pub fn create(
&self,
owner: UserId,
profile: AuthorizationProfile,
) -> Result<ProfileRevision, String>;
pub fn replace(
&self,
actor: UserId,
profile_id: ProfileId,
profile: AuthorizationProfile,
) -> Result<ProfileRevision, String>;
pub fn delete(
&self,
actor: UserId,
profile_id: ProfileId,
) -> Result<ProfileRevision, String>;
pub fn get_for_user(
&self,
user: UserId,
profile_id: ProfileId,
) -> Result<Option<SavedProfile>, String>;
pub fn list_for_user(&self, user: UserId) -> Result<Vec<SavedProfile>, String>;
pub fn resolve(
&self,
principal: RequestPrincipal,
selection: ProfileSelection,
) -> Result<ResolvedProfile, String>;
}
```
All reexports are the exact profile-types or store identities and retain their complete constructors, accessors, implemented traits, normalization, canonical codec, and value semantics. `SavedProfile` exposes `profile_id()`, `owner()`, `revision()`, and `profile()`. The facade has no public fields.
## Resolution
`BuiltIn` delegates to profile-types built-in resolution. `Inline` resolves its template and returns source `Inline` without a saved revision. `Saved(id)` queries only rows owned by `principal.user`; absence and ownership mismatch return exactly `profile is unavailable`. A saved result resolves the stored template and returns source `Saved(id)` with its exact current revision. The returned concrete authorizations and revision are a snapshot unaffected by later replacement or deletion. Resolution never calls an Access creation operation.
## Mutation wire and reconciliation
Payload version 1 has no length field. Create is exactly `[1][1][operation_id:16][owner_user_txid:12][canonical_profile_bytes...]`. Replace is exactly `[1][2][operation_id:16][profile_id:12][actor_user_txid:12][canonical_profile_bytes...]`. Delete is exactly `[1][3][operation_id:16][profile_id:12][actor_user_txid:12]` and is 42 bytes. The header is at least two bytes. Create and Replace require their complete fixed prefix followed by nonempty bytes accepted as an exact canonical profile by the profile-types codec. Unknown versions or actions, truncation, malformed profiles, noncanonical profiles, and trailing bytes are rejected.
Every mutation obtains one fresh 16-byte operation ID from the OS CSPRNG, reserves its pending correlation before encoding, and calls Peering exactly once. There are no retries or timeouts. The facade reconciles the expected action, exact callback transaction ID, and store outcome. A recorded matching callback is authoritative even if Peering returns an error. Peering success without a matching callback faults the facade. `Applied` and `Unchanged` return their revision. `Rejected(message)` returns that exact message as `Err`.
Release conformance, including wire and reconciliation fixtures, is owned by `kcode-k1-access-profiles-testkit`.
## Persistence and recovery
`open` opens the profile store with the supplied live ordering instance, obtains its durable cursor, and then registers `k1-profile-subsystem` after that cursor. Replay and live callbacks parse each payload once and call store apply once. A reorganization first invalidates the facade and all pending correlations, then clears the derived store. Callback parsing failure, callback contradiction, store failure, and query failure fault the facade. Reopen is required after a fault. The store owns durable state and its documented recovery behavior.
## Concurrency and performance
A facade-owned mutex protects only the fault marker and pending-correlation map. It is held only for brief reserve, record, removal, or invalidation transitions and never across randomness, encoding, Peering, KTO callbacks, store work, queries, or waiting. Store mutation serialization and KTO callback ordering remain inside their respective resource owners. Queries use the store's independent read paths. Concurrent unrelated subsystems and stores require no caller coordination, and a blocked dependency operation does not hold a facade lock or stall unrelated resources.
There is no facade queue, admission cap, retry, timeout, polling, worker, or background task. Public operations process complete inputs and outputs without arbitrary caps. Facade-owned mutation work and allocation are linear only in profile payload bytes, with fixed work for Delete. Resolution work is linear in the selected template and concrete output. List work is linear in its complete output. OS entropy, allocation, filesystem, SQLite, Peering, KTO serialization, callback-lane waits, and dependency work have no finite latency bound.
## Exclusions
The facade performs no HTTP, authentication, Access operation, group mutation, authority decision, deployment, or propagation policy. User, actor, and principal values are trusted authenticated evidence supplied by the caller. Profile IDs and revisions are evidence rather than authority.