kcode-k1-groups-driver-testkit 0.1.0

Generic conformance assertions for the K1 groups driver
Documentation
# Driver conformance testkit

This library defines the generic adapter contract and fixed assertions for the K1 groups driver facade. It owns fixture identities and expected results, not a concrete adapter, driver, projection, persistence, KTO, Peering, callback, thread, retry, I/O, or framework.

## Public API

```rust
use kcode_k1_groups_domain::{
    Group, GroupId, GroupMemberships, GroupName, GroupRevision, GroupRole, ModelId, UserId,
};

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ConcurrencyObservation {
    pub both_submissions_completed: bool,
    pub revoked_actor_rejected: bool,
    pub final_role: Option<GroupRole>,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct MalformedObservation {
    pub canonical_callback_failed: bool,
    pub facade_unavailable: bool,
    pub fresh_replay_failed: bool,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ReorgObservation {
    pub old_facade_unavailable: bool,
    pub projection_cleared: bool,
    pub fresh_open_empty: bool,
}

pub trait DriverAdapter {
    fn create(&self, owner: UserId, name: GroupName) -> Result<GroupRevision, String>;
    fn rename(&self, actor: UserId, group: GroupId, name: GroupName) -> Result<GroupRevision, String>;
    fn set_user_role(&self, actor: UserId, group: GroupId, user: UserId, role: Option<GroupRole>) -> Result<GroupRevision, String>;
    fn set_model_membership(&self, actor: UserId, group: GroupId, model: ModelId, present: bool) -> Result<GroupRevision, String>;
    fn get(&self, group: GroupId) -> Result<Option<Group>, String>;
    fn groups_for_user(&self, user: UserId) -> Result<Vec<GroupId>, String>;
    fn groups_for_model(&self, model: ModelId) -> Result<Vec<GroupId>, String>;
    fn memberships(&self, user: UserId, model: ModelId) -> Result<GroupMemberships, String>;
    fn restart(&mut self) -> Result<(), String>;
    fn concurrency_observation(&mut self) -> Result<ConcurrencyObservation, String>;
    fn malformed_observation(&mut self) -> Result<MalformedObservation, String>;
    fn reorg_observation(&mut self) -> Result<ReorgObservation, String>;
}

pub fn user(index: usize) -> UserId;
pub fn model(index: usize) -> ModelId;
pub fn verify<A: DriverAdapter>(adapter: &mut A) -> Result<(), String>;
```

The domain types in these signatures are not reexported. The three observation structs implement exactly the five shown traits; their public fields are their complete value API.

Each mutation method performs one direct public-driver submission. An accepted submission returns the group's revision: Create returns a revision whose group identity is derived from its transaction identity; a state-changing submission returns a new revision for that group; and an authorized equal rename or model-membership submission returns the prior group revision. A rejected submission returns `Err` containing its exact semantic reason. Query methods return complete owned results without sorting or truncation. `restart` closes and reopens the adapter-owned facade and storage root, preserving valid projected state. A successful adapter `Result` means that one requested operation completed; operational error text has no stable value. The direct methods accept every value in their domain type, and no method calls back into this testkit.

`concurrency_observation` owns a complete fixture that submits two independent mutations and immediately revokes one actor in canonical order. Both submissions must complete, the revoked actor's later mutation must be rejected, and that actor's final role must be absent. `malformed_observation` injects one canonical invalid v2 callback, observes that callback fail, observes the facade fail closed, and proves that fresh replay fails. `reorg_observation` performs the fixture's canonical-horizon reorganization, observes the old facade become unavailable, observes projection clearing, and proves that fresh open and replay are empty. Each observation owns all private KTO, Peering, callback, synchronization, cleanup, and fresh-fixture mechanics and returns only after its complete noninteractive flow.

`user` and `model` accept every `usize` and encode its big-endian 64-bit value in the trailing eight bytes of otherwise-zero 12-byte and 32-byte identities, matching the projection test contract. They are deterministic constant-work, allocation-free wrappers with no I/O, locking, waiting, retry, timeout, or retained state. The managed-check `helpers_meet_reference_budget` canary requires 100,000 helper pairs to complete within five seconds in the hardened rootless Podman environment.

`verify` requires a fresh isolated adapter. It runs one sequential fixed scenario, compares every set-like result without relying on order, permits the membership cursor to advance after rejected or unchanged submissions while preserving ordinary group state and revision, restarts once, then runs the concurrency, reorganization, and malformed observations. It makes 37 adapter calls and performs local work linear in the complete returned values with only the two fixture-name allocations and error allocation on failure. It returns the first contextual mismatch or adapter diagnostic and never intentionally panics for an adapter or domain outcome. Adapter operations own their documented storage, synchronization, callback, and replay costs; this library adds no I/O, callback, thread, lock, retry, timeout, or background work. Exclusive access is held for the call, while all concurrency needed by an observation is adapter-owned and requires no caller-managed phase.