# Access-controlled K1 persons
`K1AccessPersons` is the stateless internal boundary for standalone Persons under one parent Access record. Raw `K1Persons` remains unchanged. Account-anchored Persons remain owned by Accounts/K1Users and need no Access record or migration.
## Public API
```rust
pub use kcode_k1_access::{AccessId, RequestPrincipal};
pub use kcode_k1_access_profiles::ProfileSelection;
pub use kcode_k1_persons::{PersonId, PersonView};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SubmittedPerson { pub access_id: AccessId, pub person_id: PersonId }
pub struct K1AccessPersons;
impl K1AccessPersons {
pub fn open(access: Arc<K1Access>, profiles: Arc<K1AccessProfiles>, persons: Arc<K1Persons>) -> Result<Self, String>;
pub fn create(&self, principal: RequestPrincipal, profile: ProfileSelection, name: String) -> Result<SubmittedPerson, String>;
pub fn read(&self, principal: RequestPrincipal, access_id: AccessId) -> Result<PersonView, String>;
pub fn read_person(&self, person_id: PersonId) -> Result<PersonView, String>;
pub fn update(&self, principal: RequestPrincipal, access_id: AccessId, name: String) -> Result<(), String>;
pub fn update_person(&self, principal: RequestPrincipal, person_id: PersonId, access_id: AccessId, name: String) -> Result<(), String>;
}
```
## Resource and authority model
`open` retains the supplied Access, Access Profiles, and Persons facades, constructs the fixed `k1-person` target subsystem, performs no I/O, and starts no worker.
`create` resolves exactly the supplied profile before any Person effect. Resolution creates a concrete authorization snapshot: this facade retains no `ProfileId` linkage. It preserves every resolved owner and viewer, adds universal human and model viewers (`ALL_USERS` and `ALL_MODELS`), normalizes the resulting `Authorizations`, then creates one raw Person and one Access target containing that PersonId's exact 12 transaction bytes. It returns both IDs only after Access creation. Profile failure is pre-effect; Access failure may leave an inaccessible raw-Person orphan, with no rollback or retry.
Every newly created Person Access is universally readable by human and model principals, but owners remain managers. `read` checks current view authority for its AccessId, decodes its target, and returns the coherent canonical Person. `read_person` is universal by PersonId and returns the same current canonical view without an Access check. `update` remains compatible: it requires current view and management, a valid target, and canonicality before one raw update. `update_person` additionally requires that its supplied AccessId currently authorizes both view and management in `k1-person`, targets exactly the supplied PersonId, and remains canonical before one raw update. A mismatched AccessId never mutates that Person.
`AccessId` is not a bearer credential: it is an external resource handle evaluated against the current request principal. `PersonId` is an identity reference, not authorization. Profile snapshots and dependency-owned User, Group, Model, and Access semantics retain their own contracts.
## Boundaries
There is no listing, directory, search, discovery, reverse lookup, HTTP, authentication, deletion, resolve/merge API, migration, provider, UI, deployment, or background work. Calls are synchronous. The facade owns no lock, retry, timeout, or finite dependency-latency bound.