Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/gunnar

crates/gunnar-server/tests/enterprise.rs

//! **The owner's enterprise list, end to end over the REAL plane and stores**
//! (2026-10-05): the account admin's audit log, the operator's aggregates
//! (and nothing else) unless the account admin approves a look, and the name
//! filter — driven through the gRPC services exactly as the console and the
//! CLI reach them, with a real P-256 passkey for every login (the identity
//! core's, IDENTITY-HOST) and an approver's core session that stepped up.

use std::sync::Arc;

use gunnar_grpc::auth::PersonSession;
use gunnar_grpc::{
    AccessService, AccountsService, Caller, ClansService, ControlPlane, EnterpriseService,
    EventBus, ReposService, ServerConfig, ServiceContext,
};
use gunnar_proto::access_server::Access as _;
use gunnar_proto::accounts_server::Accounts as _;
use gunnar_proto::clans_server::Clans as _;
use gunnar_proto::enterprise_server::Enterprise as _;
use gunnar_proto::repos_server::Repos as _;
use gunnar_proto::*;
use gunnar_server::control_plane::CoreControlPlane;
use gunnar_server::stores::ServerStores;
use p256::ecdsa::signature::Signer as _;
use tonic::{Code, Request};

const RP_ID: &str = "console.example";
const ORIGIN: &str = "https://console.example";

fn person(id: &str) -> Caller {
    Caller {
        principal_id: id.to_owned(),
        fingerprint: format!("SHA256:{id}"),
        machine: false,
        authenticated: true,
    }
}

fn machine(id: &str) -> Caller {
    Caller {
        machine: true,
        ..person(id)
    }
}

fn authed<T>(caller: &Caller, body: T) -> Request<T> {
    let mut r = Request::new(body);
    r.extensions_mut().insert(caller.clone());
    r
}

fn unhex(text: &str) -> Vec<u8> {
    (0..text.len())
        .step_by(2)
        .map(|i| u8::from_str_radix(&text[i..i + 2], 16).unwrap())
        .collect()
}

fn unb64(text: &str) -> Vec<u8> {
    gunnar_grpc::webauthn::from_b64url(text).expect("base64url")
}

/// A call from `caller`'s core session, stepped up (a fresh user-verified touch).
fn stepped<T>(caller: &Caller, body: T) -> Request<T> {
    let mut r = authed(caller, body);
    r.extensions_mut().insert(PersonSession {
        stepped_up: true,
        stepped_up_at_unix_ms: None,
    });
    r
}

fn sha256(bytes: &[u8]) -> Vec<u8> {
    unhex(&gunnar_grpc::webauthn::sha256_hex(bytes))
}

/// One authenticator: a P-256 key, its id and its counter.
struct Passkey {
    key: p256::ecdsa::SigningKey,
    id: Vec<u8>,
    counter: std::cell::Cell<u32>,
}

impl Passkey {
    fn new(seed: u8, id: &str) -> Passkey {
        Passkey {
            key: p256::ecdsa::SigningKey::from_slice(&[seed; 32]).expect("a scalar"),
            id: id.as_bytes().to_vec(),
            counter: std::cell::Cell::new(0),
        }
    }

    fn public(&self) -> Vec<u8> {
        self.key
            .verifying_key()
            .to_sec1_point(false)
            .as_bytes()
            .to_vec()
    }

    /// What a browser hands back for `navigator.credentials.get` over
    /// `challenge`: (clientDataJSON, authenticatorData, signature), user
    /// present and verified, the counter moved.
    fn get(&self, challenge: &[u8]) -> (Vec<u8>, Vec<u8>, Vec<u8>) {
        self.counter.set(self.counter.get() + 1);
        let client_data = format!(
            r#"{{"type":"webauthn.get","challenge":"{}","origin":"{ORIGIN}","crossOrigin":false}}"#,
            gunnar_grpc::webauthn::b64url(challenge)
        )
        .into_bytes();
        let mut auth_data = sha256(RP_ID.as_bytes());
        auth_data.push(0x01 | 0x04);
        auth_data.extend_from_slice(&self.counter.get().to_be_bytes());
        let mut message = auth_data.clone();
        message.extend_from_slice(&sha256(&client_data));
        let signature: p256::ecdsa::Signature = self.key.sign(&message);
        (
            client_data,
            auth_data,
            signature.to_der().as_bytes().to_vec(),
        )
    }
}

struct World {
    _dir: tempfile::TempDir,
    stores: Arc<ServerStores>,
    plane: Arc<CoreControlPlane>,
    ctx: ServiceContext,
    identity: Arc<gunnar_grpc::identity::GunnarIdentity>,
    relay: Caller,
    op: Caller,
    acme: Caller,
    bob: Caller,
    acme_key: Passkey,
    bob_key: Passkey,
}

/// The estate: `op` the operator (a person, server Admin) with its own
/// account and repository; `nordisk` a namespace nobody owns (the operator's
/// forge); `acme` a customer with a private `site`, a public `www` and an
/// employee `bob`; the console's relay `gunnar-ui`.
fn world() -> World {
    let dir = tempfile::tempdir().expect("tempdir");
    let stores = Arc::new(ServerStores::open(dir.path()).expect("stores"));
    let plane = Arc::new(CoreControlPlane::new(Arc::clone(&stores)));
    let control: Arc<dyn ControlPlane> = plane.clone();
    let identity = gunnar_server::identity::build(
        dir.path(),
        Arc::clone(&control),
        &ServerConfig::default(),
        false,
    );
    let ctx = ServiceContext::new(
        control,
        Arc::new(EventBus::new(64)),
        ServerConfig::default(),
    )
    .with_identity(Arc::clone(&identity));
    plane
        .add_principal("gunnar-ui", "gunnar-ui", PrincipalKind::Machine)
        .expect("relay");
    plane
        .grant("gunnar-ui", "", "", GrantLevel::Admin)
        .expect("the relay is a server admin");
    plane
        .add_principal("op", "op", PrincipalKind::User)
        .expect("the operator");
    plane
        .grant("op", "", "", GrantLevel::Admin)
        .expect("the operator is a server admin");
    plane
        .add_principal("acme", "acme", PrincipalKind::User)
        .expect("a customer");
    let w = World {
        _dir: dir,
        stores,
        plane,
        ctx,
        identity,
        relay: machine("gunnar-ui"),
        op: person("op"),
        acme: person("acme"),
        bob: person("bob"),
        acme_key: Passkey::new(11, "acme-yubikey"),
        bob_key: Passkey::new(12, "bob-yubikey"),
    };
    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();
    rt.block_on(async {
        w.create(&w.op, "op", "notes", Visibility::Private)
            .await
            .expect("the operator's own repository");
        w.repos()
            .create_namespace(authed(
                &w.op,
                CreateNamespaceRequest {
                    name: "nordisk".into(),
                    description: String::new(),
                },
            ))
            .await
            .expect("the operator's forge namespace");
        w.create(&w.op, "nordisk", "gunnar", Visibility::Private)
            .await
            .expect("nordisk/gunnar");
        w.create(&w.acme, "acme", "site", Visibility::Private)
            .await
            .expect("acme/site");
        w.create(&w.acme, "acme", "www", Visibility::Public)
            .await
            .expect("acme/www");
        w.accounts()
            .enroll_employee(authed(
                &w.acme,
                EnrollEmployeeRequest {
                    account: "acme".into(),
                    id: "bob".into(),
                    name: "Bob".into(),
                    ..Default::default()
                },
            ))
            .await
            .expect("acme enrolls bob");
    });
    w.plane
        .add_credential(
            "acme",
            &w.acme_key.id,
            &w.acme_key.public(),
            "acme's YubiKey",
            0,
        )
        .expect("acme's passkey");
    w.plane
        .add_credential(
            "bob",
            &w.bob_key.id,
            &w.bob_key.public(),
            "bob's YubiKey",
            0,
        )
        .expect("bob's passkey");
    w
}

