kcode-k1-access 0.3.0

K1 access Groups-aware authorization facade
Documentation
# K1 access

`kcode-k1-access` is the synchronous, Groups-aware facade for the logical KTO subsystem `k1-access-subsystem`. `K1AccessDriver` owns the transaction submission, callback correlation, projection, discovery storage, and availability lifecycle. This facade owns only the Groups calls required to supply membership evidence to that driver.

## Public API

```rust
use std::{path::Path, sync::Arc};
use kcode_k1_access::{
    AccessCheck, AccessId, AccessRevision, Authorizations, GroupId, K1Access, ModelId,
    OwnerSubject, RequestPrincipal, SubsystemId, Target, TxId, UserId, ViewerSubject,
};
use kcode_k1_groups::K1Groups;
use kcode_k1_peering::K1Peering;
use kcode_k1_txn_ordering::K1TxnOrdering;

impl K1Access {
    pub fn open(
        root: &Path,
        ordering: Arc<K1TxnOrdering>,
        peering: Arc<K1Peering>,
        groups: Arc<K1Groups>,
    ) -> Result<Self, String>;
    pub fn create(
        &self,
        target: Target,
        authorizations: Authorizations,
    ) -> Result<AccessRevision, String>;
    pub fn set_authorizations(
        &self,
        principal: RequestPrincipal,
        access_id: AccessId,
        authorizations: Authorizations,
    ) -> Result<AccessRevision, String>;
    pub fn check(
        &self,
        principal: RequestPrincipal,
        access_id: AccessId,
        expected_subsystem: SubsystemId,
    ) -> Result<AccessCheck, String>;
    pub fn list_user(
        &self,
        principal: RequestPrincipal,
        expected_subsystem: SubsystemId,
    ) -> Result<Vec<AccessId>, String>;
    pub fn list_group(
        &self,
        principal: RequestPrincipal,
        group: GroupId,
        expected_subsystem: SubsystemId,
    ) -> Result<Vec<AccessId>, String>;
}
```

The facade reexports the complete consumer type contract from `kcode-k1-access-types`, including `SubsystemId`. `open` delegates to the driver, and `create` passes the supplied target and normalized authorizations to it without grants or defaults.

## Authority and discovery

`set_authorizations` calls `K1Groups::memberships` exactly once. It passes the returned human groups to `K1AccessDriver::owner_witness`; model membership never supplies management authority. A missing witness returns `principal is not an access owner`. The driver receives the principal user as actor, the Groups revision, that witness, and the requested authorizations.

`check` first calls `discovery_missing`. A missing discovery record causes exactly one `ensure_discovery` call, which must succeed before the facade calls Groups once and delegates the check with that coherent membership snapshot. Unknown IDs and IDs in another subsystem report no missing discovery and cause no ensure. Discovery is a transaction-backed monotonic stale derived index, not authority: it is only added by the ordinary Access transaction flow and does not grant access. Driver reorganization clears its projection and invalidates the driver.

`list_user` derives the principal user and delegates directly. `list_group` calls `groups_for_user` exactly once, requires the requested group in that result, including `ALL_USERS` when Groups returns it, and otherwise returns `access denied`. It does not read model membership, aggregate groups, perform per-ID checks, or copy group results into personal discovery.

## Ordering, errors, concurrency, and performance

The driver opens and registers the Access callback after its durable projection cursor. It owns operation IDs, encoding, one submission, exact callback correlation, projection faults, reorganization handling, and mutation/query errors. Its documented transaction and callback failure contract applies unchanged; recovery after driver unavailability requires a fresh `open`.

Groups failures are returned without changing driver state. There is no facade lock, retry, timeout, worker, queue, polling, background recovery, authentication, HTTP surface, deployment behavior, or live behavior. The facade performs one Groups membership query for `set_authorizations` and a successful `check`, one Groups reverse query for `list_group`, and no Groups query for `create` or `list_user`. The driver and Groups scheduling have no finite wall-clock bound.