impl World {
    fn repos(&self) -> ReposService {
        ReposService::new(self.ctx.clone())
    }
    fn accounts(&self) -> AccountsService {
        AccountsService::new(self.ctx.clone())
    }
    fn access(&self) -> AccessService {
        AccessService::new(self.ctx.clone())
    }
    fn enterprise(&self) -> EnterpriseService {
        EnterpriseService::new(self.ctx.clone())
    }
    fn clans(&self) -> ClansService {
        ClansService::new(self.ctx.clone())
    }

    async fn log_of(&self, who: &Caller, account: &str) -> Result<AuditLogResponse, tonic::Status> {
        self.enterprise()
            .audit_log(authed(
                who,
                AuditLogRequest {
                    account: account.into(),
                    filter: None,
                    page_size: 200,
                    before_seq: None,
                },
            ))
            .await
            .map(|r| r.into_inner())
    }

    async fn create(
        &self,
        who: &Caller,
        ns: &str,
        repo: &str,
        visibility: Visibility,
    ) -> Result<Repo, tonic::Status> {
        self.repos()
            .create(authed(
                who,
                CreateRepoRequest {
                    path: Some(RepoPath::new(ns, repo)),
                    visibility: visibility as i32,
                    ..Default::default()
                },
            ))
            .await
            .map(|r| r.into_inner().repo.expect("a repo"))
    }

    /// A machine's creation challenge, relayed.
    async fn challenge(&self) -> Vec<u8> {
        self.access()
            .machine_challenge(authed(&self.relay, MachineChallengeRequest::default()))
            .await
            .expect("the relay gets a challenge")
            .into_inner()
            .challenge
    }

    /// A passkey login through the identity core, as the console relays it.
    fn login(&self, key: &Passkey) -> Result<nornir_identity::LoggedIn, nornir_identity::Refused> {
        let c = self.identity.login_start(&nornir_identity::Relay {
            rp_id: RP_ID.into(),
            origin: ORIGIN.into(),
            client: None,
        })?;
        let challenge = unb64(&c.challenge);
        let (client_data_json, authenticator_data, signature) = key.get(&challenge);
        self.identity.login_finish(nornir_identity::Assertion {
            ceremony_id: c.id,
            credential_id: key.id.clone(),
            client_data_json,
            authenticator_data,
            signature,
            rp_id: RP_ID.into(),
            origin: ORIGIN.into(),
        })
    }

    async fn log(&self, who: &Caller, kinds: &[&str]) -> Result<AuditLogResponse, tonic::Status> {
        self.enterprise()
            .audit_log(authed(
                who,
                AuditLogRequest {
                    account: "acme".into(),
                    filter: Some(AuditFilter {
                        kinds: kinds.iter().map(|k| k.to_string()).collect(),
                        ..Default::default()
                    }),
                    page_size: 200,
                    before_seq: None,
                },
            ))
            .await
            .map(|r| r.into_inner())
    }

    async fn listed(&self, who: &Caller, namespace: &str) -> Vec<String> {
        let mut names: Vec<String> = self
            .repos()
            .list(authed(
                who,
                ListReposRequest {
                    namespace: namespace.into(),
                    ..Default::default()
                },
            ))
            .await
            .expect("a listing")
            .into_inner()
            .repos
            .into_iter()
            .filter_map(|r| r.path.map(|p| format!("{}/{}", p.namespace, p.repo)))
            .collect();
        names.sort();
        names
    }

    async fn get(&self, who: &Caller, ns: &str, repo: &str) -> Result<Repo, tonic::Status> {
        self.repos()
            .get(authed(
                who,
                GetRepoRequest {
                    path: Some(RepoPath::new(ns, repo)),
                },
            ))
            .await
            .map(|r| r.into_inner().repo.expect("a repo"))
    }
}

fn kinds(log: &AuditLogResponse) -> Vec<String> {
    log.entries
        .iter()
        .map(|e| format!("{}:{}:{}", e.kind, e.actor_role, e.outcome))
        .collect()
}

// ── 1. the audit log ────────────────────────────────────────────────────────

/// ★ **Everything security-relevant in the account is in its log, read by
/// its admin and nobody else**: logins (and a refused one), the member added,
/// the invite, the visibility a member tried and the admin made, the
/// repositories — hash-chained, newest first, filtered, and exported.
#[tokio::test(flavor = "multi_thread")]
async fn the_account_admin_reads_every_security_event_and_nobody_else_does() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    w.login(&w.bob_key).expect("bob logs in");
    // A refused login: a replayed counter.
    w.bob_key.counter.set(0);
    assert!(
        w.login(&w.bob_key).is_err(),
        "a counter that went back is refused"
    );
    let acme = w
        .identity
        .vouched_session("acme", true)
        .expect("acme's session")
        .token;
    w.identity
        .invite(
            &acme,
            nornir_identity::InviteAsk {
                person: Some("bob".into()),
                ..Default::default()
            },
        )
        .expect("acme invites bob to another device");
    let refused = w
        .repos()
        .set_visibility(authed(
            &w.bob,
            SetVisibilityRequest {
                path: Some(RepoPath::new("acme", "site")),
                visibility: Visibility::Public as i32,
            },
        ))
        .await
        .expect_err("a member may not make a repository public");
    assert_eq!(refused.code(), Code::PermissionDenied);
    w.repos()
        .set_visibility(authed(
            &w.acme,
            SetVisibilityRequest {
                path: Some(RepoPath::new("acme", "site")),
                visibility: Visibility::Public as i32,
            },
        ))
        .await
        .expect("the account admin may");

    let log = w.log(&w.acme, &[]).await.expect("the admin reads the log");
    let seen = kinds(&log);
    for want in [
        "repo.created:admin:ok",
        "member.added:admin:ok",
        "login:member:ok",
        "invite.created:admin:ok",
        "visibility.changed:member:refused",
        "visibility.changed:admin:ok",
    ] {
        assert!(
            seen.iter().any(|s| s == want),
            "{want} is not in the log: {seen:#?}"
        );
    }
    // The refused login names bob (nornir-identity 0.2.1), so bob's account has it again, as
    // the old Access.WebLogin wrote it.
    assert!(
        seen.iter().any(|s| s == "login:member:refused"),
        "the refused login is not in the log: {seen:#?}"
    );
    let refused = log
        .entries
        .iter()
        .find(|e| e.kind == "login" && e.outcome == "refused")
        .unwrap();
    assert_eq!(
        (refused.actor.as_str(), refused.target.as_str()),
        ("bob", "passkey"),
        "{refused:?}"
    );
    assert!(
        !seen.iter().any(|s| s.starts_with("repo.created:operator")),
        "the operator's own repositories are not acme's: {seen:#?}"
    );
    assert_eq!(
        log.entries.first().map(|e| e.kind.as_str()),
        Some("visibility.changed"),
        "newest first"
    );
    let chain = log
        .chain
        .as_ref()
        .expect("the first page says whether the chain holds");
    assert!(chain.holds, "{chain:?}");
    assert_eq!(chain.tip_hash, log.entries[0].hash);
    assert_eq!(log.retention_days, 365, "a year by default");
    let made_public = log
        .entries
        .iter()
        .find(|e| e.kind == "visibility.changed" && e.outcome == "ok")
        .unwrap();
    assert_eq!(made_public.detail, "private → public");
    assert_eq!(made_public.target, "acme/site");

    // Filtered: the visibility family only.
    let vis = w.log(&w.acme, &["visibility"]).await.unwrap();
    assert_eq!(vis.entries.len(), 2, "{:#?}", kinds(&vis));

    // Nobody else reads it: not the member, not the operator.
    for who in [&w.bob, &w.op] {
        let err = w
            .log(who, &[])
            .await
            .expect_err("only the account's admins");
        assert_eq!(
            err.code(),
            Code::PermissionDenied,
            "{}: {err:?}",
            who.principal_id
        );
        assert!(err.message().contains("account admin"), "{}", err.message());
    }

    // Exported, and the export is itself in the log.
    let csv = w
        .enterprise()
        .export_audit_log(authed(
            &w.acme,
            ExportAuditLogRequest {
                account: "acme".into(),
                format: AuditExportFormat::Csv as i32,
                ..Default::default()
            },
        ))
        .await
        .expect("a CSV")
        .into_inner();
    let text = String::from_utf8(csv.body).unwrap();
    assert!(
        text.starts_with("seq,at_utc,kind,actor,actor_role,target,detail,outcome,hash\n"),
        "{text}"
    );
    assert_eq!(csv.entries as usize, log.entries.len());
    assert!(
        csv.file_name.starts_with("audit-acme-") && csv.file_name.ends_with(".csv"),
        "{}",
        csv.file_name
    );
    let json = w
        .enterprise()
        .export_audit_log(authed(
            &w.acme,
            ExportAuditLogRequest {
                account: "acme".into(),
                format: AuditExportFormat::Json as i32,
                ..Default::default()
            },
        ))
        .await
        .expect("JSON")
        .into_inner();
    assert_eq!(json.content_type, "application/json");
    let after = w.log(&w.acme, &["audit"]).await.unwrap();
    assert_eq!(
        after.entries.len(),
        2,
        "both exports are entries: {:#?}",
        kinds(&after)
    );
    let err = w
        .enterprise()
        .export_audit_log(authed(
            &w.op,
            ExportAuditLogRequest {
                account: "acme".into(),
                ..Default::default()
            },
        ))
        .await
        .expect_err("the operator exports nothing");
    assert_eq!(err.code(), Code::PermissionDenied);
}

// ── 2. the operator sees aggregates only ───────────────────────────────────

/// ★ **The operator principal gets totals, never names**: its listings skip
/// what is inside a customer's account (a public repository excepted, as for
/// any outsider), a named read is refused, and so is every act of the account
/// admin's — while `Aggregates` counts all of it.
#[tokio::test(flavor = "multi_thread")]
async fn the_operator_principal_gets_aggregates_only() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    assert_eq!(
        w.listed(&w.op, "").await,
        vec!["acme/www", "nordisk/gunnar", "op/notes"],
        "the operator's listing: its own, the forge's, and acme's PUBLIC repository only"
    );
    assert!(
        w.listed(&w.acme, "")
            .await
            .contains(&"acme/site".to_owned()),
        "acme sees its own"
    );
    assert_eq!(
        w.listed(&w.op, "acme").await,
        vec!["acme/www"],
        "inside acme: the public subset"
    );
    let err = w
        .get(&w.op, "acme", "site")
        .await
        .expect_err("a private repository by name");
    assert_eq!(err.code(), Code::PermissionDenied);
    w.get(&w.op, "nordisk", "gunnar")
        .await
        .expect("the operator's own forge is the operator's");

    let principals: Vec<String> = w
        .access()
        .list_principals(authed(&w.op, ListPrincipalsRequest::default()))
        .await
        .expect("the operator lists principals")
        .into_inner()
        .principals
        .into_iter()
        .map(|p| p.id)
        .collect();
    assert!(
        principals.contains(&"acme".to_owned()),
        "an account's own name is how the operator addresses it"
    );
    assert!(
        !principals.contains(&"bob".to_owned()),
        "a member's name is not the operator's: {principals:?}"
    );
    let creds = w
        .access()
        .list_credentials(authed(&w.op, ListCredentialsRequest::default()))
        .await
        .expect("credentials")
        .into_inner()
        .credentials;
    assert!(
        creds
            .iter()
            .all(|c| c.principal_id != "bob" && !c.label.contains("bob")),
        "a member's passkey names nobody: {creds:?}"
    );
    assert!(
        creds.iter().any(|c| c.principal_id == "acme"),
        "the account's own person is how it is recovered: {creds:?}"
    );
    assert_eq!(
        creds.len(),
        2,
        "every passkey is still offered at login, a member's by id alone: {creds:?}"
    );

    let err = w
        .accounts()
        .list_employees(authed(
            &w.op,
            ListEmployeesRequest {
                account: "acme".into(),
            },
        ))
        .await
        .expect_err("the members of acme");
    assert_eq!(err.code(), Code::PermissionDenied);
    let err = w
        .repos()
        .set_visibility(authed(
            &w.op,
            SetVisibilityRequest {
                path: Some(RepoPath::new("acme", "site")),
                visibility: Visibility::Public as i32,
            },
        ))
        .await
        .expect_err("only the account admin makes things public — the operator neither");
    assert_eq!(err.code(), Code::PermissionDenied);
    assert!(err.message().contains("account admin"), "{}", err.message());
    let err = w
        .create(&w.op, "acme", "planted", Visibility::Private)
        .await
        .expect_err("nor creates inside");
    assert_eq!(err.code(), Code::PermissionDenied);

    let totals = w
        .enterprise()
        .aggregates(authed(&w.op, AggregatesRequest {}))
        .await
        .expect("the operator's totals")
        .into_inner();
    assert_eq!(
        totals.accounts, 2,
        "acme and the operator's own: {totals:?}"
    );
    assert_eq!(totals.enterprise_accounts, 1);
    assert_eq!(totals.members, 1);
    assert_eq!(
        totals.repos, 4,
        "the whole estate: acme's two, op/notes and the forge's nordisk/gunnar: {totals:?}"
    );
    assert_eq!(totals.public_repos, 1);
    assert_eq!(
        totals.operator_repos, 1,
        "nordisk/gunnar, the operator's share of the four"
    );
    assert_eq!(
        totals.health == "ok",
        totals.health_alarms == 0,
        "{totals:?}"
    );
    let err = w
        .enterprise()
        .aggregates(authed(&w.bob, AggregatesRequest {}))
        .await
        .expect_err("a member is no operator");
    assert_eq!(err.code(), Code::PermissionDenied);
}

/// ★ **The totals are the WHOLE estate's** (round 5.3; the owner on test2
/// 2026-10-08: "Repositories 0 (0 public) · Storage used 0 B · Room held —"
/// over seven repositories, ~205 MB, in the operator's `nordisk`, a namespace
/// no account owns). A public repository there and a pack pushed into it move
/// the repositories, the public count and the storage used — numbers, never
/// names — and `operator_repos` stays the operator's share of `repos`.
#[tokio::test(flavor = "multi_thread")]
async fn the_totals_count_the_whole_estate_the_operators_own_namespaces_too() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    w.create(&w.op, "nordisk", "site", Visibility::Public)
        .await
        .expect("a public repository in the operator's forge");
    // About 256 KiB of pack into nordisk/gunnar, and the namespace's own
    // measure once its indexes have landed (three equal readings in a row).
    let path = gunnar_core::RepoRef::new("nordisk", "gunnar").expect("legal");
    let stored = tokio::task::spawn_blocking({
        let (stores, plane) = (Arc::clone(&w.stores), Arc::clone(&w.plane));
        move || {
            let repo = stores
                .catalog()
                .get(&path)
                .expect("read")
                .expect("nordisk/gunnar exists");
            let handle = stores.repo_store(&repo).expect("open");
            let mut pb = gunnar_store::conformance::pack::PackBuilder::new(handle.hash_kind());
            pb.object(gix_object::Kind::Blob, vec![b'n'; 256 << 10]);
            handle
                .serve()
                .put_pack(&pb.build().expect("pack").bytes)
                .expect("put_pack");
            drop(handle);
            stores.close_repo(&path);
            let read = || {
                let row = &plane.usage(Some("nordisk")).expect("usage")[0];
                row.pack_bytes.saturating_add(row.lfs_bytes)
            };
            let (mut last, mut same) = (read(), 0);
            for _ in 0..100 {
                std::thread::sleep(std::time::Duration::from_millis(300));
                let now = read();
                same = if now == last { same + 1 } else { 0 };
                last = now;
                if same >= 3 {
                    break;
                }
            }
            last
        }
    })
    .await
    .unwrap();
    assert!(stored > 0, "the pack is measured in nordisk");

    let totals = w
        .enterprise()
        .aggregates(authed(&w.op, AggregatesRequest {}))
        .await
        .expect("the operator's totals")
        .into_inner();
    assert_eq!(
        totals.repos, 5,
        "acme's two, op/notes, nordisk/gunnar and nordisk/site: {totals:?}"
    );
    assert_eq!(
        totals.public_repos, 2,
        "acme/www and nordisk/site: {totals:?}"
    );
    assert_eq!(
        totals.operator_repos, 2,
        "nordisk's two, already inside the five: {totals:?}"
    );
    assert!(
        totals.stored_bytes >= stored,
        "the storage used leaves the operator's forge out: {} < {stored} in nordisk alone",
        totals.stored_bytes
    );
    let everything: u64 = w
        .plane
        .usage(None)
        .expect("every namespace's usage")
        .iter()
        .map(|r| r.pack_bytes.saturating_add(r.lfs_bytes))
        .sum();
    assert_eq!(
        totals.stored_bytes, everything,
        "the storage used is every namespace's, pack and LFS"
    );
    assert_eq!(
        totals.accounts, 2,
        "accounts are still people: acme and the operator's own, never the forge"
    );
}

// ── 2b. the look the account admin grants ──────────────────────────────────

/// ★ **An explicit, time-limited, audited grant through the Approve flow**:
/// the operator asks; the account admin approves with a fresh step-up of
/// THEIR OWN passkey and the request's code; the operator reads (never
/// writes) until the admin ends it; every step is in the account's log.
#[tokio::test(flavor = "multi_thread")]
async fn the_account_admin_approves_a_look_with_a_step_up_and_ends_it() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let asked = w
        .enterprise()
        .request_operator_access(authed(
            &w.op,
            RequestOperatorAccessRequest {
                account: "acme".into(),
                reason: "ticket 4711: a push hangs".into(),
                minutes: 30,
            },
        ))
        .await
        .expect("the operator asks")
        .into_inner()
        .request
        .unwrap();
    assert_eq!(asked.state, OperatorAccessState::Pending as i32);
    assert!(
        w.get(&w.op, "acme", "site").await.is_err(),
        "asking is not having"
    );
    let err = w
        .enterprise()
        .request_operator_access(authed(
            &w.bob,
            RequestOperatorAccessRequest {
                account: "acme".into(),
                reason: "x".into(),
                minutes: 30,
            },
        ))
        .await
        .expect_err("only an operator asks");
    assert_eq!(err.code(), Code::PermissionDenied);

    let pending = w
        .enterprise()
        .list_operator_access(authed(
            &w.acme,
            ListOperatorAccessRequest {
                account: "acme".into(),
            },
        ))
        .await
        .expect("acme sees the request")
        .into_inner()
        .requests;
    assert_eq!(pending.len(), 1);
    assert_eq!(pending[0].reason, "ticket 4711: a push hangs");

    let approve = |who: &Caller, code: &str, fresh: bool| {
        let body = ApproveOperatorAccessRequest {
            request_id: asked.request_id.clone(),
            code: code.into(),
            minutes: 0,
        };
        if fresh {
            stepped(who, body)
        } else {
            authed(who, body)
        }
    };
    let err = w
        .enterprise()
        .approve_operator_access(approve(&w.acme, &asked.code, false))
        .await
        .expect_err("no step-up");
    assert_eq!(err.code(), Code::PermissionDenied, "{err:?}");
    assert!(err.message().contains("[stepup]"), "{err:?}");
    let err = w
        .enterprise()
        .approve_operator_access(approve(&w.acme, "XXX-000", true))
        .await
        .expect_err("the wrong code");
    assert_eq!(err.code(), Code::FailedPrecondition, "{err:?}");
    let err = w
        .enterprise()
        .approve_operator_access(approve(&w.bob, &asked.code, true))
        .await
        .expect_err("a member decides nothing");
    assert_eq!(err.code(), Code::PermissionDenied, "{err:?}");
    let err = w
        .enterprise()
        .approve_operator_access(approve(&w.op, &asked.code, true))
        .await
        .expect_err("nor the operator itself");
    assert_eq!(err.code(), Code::PermissionDenied, "{err:?}");

    let approved = w
        .enterprise()
        .approve_operator_access(approve(&w.acme, &asked.code, true))
        .await
        .expect("acme approves")
        .into_inner()
        .request
        .unwrap();
    assert_eq!(approved.state, OperatorAccessState::Approved as i32);
    assert!(approved.granted_until_unix_ms > gunnar_core::now_ms() + 25 * 60_000);
    let err = w
        .enterprise()
        .approve_operator_access(approve(&w.acme, &asked.code, true))
        .await
        .expect_err("decided");
    assert_ne!(err.code(), Code::Ok);

    // The look: reads, never writes, never the log.
    w.get(&w.op, "acme", "site")
        .await
        .expect("the approved look reads");
    assert!(w.listed(&w.op, "").await.contains(&"acme/site".to_owned()));
    let err = w
        .repos()
        .set_visibility(authed(
            &w.op,
            SetVisibilityRequest {
                path: Some(RepoPath::new("acme", "site")),
                visibility: Visibility::Public as i32,
            },
        ))
        .await
        .expect_err("a look writes nothing");
    assert_eq!(err.code(), Code::PermissionDenied);
    assert_eq!(
        w.log(&w.op, &[])
            .await
            .expect_err("the log stays the admins'")
            .code(),
        Code::PermissionDenied
    );

    let ended = w
        .enterprise()
        .revoke_operator_access(authed(
            &w.acme,
            RevokeOperatorAccessRequest {
                request_id: asked.request_id.clone(),
            },
        ))
        .await
        .expect("acme ends it")
        .into_inner()
        .request
        .unwrap();
    assert_eq!(ended.state, OperatorAccessState::Revoked as i32);
    assert!(w.get(&w.op, "acme", "site").await.is_err(), "ended");

    let log = w.log(&w.acme, &["operator_access"]).await.unwrap();
    assert_eq!(
        kinds(&log),
        vec![
            "operator_access.revoked:admin:ok",
            "operator_access.approved:admin:ok",
            "operator_access.requested:operator:ok"
        ],
    );
    assert!(
        log.entries[2].detail.contains("ticket 4711"),
        "{:?}",
        log.entries[2]
    );
}

// ── 3. the name filter ──────────────────────────────────────────────────────

/// ★ **An offensive name is refused with a sentence and the account admin is
/// told; a borderline one waits for the account admin — not the operator —
/// and passes once allowed; reserved names are not a person's; the lists are
/// gunnar's configuration.**
#[tokio::test(flavor = "multi_thread")]
async fn a_name_the_filter_stops_is_refused_held_or_allowed_by_the_account_admin() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let err = w
        .create(&w.acme, "acme", "fuck-this", Visibility::Private)
        .await
        .expect_err("an offensive name");
    assert_eq!(err.code(), Code::InvalidArgument);
    assert!(
        err.message().contains("refused")
            && err.message().to_lowercase().contains("choose another name"),
        "{}",
        err.message()
    );
    assert!(
        !err.message()
            .to_lowercase()
            .contains("contains a word \"fuck"),
        "the word is not repeated back"
    );
    assert!(
        w.get(&w.acme, "acme", "fuck-this").await.is_err(),
        "nothing was made"
    );
    let err = w
        .create(&w.acme, "acme", "sh1t_h3ad", Visibility::Private)
        .await
        .expect_err("leet");
    assert_eq!(err.code(), Code::InvalidArgument);

    let err = w
        .create(&w.acme, "acme", "porn-filter", Visibility::Private)
        .await
        .expect_err("held");
    assert_eq!(err.code(), Code::FailedPrecondition);
    assert!(
        err.message().contains("account admin's review"),
        "{}",
        err.message()
    );
    let queue = w
        .enterprise()
        .list_name_reviews(authed(
            &w.acme,
            ListNameReviewsRequest {
                account: "acme".into(),
            },
        ))
        .await
        .expect("acme's queue")
        .into_inner();
    assert_eq!(queue.pending, 1, "{queue:?}");
    assert_eq!(
        queue.reviews.len(),
        3,
        "the two refusals are noted too: {queue:?}"
    );
    let held = queue
        .reviews
        .iter()
        .find(|r| r.state == "pending")
        .unwrap()
        .clone();
    for who in [&w.op, &w.bob] {
        let err = w
            .enterprise()
            .decide_name_review(authed(
                who,
                DecideNameReviewRequest {
                    account: "acme".into(),
                    id: held.id.clone(),
                    allow: true,
                },
            ))
            .await
            .expect_err("only the account admin decides");
        assert_eq!(err.code(), Code::PermissionDenied, "{}", who.principal_id);
    }
    w.enterprise()
        .decide_name_review(authed(
            &w.acme,
            DecideNameReviewRequest {
                account: "acme".into(),
                id: held.id.clone(),
                allow: true,
            },
        ))
        .await
        .expect("acme allows it");
    w.create(&w.acme, "acme", "porn-filter", Visibility::Private)
        .await
        .expect("allowed in acme now");

    // A member named as staff is not made.
    let err = w
        .accounts()
        .enroll_employee(authed(
            &w.acme,
            EnrollEmployeeRequest {
                account: "acme".into(),
                id: "support".into(),
                name: "support".into(),
                ..Default::default()
            },
        ))
        .await
        .expect_err("a reserved name");
    assert_eq!(err.code(), Code::InvalidArgument);
    assert!(err.message().contains("reserved"), "{}", err.message());
    // A signup relayed by a machine is held to the reserved names; the
    // operator (a person) names the estate's own.
    let err = w
        .access()
        .add_principal(authed(
            &w.relay,
            AddPrincipalRequest {
                name: "administrator".into(),
                kind: PrincipalKind::User as i32,
                id: String::new(),
            },
        ))
        .await
        .expect_err("a machine relaying a signup");
    assert_eq!(err.code(), Code::InvalidArgument);
    w.access()
        .add_principal(authed(
            &w.op,
            AddPrincipalRequest {
                name: "security".into(),
                kind: PrincipalKind::User as i32,
                id: String::new(),
            },
        ))
        .await
        .expect("the operator names a staff account");

    let log = w.log(&w.acme, &["name"]).await.unwrap();
    let seen = kinds(&log);
    for want in [
        "name.refused:admin:refused",
        "name.held:admin:refused",
        "name.allowed:admin:ok",
    ] {
        assert!(seen.iter().any(|s| s == want), "{want}: {seen:#?}");
    }

    // The lists are gunnar's, set by a server admin, read by anyone it asks.
    let mut lists = w
        .enterprise()
        .get_name_lists(authed(&w.op, GetNameListsRequest {}))
        .await
        .expect("the lists")
        .into_inner();
    assert!(!lists.blocked.is_empty() && !lists.reserved.is_empty());
    lists.blocked.push("frobnicate".into());
    w.enterprise()
        .set_name_lists(authed(
            &w.op,
            SetNameListsRequest {
                lists: Some(lists.clone()),
            },
        ))
        .await
        .expect("the operator sets the lists");
    let err = w
        .create(&w.acme, "acme", "frobnicate-all", Visibility::Private)
        .await
        .expect_err("the new word");
    assert_eq!(err.code(), Code::InvalidArgument);
    let err = w
        .enterprise()
        .set_name_lists(authed(&w.acme, SetNameListsRequest { lists: Some(lists) }))
        .await
        .expect_err("an account admin does not set the server's lists");
    assert_eq!(err.code(), Code::PermissionDenied);
    let checked = w
        .enterprise()
        .check_name(authed(
            &w.bob,
            CheckNameRequest {
                kind: "repo".into(),
                name: "f\u{0430}ggot-list".into(),
                account: "acme".into(),
            },
        ))
        .await
        .expect("anyone authenticated asks")
        .into_inner();
    assert_eq!(checked.verdict, "blocked", "a Cyrillic а is still a");
}

// ── 1b. an approval (machine enrolment) in the approver's account log ─────

/// ★ **"Approvals (machine enrolment)"**: a kit asks for a machine
/// credential, the operator — a person, server admin — approves it with a
/// fresh touch of their own passkey; the approval (and a refusal) is in the
/// OPERATOR's own account log, by the operator, naming the machine.
#[tokio::test(flavor = "multi_thread")]
async fn a_machine_enrolment_approval_is_in_the_approvers_account_log() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let op_key = Passkey::new(13, "op-yubikey");
    w.plane
        .add_credential("op", &op_key.id, &op_key.public(), "op's YubiKey", 0)
        .expect("op's passkey");
    let kits = [
        Passkey::new(14, "kit-oden-key"),
        Passkey::new(15, "kit-dwarf-key"),
    ];
    let ask = |machine: &'static str, challenge: Vec<u8>| {
        let kit = if machine == "kit-oden" {
            &kits[0]
        } else {
            &kits[1]
        };
        RequestMachineEnrolmentRequest {
        machine: machine.to_owned(),
        label: format!("installer kit on {machine}"),
        server_level: GrantLevel::Admin as i32,
        credential_id: kit.id.clone(),
        public_key: kit.public(),
        client_data_json: format!(
            r#"{{"type":"webauthn.create","challenge":"{}","origin":"{ORIGIN}","crossOrigin":false}}"#,
            gunnar_grpc::webauthn::b64url(&challenge)
        )
        .into_bytes(),
        rp_id: RP_ID.to_owned(),
        origin: ORIGIN.to_owned(),
        sign_count: 0,
        attestation_object: gunnar_grpc::webauthn::attestation_none(RP_ID, &kit.id, &kit.public(), 0),
    }
    };
    let held = w
        .access()
        .request_machine_enrolment(authed(&w.relay, ask("kit-oden", w.challenge().await)))
        .await
        .expect("the kit asks, relayed")
        .into_inner()
        .request
        .unwrap();
    w.access()
        .approve_machine_enrolment(stepped(
            &w.op,
            ApproveMachineEnrolmentRequest {
                request_id: held.request_id.clone(),
                code: held.code.clone(),
                server_level: GrantLevel::Unspecified as i32,
            },
        ))
        .await
        .expect("the operator approves with its own touch");
    let refused = w
        .access()
        .request_machine_enrolment(authed(&w.relay, ask("kit-dwarf", w.challenge().await)))
        .await
        .expect("a second kit asks")
        .into_inner()
        .request
        .unwrap();
    w.access()
        .refuse_machine_enrolment(authed(
            &w.op,
            RefuseMachineEnrolmentRequest {
                request_id: refused.request_id.clone(),
            },
        ))
        .await
        .expect("the operator refuses it");

    let log = w
        .enterprise()
        .audit_log(authed(
            &w.op,
            AuditLogRequest {
                account: "op".into(),
                filter: Some(AuditFilter {
                    kinds: vec!["approval".into()],
                    ..Default::default()
                }),
                page_size: 10,
                before_seq: None,
            },
        ))
        .await
        .expect("the operator reads its OWN account's log")
        .into_inner();
    let seen: Vec<String> = log
        .entries
        .iter()
        .map(|e| format!("{}:{}:{}:{}", e.kind, e.actor, e.actor_role, e.target))
        .collect();
    assert_eq!(
        seen,
        vec![
            "approval.machine_refused:op:admin:kit-dwarf",
            "approval.machine:op:admin:kit-oden"
        ],
        "{seen:#?}"
    );
    assert!(
        log.entries[1].detail.contains(&held.code),
        "{:?}",
        log.entries[1]
    );
    // acme's log knows nothing of it.
    let acme = w.log(&w.acme, &["approval"]).await.unwrap();
    assert!(acme.entries.is_empty(), "{:?}", kinds(&acme));
}

// ── 4. clans are accounts to the enterprise list ──────────────────────────

/// ★ **A CLAN is an account to the enterprise list** (follow-ups of the
/// clans + audit merge, 2026-10-05): a clan's namespace is behind the
/// operator's shield like an account's (its repositories are not the
/// operator's to list or read, and `Aggregates` counts them inside the
/// accounts, not as the operator's); every clan verb is in the clan's own
/// audit log, which its admin reads — and the account that acted has it in
/// its own; and `Clans.Create` passes the name filter as a namespace does.
#[tokio::test(flavor = "multi_thread")]
async fn a_clan_is_an_account_to_the_enterprise_list() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    for id in ["carol", "dave"] {
        w.plane
            .add_principal(id, id, PrincipalKind::User)
            .expect("an ordinary account");
    }
    let (carol, dave) = (person("carol"), person("dave"));
    // The name filter: an offensive clan name is refused, and nothing is made.
    let err = w
        .clans()
        .create(authed(
            &carol,
            CreateClanRequest {
                name: "fuck-crew".into(),
                contribution_bytes: 0,
            },
        ))
        .await
        .expect_err("an offensive clan name");
    assert_eq!(err.code(), Code::InvalidArgument, "{err:?}");
    assert!(
        w.plane.namespace("fuck-crew").unwrap().is_none(),
        "a refused clan left a namespace"
    );
    w.clans()
        .create(authed(
            &carol,
            CreateClanRequest {
                name: "fellows".into(),
                contribution_bytes: 0,
            },
        ))
        .await
        .expect("a clean clan name");
    w.clans()
        .invite(authed(
            &carol,
            InviteToClanRequest {
                clan: "fellows".into(),
                principal_id: "dave".into(),
            },
        ))
        .await
        .expect("carol invites dave");
    w.clans()
        .accept(authed(
            &dave,
            AcceptClanInviteRequest {
                clan: "fellows".into(),
                contribution_bytes: 0,
            },
        ))
        .await
        .expect("dave joins");
    w.clans()
        .set_admin(authed(
            &carol,
            SetClanAdminRequest {
                clan: "fellows".into(),
                principal_id: "dave".into(),
                admin: true,
            },
        ))
        .await
        .expect("carol makes dave an admin");
    w.clans()
        .set_contribution(authed(
            &dave,
            SetClanContributionRequest {
                clan: "fellows".into(),
                contribution_bytes: 0,
            },
        ))
        .await
        .expect("dave sets what he gives");
    w.create(&dave, "fellows", "plans", Visibility::Private)
        .await
        .expect("a member makes a private repository");

    // The operator's shield: the clan's repositories are not the operator's.
    assert!(
        !w.listed(&w.op, "")
            .await
            .contains(&"fellows/plans".to_owned()),
        "the operator lists a clan's repository"
    );
    let err = w
        .get(&w.op, "fellows", "plans")
        .await
        .expect_err("a clan's private repository by name");
    assert_eq!(err.code(), Code::PermissionDenied, "{err:?}");
    let totals = w
        .enterprise()
        .aggregates(authed(&w.op, AggregatesRequest {}))
        .await
        .expect("totals")
        .into_inner();
    assert_eq!(
        totals.operator_repos, 1,
        "a clan's repository is not the operator's: {totals:?}"
    );
    assert_eq!(
        totals.repos, 5,
        "the whole estate: acme's two, op/notes, nordisk/gunnar and fellows/plans: {totals:?}"
    );

    // The clan's own log, read by its admins and nobody else.
    let log = w
        .log_of(&carol, "fellows")
        .await
        .expect("the clan's admin reads the clan's log");
    let seen = kinds(&log);
    for want in [
        "clan.created:admin:ok",
        "clan.invited:admin:ok",
        "clan.joined:member:ok",
        "clan.admin_made:admin:ok",
        "clan.contribution:admin:ok",
        "repo.created:admin:ok",
    ] {
        assert!(
            seen.iter().any(|s| s == want),
            "{want} is not in the clan's log: {seen:#?}"
        );
    }
    for who in [&w.op, &w.acme] {
        let err = w
            .log_of(who, "fellows")
            .await
            .expect_err("only the clan's admins");
        assert_eq!(
            err.code(),
            Code::PermissionDenied,
            "{}: {err:?}",
            who.principal_id
        );
    }
    // The account that acted has it in its own log.
    let own = kinds(&w.log_of(&dave, "dave").await.expect("dave reads his own"));
    assert!(
        own.iter().any(|s| s == "clan.joined:admin:ok"),
        "dave's own log: {own:#?}"
    );
    let own = kinds(
        &w.log_of(&carol, "carol")
            .await
            .expect("carol reads her own"),
    );
    assert!(
        own.iter().any(|s| s == "clan.created:admin:ok"),
        "carol's own log: {own:#?}"
    );
}

/// ★ **A repository offered out of a clan is in the account logs** (clans
/// round 2 follow-up, 2026-10-06): `Clans.OfferRepo` and every answer to it
/// (`Clans.AnswerRepoOffer`: withdrawn by the clan's admin, declined or taken
/// by the account's) are in the clan's own log, in the offering admin's
/// account's, and in the receiving account's — once each, and in no other
/// account's.
#[tokio::test(flavor = "multi_thread")]
async fn a_repository_offered_out_of_a_clan_is_in_the_clans_the_offerers_and_the_receivers_logs() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    for id in ["carol", "dave"] {
        w.plane
            .add_principal(id, id, PrincipalKind::User)
            .expect("an ordinary account");
    }
    let (carol, dave) = (person("carol"), person("dave"));
    w.clans()
        .create(authed(
            &carol,
            CreateClanRequest {
                name: "fellows".into(),
                contribution_bytes: 0,
            },
        ))
        .await
        .expect("carol makes the clan");
    w.create(&carol, "fellows", "plans", Visibility::Private)
        .await
        .expect("a clan's repository");
    let offer = |who: &Caller| {
        let who = who.clone();
        let clans = w.clans();
        async move {
            clans
                .offer_repo(authed(
                    &who,
                    OfferRepoRequest {
                        clan: "fellows".into(),
                        repo: "plans".into(),
                        account: "dave".into(),
                    },
                ))
                .await
                .map(|_| ())
        }
    };
    let answer = |who: &Caller, accept: bool| {
        let who = who.clone();
        let clans = w.clans();
        async move {
            clans
                .answer_repo_offer(authed(
                    &who,
                    AnswerRepoOfferRequest {
                        clan: "fellows".into(),
                        repo: "plans".into(),
                        accept,
                    },
                ))
                .await
                .map(|_| ())
        }
    };
    offer(&carol)
        .await
        .expect("carol offers fellows/plans to dave");
    answer(&carol, false).await.expect("carol withdraws it");
    offer(&carol).await.expect("offered again");
    answer(&dave, false).await.expect("dave declines it");
    offer(&carol).await.expect("offered a third time");
    answer(&dave, true).await.expect("dave takes it");

    const EVENTS: [&str; 4] = [
        "clan.repo_offered",
        "clan.repo_offer_withdrawn",
        "clan.repo_offer_declined",
        "clan.repo_moved",
    ];
    let count = |seen: &[String], kind: &str| {
        seen.iter()
            .filter(|s| s.split(':').next() == Some(kind) && s.ends_with(":ok"))
            .count()
    };
    for (reader, account, offered) in [
        (&carol, "fellows", 3),
        (&carol, "carol", 3),
        (&dave, "dave", 3),
    ] {
        let seen = kinds(
            &w.log_of(reader, account)
                .await
                .unwrap_or_else(|e| panic!("{account}'s log: {e:?}")),
        );
        assert_eq!(
            count(&seen, "clan.repo_offered"),
            offered,
            "three offers in {account}'s log: {seen:#?}"
        );
        for kind in &EVENTS[1..] {
            assert_eq!(
                count(&seen, kind),
                1,
                "{kind} once in {account}'s log: {seen:#?}"
            );
        }
    }
    let acme = kinds(&w.log_of(&w.acme, "acme").await.expect("acme's own"));
    for kind in EVENTS {
        assert_eq!(
            count(&acme, kind),
            0,
            "{kind} in an uninvolved account's log: {acme:#?}"
        );
    }
}

// ── 5. members (owner, 2026-10-07: a customer is an ACCOUNT that pays; its
//       members use its space, never buy, and get Write from its admin) ───────

/// ★ **WhoAmI says which account the caller acts in and what it is to it**,
/// over the real table: `acme` (one member, `bob`) is its admin, `bob` its
/// employee — never a namespace of his own — and `op`, who holds an account
/// of his own and no members, an individual. A console draws the buying doors
/// and the member's storage from this answer and nothing of its own.
#[tokio::test(flavor = "multi_thread")]
async fn who_am_i_names_the_account_and_the_callers_role_in_it() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let who = |caller: &Caller| {
        let access = w.access();
        let caller = caller.clone();
        async move {
            let me = access
                .who_am_i(authed(&caller, WhoAmIRequest {}))
                .await
                .expect("an answer")
                .into_inner();
            (me.account, me.account_role, me.account_admin)
        }
    };
    assert_eq!(
        who(&w.acme).await,
        ("acme".to_owned(), "admin".to_owned(), "acme".to_owned())
    );
    assert_eq!(
        who(&w.bob).await,
        ("acme".to_owned(), "employee".to_owned(), "acme".to_owned()),
        "a member acts in the account that enrolled him"
    );
    assert_eq!(
        who(&w.op).await,
        ("op".to_owned(), "individual".to_owned(), "op".to_owned())
    );
    assert_eq!(
        who(&w.relay).await,
        (String::new(), String::new(), String::new()),
        "a machine with no account of its own speaks for none"
    );
}

/// ★ **The account admin gives a member Write on one of the account's
/// repositories, sees it, and takes it away — and Gunnar is what says only
/// the admin may.** The member cannot grant himself, cannot read the grants,
/// and the admin's listing covers the admin's own account and nothing else.
#[tokio::test(flavor = "multi_thread")]
async fn the_account_admin_gives_a_member_write_and_takes_it_away() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let write = |who: &Caller, principal: &str| {
        let access = w.access();
        let (who, principal) = (who.clone(), principal.to_owned());
        async move {
            access
                .grant(authed(
                    &who,
                    GrantRequest {
                        principal_id: principal,
                        namespace: "acme".into(),
                        repo: "site".into(),
                        level: GrantLevel::Write as i32,
                    },
                ))
                .await
                .map(|_| ())
        }
    };
    let listed = |who: &Caller, namespace: &str, repo: &str| {
        let access = w.access();
        let (who, namespace, repo) = (who.clone(), namespace.to_owned(), repo.to_owned());
        async move {
            access
                .list_grants(authed(
                    &who,
                    ListGrantsRequest {
                        principal_id: String::new(),
                        namespace,
                        repo,
                    },
                ))
                .await
                .map(|r| {
                    let mut rows: Vec<String> = r
                        .into_inner()
                        .grants
                        .into_iter()
                        .map(|g| {
                            format!("{}:{}/{}:{}", g.principal_id, g.namespace, g.repo, g.level)
                        })
                        .collect();
                    rows.sort();
                    rows
                })
        }
    };
    let (read, writes) = (GrantLevel::Read as i32, GrantLevel::Write as i32);

    // A member owns no account by his name: no namespace `bob` is his to
    // administer (the walkthrough's `ben` was offered one for New repository
    // and Import, and bought room for it).
    let own = w
        .access()
        .check(authed(
            &w.bob,
            CheckRequest {
                namespace: "bob".into(),
                repo: String::new(),
                level: GrantLevel::Admin as i32,
            },
        ))
        .await
        .expect("an answer")
        .into_inner();
    assert!(
        !own.allowed,
        "a member is no account's admin by his name: {own:?}"
    );

    // The member may not hand himself Write, nor read who holds what.
    let refused = write(&w.bob, "bob")
        .await
        .expect_err("a member grants nothing");
    assert_eq!(refused.code(), Code::PermissionDenied, "{refused:?}");
    let refused = listed(&w.bob, "acme", "")
        .await
        .expect_err("a member reads no grants");
    assert_eq!(refused.code(), Code::PermissionDenied, "{refused:?}");

    // The account admin sees what enrolment gave bob: Read on the account.
    assert_eq!(
        listed(&w.acme, "acme", "")
            .await
            .expect("the admin reads the account's grants"),
        [format!("bob:acme/:{read}")]
    );
    // …and gives him Write on one repository.
    write(&w.acme, "bob")
        .await
        .expect("the account admin grants Write");
    assert_eq!(
        listed(&w.acme, "acme", "site")
            .await
            .expect("one repository's"),
        [format!("bob:acme/site:{writes}")]
    );
    let may = w
        .access()
        .check(authed(
            &w.bob,
            CheckRequest {
                namespace: "acme".into(),
                repo: "site".into(),
                level: GrantLevel::Write as i32,
            },
        ))
        .await
        .expect("an answer")
        .into_inner();
    assert!(may.allowed, "bob may write acme/site now: {may:?}");

    // The admin's listing is the admin's OWN account: no other, and not the
    // whole table (a server admin's).
    for (namespace, why) in [("nordisk", "another namespace"), ("", "the whole table")] {
        let refused = listed(&w.acme, namespace, "").await.expect_err(why);
        assert_eq!(refused.code(), Code::PermissionDenied, "{why}: {refused:?}");
    }

    // Taken away again: back to the account's Read.
    w.access()
        .revoke(authed(
            &w.acme,
            RevokeRequest {
                principal_id: "bob".into(),
                namespace: "acme".into(),
                repo: "site".into(),
            },
        ))
        .await
        .expect("the account admin takes Write away");
    assert_eq!(
        listed(&w.acme, "acme", "site")
            .await
            .expect("one repository's"),
        Vec::<String>::new()
    );
    let may = w
        .access()
        .check(authed(
            &w.bob,
            CheckRequest {
                namespace: "acme".into(),
                repo: "site".into(),
                level: GrantLevel::Write as i32,
            },
        ))
        .await
        .expect("an answer")
        .into_inner();
    assert!(!may.allowed, "bob may no longer write acme/site: {may:?}");
    let log = kinds(&w.log(&w.acme, &["grant"]).await.expect("the admin's log"));
    for want in ["grant.added:admin:ok", "grant.revoked:admin:ok"] {
        assert!(
            log.iter().any(|s| s == want),
            "{want} is not in acme's log: {log:#?}"
        );
    }
}

/// ★ **Users the account's admin bought are added in the admin's name.** The
/// seller (monetize, at server scope) delivers a paid "Add users" order; the
/// account's log says the account's admin added the member — and who
/// delivered it, under which order — never "operator" reaching inside the
/// account (the walkthrough of 2026-10-07 read "alice (operator)" there: the
/// rig's box operator, whose key the bench monetize signs with).
#[tokio::test(flavor = "multi_thread")]
async fn users_the_admin_bought_are_added_in_the_admins_name() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let order = "gunnar/acme/2026-10-07+users=1";
    w.accounts()
        .enroll_employee(authed(
            &w.op,
            EnrollEmployeeRequest {
                account: "acme".into(),
                id: "carl".into(),
                name: "Carl".into(),
                order: order.into(),
                ..Default::default()
            },
        ))
        .await
        .expect("the seller delivers the paid order");
    let log = w
        .log(&w.acme, &["member.added"])
        .await
        .expect("the admin's log");
    let carl = log
        .entries
        .iter()
        .find(|e| e.target == "carl")
        .expect("carl's entry");
    assert_eq!(
        (carl.actor.as_str(), carl.actor_role.as_str()),
        ("acme", "admin"),
        "{carl:?}"
    );
    assert!(
        carl.detail.contains(order) && carl.detail.contains("delivered by op"),
        "the delivery is named: {carl:?}"
    );
}

/// ★ **Turning encryption on or off is in the account's audit log** (wiring
/// tracer B 2026-10-08), as a visibility change is: it decides what the
/// operator can be trusted with for every member, and turning it OFF was
/// written nowhere the account admin reads — only a tracing line on the box.
#[tokio::test(flavor = "multi_thread")]
async fn turning_encryption_on_or_off_is_in_the_accounts_audit_log() {
    let w = tokio::task::spawn_blocking(world).await.unwrap();
    let set = |on: bool| SetEncryptedRequest {
        path: Some(RepoPath::new("acme", "site")),
        encrypted: on,
    };
    let refused = w
        .repos()
        .set_encrypted(authed(&w.bob, set(true)))
        .await
        .expect_err("a member may not");
    assert_eq!(refused.code(), Code::PermissionDenied);
    w.repos()
        .set_encrypted(authed(&w.acme, set(true)))
        .await
        .expect("the account admin turns it on");
    w.repos()
        .set_encrypted(authed(&w.acme, set(false)))
        .await
        .expect("…and off");
    let log = w.log(&w.acme, &[]).await.expect("the admin reads the log");
    let seen = kinds(&log);
    for want in [
        "encrypted.changed:member:refused",
        "encrypted.changed:admin:ok",
    ] {
        assert!(
            seen.iter().any(|s| s == want),
            "{want} is not in the log: {seen:#?}"
        );
    }
    let off = log
        .entries
        .iter()
        .find(|e| e.kind == "encrypted.changed" && e.outcome == "ok")
        .expect("the newest");
    assert_eq!(
        off.detail, "encrypted → plaintext allowed",
        "newest first: the turn OFF"
    );
    assert_eq!(off.target, "acme/site");
}