myc

Self-custodial remote signer for Radroots apps
git clone https://radroots.dev/git/myc.git
Log | Files | Refs | README | LICENSE

admin_v1.rs (75498B)


      1 //! Exact Myc v1 Unix-admin route and model boundary.
      2 
      3 use core::{fmt, future::Future, pin::Pin, time::Duration};
      4 use std::{
      5     collections::BTreeSet,
      6     error::Error,
      7     path::Path,
      8     sync::{Arc, OnceLock},
      9 };
     10 
     11 use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
     12 use radroots_service_host::{
     13     AdminCorrelationId, AdminError, AdminErrorCode, AdminErrorMessage, AdminHttpMethod,
     14     AdminMutationRequest, AdminOperationId, AdminRequest, AdminRouteFailure,
     15     AdminRouteFailureStatus, AdminRouteOutcome, AdminRouter, AdminServer, AdminServerError,
     16     AdminTransportLimitValues, AdminTransportLimits, CancellationToken, UnixAdminSocketBinding,
     17     UnixAdminSocketWriterAuthority,
     18 };
     19 use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};
     20 use serde_json::{Map, Value};
     21 
     22 // Original model admission is never permitted to exceed the complete response
     23 // body cap enforced again by the shared host after envelope encoding.
     24 const MYC_ADMIN_RESPONSE_BODY_MAX_UTF8_BYTES: usize = 1_048_576;
     25 
     26 const OPERATOR_CONTRACT: &str =
     27     include_str!("../contracts/services_hardening/operator_contract.v1.json");
     28 
     29 /// Closed Myc v1 admin method vocabulary.
     30 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
     31 pub enum MycAdminMethod {
     32     Get,
     33     Post,
     34 }
     35 
     36 /// Closed Myc v1 Unix-admin route inventory.
     37 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
     38 pub enum MycAdminRoute {
     39     Status,
     40     EffectiveConfig,
     41     IdentityStatus,
     42     IdentityPublic,
     43     StateStatus,
     44     StateBackup,
     45     MetricsSnapshot,
     46     ConnectionsList,
     47     ConnectionApprove,
     48     ConnectionReject,
     49     ConnectionRevoke,
     50     ChallengeRequire,
     51     ChallengeAuthorize,
     52     AuditEvents,
     53     AuditSummary,
     54     DiscoveryDesired,
     55     DiscoveryRender,
     56     DiscoveryRefresh,
     57     DiscoveryPublish,
     58 }
     59 
     60 impl MycAdminRoute {
     61     pub const ALL: [Self; 19] = [
     62         Self::Status,
     63         Self::EffectiveConfig,
     64         Self::IdentityStatus,
     65         Self::IdentityPublic,
     66         Self::StateStatus,
     67         Self::StateBackup,
     68         Self::MetricsSnapshot,
     69         Self::ConnectionsList,
     70         Self::ConnectionApprove,
     71         Self::ConnectionReject,
     72         Self::ConnectionRevoke,
     73         Self::ChallengeRequire,
     74         Self::ChallengeAuthorize,
     75         Self::AuditEvents,
     76         Self::AuditSummary,
     77         Self::DiscoveryDesired,
     78         Self::DiscoveryRender,
     79         Self::DiscoveryRefresh,
     80         Self::DiscoveryPublish,
     81     ];
     82 
     83     #[must_use]
     84     pub const fn method(self) -> MycAdminMethod {
     85         match self {
     86             Self::Status
     87             | Self::EffectiveConfig
     88             | Self::IdentityStatus
     89             | Self::IdentityPublic
     90             | Self::StateStatus
     91             | Self::MetricsSnapshot
     92             | Self::ConnectionsList
     93             | Self::AuditEvents
     94             | Self::AuditSummary
     95             | Self::DiscoveryDesired => MycAdminMethod::Get,
     96             Self::StateBackup
     97             | Self::ConnectionApprove
     98             | Self::ConnectionReject
     99             | Self::ConnectionRevoke
    100             | Self::ChallengeRequire
    101             | Self::ChallengeAuthorize
    102             | Self::DiscoveryRender
    103             | Self::DiscoveryRefresh
    104             | Self::DiscoveryPublish => MycAdminMethod::Post,
    105         }
    106     }
    107 
    108     #[must_use]
    109     pub const fn path(self) -> &'static str {
    110         match self {
    111             Self::Status => "/v1/status",
    112             Self::EffectiveConfig => "/v1/config/effective",
    113             Self::IdentityStatus => "/v1/identity/status",
    114             Self::IdentityPublic => "/v1/identity/public",
    115             Self::StateStatus => "/v1/state/status",
    116             Self::StateBackup => "/v1/state/backup",
    117             Self::MetricsSnapshot => "/v1/metrics/snapshot",
    118             Self::ConnectionsList => "/v1/connections",
    119             Self::ConnectionApprove => "/v1/connections/{connection_id}/approve",
    120             Self::ConnectionReject => "/v1/connections/{connection_id}/reject",
    121             Self::ConnectionRevoke => "/v1/connections/{connection_id}/revoke",
    122             Self::ChallengeRequire => "/v1/authorization/challenges/require",
    123             Self::ChallengeAuthorize => "/v1/authorization/challenges/{challenge_id}/authorize",
    124             Self::AuditEvents => "/v1/audit/events",
    125             Self::AuditSummary => "/v1/audit/summary",
    126             Self::DiscoveryDesired => "/v1/discovery/desired",
    127             Self::DiscoveryRender => "/v1/discovery/render",
    128             Self::DiscoveryRefresh => "/v1/discovery/refresh",
    129             Self::DiscoveryPublish => "/v1/discovery/publish",
    130         }
    131     }
    132 
    133     #[must_use]
    134     pub const fn operation_id(self) -> &'static str {
    135         match self {
    136             Self::Status => "radroots.myc.status.get.v1",
    137             Self::EffectiveConfig => "radroots.myc.config.effective.get.v1",
    138             Self::IdentityStatus => "radroots.myc.identity.status.get.v1",
    139             Self::IdentityPublic => "radroots.myc.identity.public.get.v1",
    140             Self::StateStatus => "radroots.myc.state.status.get.v1",
    141             Self::StateBackup => "radroots.myc.state.backup.create.v1",
    142             Self::MetricsSnapshot => "radroots.myc.metrics.snapshot.get.v1",
    143             Self::ConnectionsList => "radroots.myc.connections.list.v1",
    144             Self::ConnectionApprove => "radroots.myc.connection.approve.v1",
    145             Self::ConnectionReject => "radroots.myc.connection.reject.v1",
    146             Self::ConnectionRevoke => "radroots.myc.connection.revoke.v1",
    147             Self::ChallengeRequire => "radroots.myc.authorization.challenge.require.v1",
    148             Self::ChallengeAuthorize => "radroots.myc.authorization.challenge.authorize.v1",
    149             Self::AuditEvents => "radroots.myc.audit.events.list.v1",
    150             Self::AuditSummary => "radroots.myc.audit.summary.get.v1",
    151             Self::DiscoveryDesired => "radroots.myc.discovery.desired.get.v1",
    152             Self::DiscoveryRender => "radroots.myc.discovery.render.v1",
    153             Self::DiscoveryRefresh => "radroots.myc.discovery.refresh.v1",
    154             Self::DiscoveryPublish => "radroots.myc.discovery.publish.v1",
    155         }
    156     }
    157 
    158     #[must_use]
    159     pub const fn request_model(self) -> &'static str {
    160         match self {
    161             Self::Status
    162             | Self::EffectiveConfig
    163             | Self::StateStatus
    164             | Self::MetricsSnapshot
    165             | Self::DiscoveryDesired => "empty",
    166             Self::IdentityStatus => "identity_status_query_v1",
    167             Self::IdentityPublic => "identity_public_query_v1",
    168             Self::StateBackup => "state_backup_request_v1",
    169             Self::ConnectionsList => "connections_query_v1",
    170             Self::ConnectionApprove => "connection_approve_request_v1",
    171             Self::ConnectionReject => "connection_reject_request_v1",
    172             Self::ConnectionRevoke => "connection_revoke_request_v1",
    173             Self::ChallengeRequire => "challenge_require_request_v1",
    174             Self::ChallengeAuthorize => "challenge_authorize_request_v1",
    175             Self::AuditEvents => "audit_events_query_v1",
    176             Self::AuditSummary => "audit_summary_query_v1",
    177             Self::DiscoveryRender => "discovery_render_request_v1",
    178             Self::DiscoveryRefresh => "discovery_refresh_request_v1",
    179             Self::DiscoveryPublish => "discovery_publish_request_v1",
    180         }
    181     }
    182 
    183     #[must_use]
    184     pub const fn response_model(self) -> &'static str {
    185         match self {
    186             Self::Status => "service_status_v1",
    187             Self::EffectiveConfig => "effective_config_v1",
    188             Self::IdentityStatus => "identity_status_v1",
    189             Self::IdentityPublic => "identity_public_v1",
    190             Self::StateStatus => "state_status_v1",
    191             Self::StateBackup => "state_backup_receipt_v1",
    192             Self::MetricsSnapshot => "metrics_snapshot_v1",
    193             Self::ConnectionsList => "connections_page_v1",
    194             Self::ConnectionApprove | Self::ConnectionReject | Self::ConnectionRevoke => {
    195                 "connection_mutation_receipt_v1"
    196             }
    197             Self::ChallengeRequire => "challenge_v1",
    198             Self::ChallengeAuthorize => "challenge_authorization_receipt_v1",
    199             Self::AuditEvents => "audit_events_page_v1",
    200             Self::AuditSummary => "audit_summary_v1",
    201             Self::DiscoveryDesired => "discovery_desired_v1",
    202             Self::DiscoveryRender => "discovery_render_receipt_v1",
    203             Self::DiscoveryRefresh => "discovery_refresh_receipt_v1",
    204             Self::DiscoveryPublish => "discovery_publish_receipt_v1",
    205         }
    206     }
    207 
    208     #[must_use]
    209     pub const fn is_mutation(self) -> bool {
    210         matches!(self.method(), MycAdminMethod::Post)
    211     }
    212 
    213     const fn host_method(self) -> AdminHttpMethod {
    214         match self.method() {
    215             MycAdminMethod::Get => AdminHttpMethod::Get,
    216             MycAdminMethod::Post => AdminHttpMethod::Post,
    217         }
    218     }
    219 
    220     const fn parameter_name(self) -> Option<&'static str> {
    221         match self {
    222             Self::ConnectionApprove | Self::ConnectionReject | Self::ConnectionRevoke => {
    223                 Some("connection_id")
    224             }
    225             Self::ChallengeAuthorize => Some("challenge_id"),
    226             _ => None,
    227         }
    228     }
    229 }
    230 
    231 /// One route-bound, already validated Myc admin request.
    232 pub struct MycAdminRequestDocument {
    233     route: MycAdminRoute,
    234     operation_id: Option<AdminOperationId>,
    235     correlation_id: AdminCorrelationId,
    236     parameter: Option<(&'static str, Box<str>)>,
    237     model_bytes: Box<[u8]>,
    238 }
    239 
    240 impl MycAdminRequestDocument {
    241     #[must_use]
    242     pub const fn route(&self) -> MycAdminRoute {
    243         self.route
    244     }
    245 
    246     /// Returns the caller's durable idempotency identity for a mutation.
    247     #[must_use]
    248     pub fn operation_id(&self) -> Option<&str> {
    249         self.operation_id.as_ref().map(AdminOperationId::as_str)
    250     }
    251 
    252     #[must_use]
    253     pub fn correlation_id(&self) -> &str {
    254         self.correlation_id.as_str()
    255     }
    256 
    257     /// Returns a validated percent-decoded path parameter when this route has one.
    258     #[must_use]
    259     pub fn parameter(&self, name: &str) -> Option<&str> {
    260         self.parameter
    261             .as_ref()
    262             .filter(|(parameter_name, _)| *parameter_name == name)
    263             .map(|(_, value)| value.as_ref())
    264     }
    265 
    266     pub(crate) fn parameter_binding(&self) -> Option<(&'static str, &str)> {
    267         self.parameter
    268             .as_ref()
    269             .map(|(name, value)| (*name, value.as_ref()))
    270     }
    271 
    272     /// Returns compact canonical JSON for the route's exact request model.
    273     #[must_use]
    274     pub fn model_bytes(&self) -> &[u8] {
    275         &self.model_bytes
    276     }
    277 
    278     #[cfg(test)]
    279     pub(crate) fn mutation_for_test(
    280         route: MycAdminRoute,
    281         operation_id: &str,
    282         parameter: Option<(&'static str, &str)>,
    283         model_bytes: &[u8],
    284     ) -> Self {
    285         assert!(route.is_mutation());
    286         Self {
    287             route,
    288             operation_id: Some(AdminOperationId::new(operation_id).expect("test operation ID")),
    289             correlation_id: AdminCorrelationId::new("test-correlation")
    290                 .expect("test correlation ID"),
    291             parameter: parameter.map(|(name, value)| (name, value.into())),
    292             model_bytes: model_bytes.into(),
    293         }
    294     }
    295 }
    296 
    297 impl fmt::Debug for MycAdminRequestDocument {
    298     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    299         formatter
    300             .debug_struct("MycAdminRequestDocument")
    301             .field("route", &self.route)
    302             .field("mutation", &self.operation_id.is_some())
    303             .field("has_parameter", &self.parameter.is_some())
    304             .field("model", &"[redacted]")
    305             .finish()
    306     }
    307 }
    308 
    309 /// One exact validated response model for a fixed route.
    310 pub struct MycAdminResponseDocument {
    311     route: MycAdminRoute,
    312     canonical_bytes: Box<[u8]>,
    313     value: Value,
    314 }
    315 
    316 impl MycAdminResponseDocument {
    317     /// Admits only compact canonical JSON matching the route's response model.
    318     pub fn from_canonical_bytes(
    319         route: MycAdminRoute,
    320         bytes: &[u8],
    321     ) -> Result<Self, MycAdminDocumentError> {
    322         if bytes.is_empty() {
    323             return Err(MycAdminDocumentError::new(
    324                 MycAdminDocumentErrorKind::Malformed,
    325             ));
    326         }
    327         if bytes.len() > MYC_ADMIN_RESPONSE_BODY_MAX_UTF8_BYTES {
    328             return Err(MycAdminDocumentError::new(
    329                 MycAdminDocumentErrorKind::TooLarge,
    330             ));
    331         }
    332         let value = strict_json(bytes)?;
    333         validate_model(route.response_model(), &value)?;
    334         let canonical = serde_json::to_vec(&value)
    335             .map_err(|_| MycAdminDocumentError::new(MycAdminDocumentErrorKind::Malformed))?;
    336         if canonical.as_slice() != bytes {
    337             return Err(MycAdminDocumentError::new(
    338                 MycAdminDocumentErrorKind::NonCanonical,
    339             ));
    340         }
    341         Ok(Self {
    342             route,
    343             canonical_bytes: canonical.into_boxed_slice(),
    344             value,
    345         })
    346     }
    347 
    348     #[must_use]
    349     pub const fn route(&self) -> MycAdminRoute {
    350         self.route
    351     }
    352 
    353     #[must_use]
    354     pub fn canonical_bytes(&self) -> &[u8] {
    355         &self.canonical_bytes
    356     }
    357 }
    358 
    359 impl fmt::Debug for MycAdminResponseDocument {
    360     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    361         formatter
    362             .debug_struct("MycAdminResponseDocument")
    363             .field("route", &self.route)
    364             .field("model", &"[redacted]")
    365             .finish()
    366     }
    367 }
    368 
    369 /// Stable classification for a rejected Myc admin document.
    370 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    371 pub enum MycAdminDocumentErrorKind {
    372     TooLarge,
    373     Malformed,
    374     DuplicateField,
    375     NullForbidden,
    376     NonCanonical,
    377     InvalidModel,
    378 }
    379 
    380 /// Source-free and content-free Myc admin document error.
    381 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    382 pub struct MycAdminDocumentError {
    383     kind: MycAdminDocumentErrorKind,
    384 }
    385 
    386 impl MycAdminDocumentError {
    387     const fn new(kind: MycAdminDocumentErrorKind) -> Self {
    388         Self { kind }
    389     }
    390 
    391     #[must_use]
    392     pub const fn kind(self) -> MycAdminDocumentErrorKind {
    393         self.kind
    394     }
    395 }
    396 
    397 impl fmt::Display for MycAdminDocumentError {
    398     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    399         formatter.write_str("Myc admin document is invalid")
    400     }
    401 }
    402 
    403 impl Error for MycAdminDocumentError {}
    404 
    405 /// Stable route-handler failure mapped to a bounded safe admin response.
    406 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    407 pub enum MycAdminHandlerErrorKind {
    408     InvalidCursor,
    409     OperationIdConflict,
    410     NotFound,
    411     Conflict,
    412     Unavailable,
    413     Internal,
    414 }
    415 
    416 /// Source-free route-handler error.
    417 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    418 pub struct MycAdminHandlerError {
    419     kind: MycAdminHandlerErrorKind,
    420 }
    421 
    422 impl MycAdminHandlerError {
    423     #[must_use]
    424     pub const fn new(kind: MycAdminHandlerErrorKind) -> Self {
    425         Self { kind }
    426     }
    427 
    428     #[must_use]
    429     pub const fn kind(self) -> MycAdminHandlerErrorKind {
    430         self.kind
    431     }
    432 }
    433 
    434 impl fmt::Display for MycAdminHandlerError {
    435     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    436         formatter.write_str("Myc admin operation failed")
    437     }
    438 }
    439 
    440 impl Error for MycAdminHandlerError {}
    441 
    442 /// Boxed route future used by the sealed Myc admin adapter.
    443 pub type MycAdminFuture<'a> = Pin<
    444     Box<dyn Future<Output = Result<MycAdminResponseDocument, MycAdminHandlerError>> + Send + 'a>,
    445 >;
    446 
    447 /// Domain port behind the exact Myc admin transport.
    448 ///
    449 /// Implementations own authoritative local commit, durable operation-ID
    450 /// replay/conflict handling, and any provider or outbox orchestration. Returning
    451 /// success means that the operation's contract-defined local effect is already
    452 /// committed; relay submission or delivery is not implied. Pagination cursors
    453 /// must be authenticated and bound to the same route, filters, and snapshot;
    454 /// mismatched or invalid cursors return [`MycAdminHandlerErrorKind::InvalidCursor`].
    455 /// Reusing an operation ID with identical canonical request bytes returns the
    456 /// original committed response; reuse with different bytes returns
    457 /// [`MycAdminHandlerErrorKind::OperationIdConflict`].
    458 pub trait MycAdminHandler: Send + Sync + 'static {
    459     fn handle<'a>(&'a self, request: MycAdminRequestDocument) -> MycAdminFuture<'a>;
    460 }
    461 
    462 /// Source-free router-construction failure.
    463 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    464 pub struct MycAdminRouterError;
    465 
    466 impl fmt::Display for MycAdminRouterError {
    467     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    468         formatter.write_str("Myc admin router could not be constructed")
    469     }
    470 }
    471 
    472 impl Error for MycAdminRouterError {}
    473 
    474 /// Opaque, fully registered Myc v1 router capability.
    475 ///
    476 /// The underlying shared-host router remains an implementation detail. The
    477 /// later runtime-composition checkpoint consumes this capability without
    478 /// exposing raw listener or transport authority.
    479 pub struct MycAdminRouter {
    480     inner: AdminRouter,
    481 }
    482 
    483 impl fmt::Debug for MycAdminRouter {
    484     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    485         let Self { inner } = self;
    486         let _ = inner;
    487         formatter.write_str("MycAdminRouter")
    488     }
    489 }
    490 
    491 impl MycAdminRouter {
    492     fn into_inner(self) -> AdminRouter {
    493         self.inner
    494     }
    495 }
    496 
    497 /// Cloneable cooperative cancellation for the Myc Unix-admin server.
    498 #[derive(Clone, Default)]
    499 pub struct MycAdminCancellationToken {
    500     inner: CancellationToken,
    501 }
    502 
    503 impl MycAdminCancellationToken {
    504     #[must_use]
    505     pub fn new() -> Self {
    506         Self::default()
    507     }
    508 
    509     /// Requests cancellation. Repeated requests have no additional effect.
    510     pub fn cancel(&self) {
    511         self.inner.cancel();
    512     }
    513 
    514     #[must_use]
    515     pub fn is_cancelled(&self) -> bool {
    516         self.inner.is_cancelled()
    517     }
    518 }
    519 
    520 impl fmt::Debug for MycAdminCancellationToken {
    521     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    522         formatter
    523             .debug_struct("MycAdminCancellationToken")
    524             .field("cancelled", &self.is_cancelled())
    525             .finish()
    526     }
    527 }
    528 
    529 /// Stable source-free Myc Unix-admin server failure classification.
    530 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    531 pub enum MycAdminServerErrorKind {
    532     InvalidConfiguration,
    533     Router,
    534     ServerConfiguration,
    535     WriterAuthority,
    536     Bind,
    537     Listener,
    538     Accept,
    539     ConnectionTaskPanicked,
    540 }
    541 
    542 impl MycAdminServerErrorKind {
    543     #[must_use]
    544     pub const fn code(self) -> &'static str {
    545         match self {
    546             Self::InvalidConfiguration => "admin_configuration_invalid",
    547             Self::Router => "admin_router_invalid",
    548             Self::ServerConfiguration => "admin_server_configuration_invalid",
    549             Self::WriterAuthority => "admin_writer_authority_unavailable",
    550             Self::Bind => "admin_bind_failed",
    551             Self::Listener => "admin_listener_failed",
    552             Self::Accept => "admin_accept_failed",
    553             Self::ConnectionTaskPanicked => "admin_connection_task_panicked",
    554         }
    555     }
    556 }
    557 
    558 /// One redacted source-free Myc Unix-admin server failure.
    559 #[derive(Clone, Copy, PartialEq, Eq)]
    560 pub struct MycAdminServerError {
    561     kind: MycAdminServerErrorKind,
    562 }
    563 
    564 impl MycAdminServerError {
    565     const fn new(kind: MycAdminServerErrorKind) -> Self {
    566         Self { kind }
    567     }
    568 
    569     #[must_use]
    570     pub const fn kind(self) -> MycAdminServerErrorKind {
    571         self.kind
    572     }
    573 
    574     #[must_use]
    575     pub const fn code(self) -> &'static str {
    576         self.kind.code()
    577     }
    578 }
    579 
    580 impl fmt::Debug for MycAdminServerError {
    581     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    582         formatter
    583             .debug_struct("MycAdminServerError")
    584             .field("kind", &self.kind)
    585             .finish()
    586     }
    587 }
    588 
    589 impl fmt::Display for MycAdminServerError {
    590     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    591         formatter.write_str("Myc Unix-admin server failed")
    592     }
    593 }
    594 
    595 impl Error for MycAdminServerError {}
    596 
    597 /// Unbound production Myc Unix-admin server.
    598 ///
    599 /// Construction projects only the already-admitted Myc configuration, seals
    600 /// the exact route inventory around the supplied domain handler, and uses the
    601 /// shared host's system entropy. The raw shared router and server never cross
    602 /// this boundary.
    603 pub struct MycAdminServer {
    604     inner: AdminServer,
    605 }
    606 
    607 impl MycAdminServer {
    608     pub fn new<H>(
    609         configuration: &crate::MycConfigDocumentV1,
    610         handler: Arc<H>,
    611     ) -> Result<Self, MycAdminServerError>
    612     where
    613         H: MycAdminHandler,
    614     {
    615         let limits = admin_transport_limits(configuration)?;
    616         let router = build_myc_admin_router(handler)
    617             .map_err(|_| MycAdminServerError::new(MycAdminServerErrorKind::Router))?;
    618         let inner = AdminServer::with_system_entropy(router.into_inner(), limits)
    619             .map_err(|_| MycAdminServerError::new(MycAdminServerErrorKind::ServerConfiguration))?;
    620         Ok(Self { inner })
    621     }
    622 
    623     /// Acquires the canonical runtime-directory authority and binds `admin.sock`.
    624     ///
    625     /// Binding does not spawn a task or begin request admission. Unit 15 owns
    626     /// the final supervised server task and its shutdown phase.
    627     pub async fn bind(
    628         self,
    629         runtime: &crate::MycRuntimeContext,
    630     ) -> Result<MycBoundAdminServer, MycAdminServerError> {
    631         let authority = UnixAdminSocketWriterAuthority::acquire(runtime.context().paths().run())
    632             .map_err(|_| MycAdminServerError::new(MycAdminServerErrorKind::WriterAuthority))?;
    633         let binding = UnixAdminSocketBinding::bind(authority, runtime.artifacts().admin_socket())
    634             .await
    635             .map_err(|_| MycAdminServerError::new(MycAdminServerErrorKind::Bind))?;
    636         Ok(MycBoundAdminServer {
    637             inner: self.inner,
    638             binding,
    639         })
    640     }
    641 }
    642 
    643 impl fmt::Debug for MycAdminServer {
    644     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    645         formatter.write_str("MycAdminServer([sealed])")
    646     }
    647 }
    648 
    649 /// Bound production Myc Unix-admin server.
    650 pub struct MycBoundAdminServer {
    651     inner: AdminServer,
    652     binding: UnixAdminSocketBinding,
    653 }
    654 
    655 impl MycBoundAdminServer {
    656     /// Serves until supervisor cancellation and then drains bounded connection work.
    657     pub async fn serve(
    658         self,
    659         cancellation: MycAdminCancellationToken,
    660     ) -> Result<(), MycAdminServerError> {
    661         self.inner
    662             .serve(self.binding, cancellation.inner)
    663             .await
    664             .map_err(map_admin_server_error)
    665     }
    666 }
    667 
    668 impl fmt::Debug for MycBoundAdminServer {
    669     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
    670         formatter.write_str("MycBoundAdminServer([sealed])")
    671     }
    672 }
    673 
    674 /// Registers the complete closed Myc v1 route inventory on the hardened Lib router.
    675 pub fn build_myc_admin_router<H>(handler: Arc<H>) -> Result<MycAdminRouter, MycAdminRouterError>
    676 where
    677     H: MycAdminHandler,
    678 {
    679     if !operator_route_inventory_is_exact() {
    680         return Err(MycAdminRouterError);
    681     }
    682     let mut router = AdminRouter::new();
    683     for route in MycAdminRoute::ALL {
    684         let handler = Arc::clone(&handler);
    685         router
    686             .route(route.host_method(), route.path(), move |request| {
    687                 let handler = Arc::clone(&handler);
    688                 async move { dispatch_route(route, handler, request).await }
    689             })
    690             .map_err(|_| MycAdminRouterError)?;
    691     }
    692     Ok(MycAdminRouter { inner: router })
    693 }
    694 
    695 pub(crate) fn admin_transport_limits(
    696     configuration: &crate::MycConfigDocumentV1,
    697 ) -> Result<AdminTransportLimits, MycAdminServerError> {
    698     let admin = configuration
    699         .normalized()
    700         .pointer("/resource_limits/admin")
    701         .ok_or_else(invalid_admin_configuration)?;
    702     let values = AdminTransportLimitValues {
    703         header_count: admin_u32(admin, "/header_count")?,
    704         header_bytes: admin_u32(admin, "/header_bytes")?,
    705         request_body_utf8_bytes: admin_u32(admin, "/request_body_utf8_bytes")?,
    706         response_body_utf8_bytes: admin_u32(admin, "/response_body_utf8_bytes")?,
    707         concurrent_connections: admin_u32(admin, "/concurrent_connections")?,
    708         request_deadline: Duration::from_millis(admin_u64(admin, "/request_deadline_ms")?),
    709         idle_timeout: Duration::from_millis(admin_u64(admin, "/idle_timeout_ms")?),
    710         query_items: admin_u32(admin, "/query_items")?,
    711     };
    712     AdminTransportLimits::new(values).map_err(|_| invalid_admin_configuration())
    713 }
    714 
    715 pub(crate) fn admit_admin_response_value(
    716     route: MycAdminRoute,
    717     value: &Value,
    718 ) -> Result<Box<[u8]>, MycAdminDocumentError> {
    719     let bytes = serde_json::to_vec(value)
    720         .map_err(|_| MycAdminDocumentError::new(MycAdminDocumentErrorKind::Malformed))?;
    721     MycAdminResponseDocument::from_canonical_bytes(route, &bytes)
    722         .map(|document| document.canonical_bytes)
    723 }
    724 
    725 fn admin_u64(value: &Value, pointer: &str) -> Result<u64, MycAdminServerError> {
    726     value
    727         .pointer(pointer)
    728         .and_then(Value::as_u64)
    729         .ok_or_else(invalid_admin_configuration)
    730 }
    731 
    732 fn admin_u32(value: &Value, pointer: &str) -> Result<u32, MycAdminServerError> {
    733     u32::try_from(admin_u64(value, pointer)?).map_err(|_| invalid_admin_configuration())
    734 }
    735 
    736 const fn invalid_admin_configuration() -> MycAdminServerError {
    737     MycAdminServerError::new(MycAdminServerErrorKind::InvalidConfiguration)
    738 }
    739 
    740 const fn map_admin_server_error(error: AdminServerError) -> MycAdminServerError {
    741     let kind = match error {
    742         AdminServerError::ListenerClone { .. } | AdminServerError::ListenerRegistration { .. } => {
    743             MycAdminServerErrorKind::Listener
    744         }
    745         AdminServerError::Accept { .. } => MycAdminServerErrorKind::Accept,
    746         AdminServerError::ConnectionTaskPanicked => MycAdminServerErrorKind::ConnectionTaskPanicked,
    747     };
    748     MycAdminServerError::new(kind)
    749 }
    750 
    751 async fn dispatch_route<H>(
    752     route: MycAdminRoute,
    753     handler: Arc<H>,
    754     request: AdminRequest,
    755 ) -> AdminRouteOutcome
    756 where
    757     H: MycAdminHandler,
    758 {
    759     let document = match request_document(route, &request) {
    760         Ok(document) => document,
    761         Err(_) => return failure(MycAdminHandlerErrorKind::Conflict, true),
    762     };
    763     match handler.handle(document).await {
    764         Ok(response) if response.route == route => match request.success(&response.value) {
    765             Ok(outcome) => outcome,
    766             Err(_) => failure(MycAdminHandlerErrorKind::Internal, false),
    767         },
    768         Ok(_) => failure(MycAdminHandlerErrorKind::Internal, false),
    769         Err(error) => failure(error.kind, false),
    770     }
    771 }
    772 
    773 fn failure(kind: MycAdminHandlerErrorKind, invalid_request: bool) -> AdminRouteOutcome {
    774     let (status, code, message) = if invalid_request {
    775         (
    776             AdminRouteFailureStatus::BadRequest,
    777             "invalid_request",
    778             "admin request does not match the route model",
    779         )
    780     } else {
    781         match kind {
    782             MycAdminHandlerErrorKind::InvalidCursor => (
    783                 AdminRouteFailureStatus::BadRequest,
    784                 "invalid_cursor",
    785                 "admin pagination cursor is invalid",
    786             ),
    787             MycAdminHandlerErrorKind::OperationIdConflict => (
    788                 AdminRouteFailureStatus::Conflict,
    789                 "operation_id_conflict",
    790                 "admin operation identity conflicts with retained state",
    791             ),
    792             MycAdminHandlerErrorKind::NotFound => (
    793                 AdminRouteFailureStatus::NotFound,
    794                 "not_found",
    795                 "admin resource was not found",
    796             ),
    797             MycAdminHandlerErrorKind::Conflict => (
    798                 AdminRouteFailureStatus::Conflict,
    799                 "operation_conflict",
    800                 "admin operation conflicts with current state",
    801             ),
    802             MycAdminHandlerErrorKind::Unavailable => (
    803                 AdminRouteFailureStatus::Unavailable,
    804                 "service_unavailable",
    805                 "admin operation is temporarily unavailable",
    806             ),
    807             MycAdminHandlerErrorKind::Internal => (
    808                 AdminRouteFailureStatus::Internal,
    809                 "internal_error",
    810                 "admin operation failed internally",
    811             ),
    812         }
    813     };
    814     let code = AdminErrorCode::new(code).expect("fixed admin error code");
    815     let message = AdminErrorMessage::new(message).expect("fixed admin error message");
    816     AdminRouteOutcome::failure(AdminRouteFailure::new(
    817         status,
    818         AdminError::new(code, message),
    819     ))
    820 }
    821 
    822 fn request_document(
    823     route: MycAdminRoute,
    824     request: &AdminRequest,
    825 ) -> Result<MycAdminRequestDocument, MycAdminDocumentError> {
    826     let (operation_id, value) = match route.method() {
    827         MycAdminMethod::Get => (None, query_model(route, request.query())?),
    828         MycAdminMethod::Post => {
    829             let envelope = request
    830                 .decode_json::<AdminMutationRequest<Value>>()
    831                 .map_err(|_| MycAdminDocumentError::new(MycAdminDocumentErrorKind::Malformed))?;
    832             (
    833                 Some(envelope.operation_id().clone()),
    834                 envelope.into_request(),
    835             )
    836         }
    837     };
    838     validate_model(route.request_model(), &value)?;
    839     let model_bytes = serde_json::to_vec(&value)
    840         .map_err(|_| MycAdminDocumentError::new(MycAdminDocumentErrorKind::Malformed))?;
    841     let parameter = route
    842         .parameter_name()
    843         .map(|name| {
    844             let value = request
    845                 .parameter(name)
    846                 .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))?
    847                 .to_owned()
    848                 .into_boxed_str();
    849             validate_type("bounded_id", &Value::String(value.to_string()), 0)?;
    850             Ok((name, value))
    851         })
    852         .transpose()?;
    853     Ok(MycAdminRequestDocument {
    854         route,
    855         operation_id,
    856         correlation_id: request.correlation_id().clone(),
    857         parameter,
    858         model_bytes: model_bytes.into_boxed_slice(),
    859     })
    860 }
    861 
    862 fn query_model(route: MycAdminRoute, query: Option<&str>) -> Result<Value, MycAdminDocumentError> {
    863     let Some(query) = query else {
    864         return Ok(Value::Object(Map::new()));
    865     };
    866     if query.is_empty() {
    867         return Err(MycAdminDocumentError::new(
    868             MycAdminDocumentErrorKind::InvalidModel,
    869         ));
    870     }
    871     let fields = model_fields(route.request_model())?;
    872     let mut output = Map::new();
    873     for item in query.split('&') {
    874         let (raw_key, raw_value) = item
    875             .split_once('=')
    876             .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))?;
    877         if raw_key.is_empty()
    878             || !valid_percent_encoding(raw_key)
    879             || !valid_percent_encoding(raw_value)
    880         {
    881             return Err(MycAdminDocumentError::new(
    882                 MycAdminDocumentErrorKind::InvalidModel,
    883             ));
    884         }
    885         let key = percent_decode(raw_key)?;
    886         let value = percent_decode(raw_value)?;
    887         if output.contains_key(&key) {
    888             return Err(MycAdminDocumentError::new(
    889                 MycAdminDocumentErrorKind::DuplicateField,
    890             ));
    891         }
    892         let descriptor = fields
    893             .get(&key)
    894             .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))?;
    895         let type_name = descriptor
    896             .get("type")
    897             .and_then(Value::as_str)
    898             .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))?;
    899         output.insert(key, query_scalar(type_name, value)?);
    900     }
    901     Ok(Value::Object(output))
    902 }
    903 
    904 fn query_scalar(type_name: &str, value: String) -> Result<Value, MycAdminDocumentError> {
    905     let descriptor = type_descriptor(type_name)?;
    906     match descriptor.get("kind").and_then(Value::as_str) {
    907         Some("integer") => {
    908             let canonical = value == "0"
    909                 || (value.as_bytes().first().is_some_and(u8::is_ascii_digit)
    910                     && !value.starts_with('0')
    911                     && value.bytes().all(|byte| byte.is_ascii_digit()));
    912             if !canonical {
    913                 return Err(MycAdminDocumentError::new(
    914                     MycAdminDocumentErrorKind::InvalidModel,
    915                 ));
    916             }
    917             value
    918                 .parse::<u64>()
    919                 .map(Value::from)
    920                 .map_err(|_| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))
    921         }
    922         Some("boolean") => match value.as_str() {
    923             "true" => Ok(Value::Bool(true)),
    924             "false" => Ok(Value::Bool(false)),
    925             _ => Err(MycAdminDocumentError::new(
    926                 MycAdminDocumentErrorKind::InvalidModel,
    927             )),
    928         },
    929         _ => Ok(Value::String(value)),
    930     }
    931 }
    932 
    933 fn percent_decode(value: &str) -> Result<String, MycAdminDocumentError> {
    934     let bytes = value.as_bytes();
    935     let mut decoded = Vec::with_capacity(bytes.len());
    936     let mut index = 0;
    937     while index < bytes.len() {
    938         match bytes[index] {
    939             b'%' => {
    940                 let high = hex_nibble(bytes[index + 1]).ok_or_else(invalid_model_error)?;
    941                 let low = hex_nibble(bytes[index + 2]).ok_or_else(invalid_model_error)?;
    942                 decoded.push((high << 4) | low);
    943                 index += 3;
    944             }
    945             b'+' => {
    946                 decoded.push(b' ');
    947                 index += 1;
    948             }
    949             byte => {
    950                 decoded.push(byte);
    951                 index += 1;
    952             }
    953         }
    954     }
    955     String::from_utf8(decoded).map_err(|_| invalid_model_error())
    956 }
    957 
    958 const fn hex_nibble(byte: u8) -> Option<u8> {
    959     match byte {
    960         b'0'..=b'9' => Some(byte - b'0'),
    961         b'a'..=b'f' => Some(byte - b'a' + 10),
    962         b'A'..=b'F' => Some(byte - b'A' + 10),
    963         _ => None,
    964     }
    965 }
    966 
    967 fn valid_percent_encoding(value: &str) -> bool {
    968     let bytes = value.as_bytes();
    969     let mut index = 0;
    970     while index < bytes.len() {
    971         if bytes[index] == b'%' {
    972             if index + 2 >= bytes.len()
    973                 || !bytes[index + 1].is_ascii_hexdigit()
    974                 || !bytes[index + 2].is_ascii_hexdigit()
    975             {
    976                 return false;
    977             }
    978             index += 3;
    979         } else {
    980             index += 1;
    981         }
    982     }
    983     true
    984 }
    985 
    986 fn operator_contract() -> &'static Value {
    987     static CONTRACT: OnceLock<Value> = OnceLock::new();
    988     CONTRACT.get_or_init(|| {
    989         serde_json::from_str(OPERATOR_CONTRACT).expect("checked-in Myc operator contract")
    990     })
    991 }
    992 
    993 fn operator_route_inventory_is_exact() -> bool {
    994     let Some(admin) = operator_contract().get("admin") else {
    995         return false;
    996     };
    997     let Some(routes) = admin.get("routes").and_then(Value::as_array) else {
    998         return false;
    999     };
   1000     let Some(models) = admin.get("models").and_then(Value::as_object) else {
   1001         return false;
   1002     };
   1003     routes.len() == MycAdminRoute::ALL.len()
   1004         && models.len() == 32
   1005         && admin
   1006             .pointer("/model_wire_contract/response_body_max_utf8_bytes")
   1007             .and_then(Value::as_u64)
   1008             == Some(MYC_ADMIN_RESPONSE_BODY_MAX_UTF8_BYTES as u64)
   1009         && routes.iter().zip(MycAdminRoute::ALL).all(|(wire, route)| {
   1010             wire.get("method").and_then(Value::as_str)
   1011                 == Some(match route.method() {
   1012                     MycAdminMethod::Get => "GET",
   1013                     MycAdminMethod::Post => "POST",
   1014                 })
   1015                 && wire.get("path").and_then(Value::as_str) == Some(route.path())
   1016                 && wire.get("operation_id").and_then(Value::as_str) == Some(route.operation_id())
   1017                 && wire.get("request_model").and_then(Value::as_str) == Some(route.request_model())
   1018                 && wire.get("response_model").and_then(Value::as_str)
   1019                     == Some(route.response_model())
   1020                 && wire.get("mutation").and_then(Value::as_bool) == Some(route.is_mutation())
   1021         })
   1022 }
   1023 
   1024 fn model_fields(model_name: &str) -> Result<&'static Map<String, Value>, MycAdminDocumentError> {
   1025     operator_contract()
   1026         .pointer(&format!("/admin/models/{model_name}/fields"))
   1027         .and_then(Value::as_object)
   1028         .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))
   1029 }
   1030 
   1031 fn type_descriptor(type_name: &str) -> Result<&'static Value, MycAdminDocumentError> {
   1032     operator_contract()
   1033         .pointer(&format!("/admin/types/{type_name}"))
   1034         .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))
   1035 }
   1036 
   1037 fn validate_model(model_name: &str, value: &Value) -> Result<(), MycAdminDocumentError> {
   1038     let object = value
   1039         .as_object()
   1040         .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))?;
   1041     let fields = model_fields(model_name)?;
   1042     for key in object.keys() {
   1043         if !fields.contains_key(key) {
   1044             return Err(MycAdminDocumentError::new(
   1045                 MycAdminDocumentErrorKind::InvalidModel,
   1046             ));
   1047         }
   1048     }
   1049     for (name, field) in fields {
   1050         let required = field.get("presence").and_then(Value::as_str) == Some("required");
   1051         let type_name = field
   1052             .get("type")
   1053             .and_then(Value::as_str)
   1054             .ok_or_else(|| MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel))?;
   1055         match object.get(name) {
   1056             Some(value) => validate_type(type_name, value, 0)?,
   1057             None if required => {
   1058                 return Err(MycAdminDocumentError::new(
   1059                     MycAdminDocumentErrorKind::InvalidModel,
   1060                 ));
   1061             }
   1062             None => {}
   1063         }
   1064     }
   1065     Ok(())
   1066 }
   1067 
   1068 fn validate_type(
   1069     type_name: &str,
   1070     value: &Value,
   1071     depth: usize,
   1072 ) -> Result<(), MycAdminDocumentError> {
   1073     if depth > 24 || value.is_null() {
   1074         return Err(MycAdminDocumentError::new(if value.is_null() {
   1075             MycAdminDocumentErrorKind::NullForbidden
   1076         } else {
   1077             MycAdminDocumentErrorKind::InvalidModel
   1078         }));
   1079     }
   1080     let descriptor = type_descriptor(type_name)?;
   1081     match descriptor.get("kind").and_then(Value::as_str) {
   1082         Some("literal") => {
   1083             if descriptor.get("value") != Some(value) {
   1084                 return invalid_model();
   1085             }
   1086         }
   1087         Some("boolean") => {
   1088             if !value.is_boolean() {
   1089                 return invalid_model();
   1090             }
   1091         }
   1092         Some("integer") => validate_integer(descriptor, value)?,
   1093         Some("string") => validate_string(descriptor, value)?,
   1094         Some("enum") => {
   1095             if !descriptor
   1096                 .get("values")
   1097                 .and_then(Value::as_array)
   1098                 .is_some_and(|values| values.contains(value))
   1099             {
   1100                 return invalid_model();
   1101             }
   1102         }
   1103         Some("string_union") => validate_string_union(descriptor, value)?,
   1104         Some("array") => validate_array(descriptor, value, depth + 1)?,
   1105         Some("canonical_delimited_set") => {
   1106             validate_delimited_set(descriptor, value, depth + 1)?;
   1107         }
   1108         Some("map") => validate_map(descriptor, value, depth + 1)?,
   1109         Some("closed_object") => validate_closed_object(descriptor, value, depth + 1)?,
   1110         Some("tagged_union") => validate_tagged_union(descriptor, value, depth + 1)?,
   1111         Some("alias") => validate_type(
   1112             descriptor
   1113                 .get("target")
   1114                 .and_then(Value::as_str)
   1115                 .ok_or_else(invalid_model_error)?,
   1116             value,
   1117             depth + 1,
   1118         )?,
   1119         Some("optional") => validate_type(
   1120             descriptor
   1121                 .get("value")
   1122                 .and_then(Value::as_str)
   1123                 .ok_or_else(invalid_model_error)?,
   1124             value,
   1125             depth + 1,
   1126         )?,
   1127         Some("canonical_json_object") => {
   1128             if !value.is_object()
   1129                 || serde_json::to_vec(value).ok().is_none_or(|bytes| {
   1130                     bytes.len()
   1131                         > descriptor
   1132                             .get("maximum_utf8_bytes")
   1133                             .and_then(Value::as_u64)
   1134                             .and_then(|value| usize::try_from(value).ok())
   1135                             .unwrap_or(0)
   1136                 })
   1137             {
   1138                 return invalid_model();
   1139             }
   1140         }
   1141         _ => return invalid_model(),
   1142     }
   1143     Ok(())
   1144 }
   1145 
   1146 fn validate_integer(descriptor: &Value, value: &Value) -> Result<(), MycAdminDocumentError> {
   1147     let number = value.as_u64().ok_or_else(invalid_model_error)?;
   1148     let minimum = descriptor
   1149         .get("minimum")
   1150         .and_then(Value::as_u64)
   1151         .unwrap_or(0);
   1152     let maximum = descriptor
   1153         .get("maximum")
   1154         .and_then(Value::as_u64)
   1155         .unwrap_or(u64::MAX);
   1156     if !(minimum..=maximum).contains(&number) {
   1157         return invalid_model();
   1158     }
   1159     Ok(())
   1160 }
   1161 
   1162 fn validate_string(descriptor: &Value, value: &Value) -> Result<(), MycAdminDocumentError> {
   1163     let string = value.as_str().ok_or_else(invalid_model_error)?;
   1164     let exact = descriptor
   1165         .get("utf8_bytes")
   1166         .and_then(Value::as_u64)
   1167         .and_then(|value| usize::try_from(value).ok());
   1168     let minimum = descriptor
   1169         .get("minimum_utf8_bytes")
   1170         .and_then(Value::as_u64)
   1171         .and_then(|value| usize::try_from(value).ok())
   1172         .unwrap_or(0);
   1173     let maximum = descriptor
   1174         .get("maximum_utf8_bytes")
   1175         .and_then(Value::as_u64)
   1176         .and_then(|value| usize::try_from(value).ok())
   1177         .unwrap_or(usize::MAX);
   1178     if exact.is_some_and(|exact| string.len() != exact)
   1179         || !(minimum..=maximum).contains(&string.len())
   1180         || string.chars().any(char::is_control)
   1181     {
   1182         return invalid_model();
   1183     }
   1184     if let Some(pattern) = descriptor.get("pattern").and_then(Value::as_str) {
   1185         let valid = match pattern {
   1186             "^[A-Za-z0-9][A-Za-z0-9._:-]*$" => bounded_id(string),
   1187             "^[a-z][a-z0-9_]*$" => safe_code(string),
   1188             "^[0-9a-f]{64}$" => lower_hex(string, 64),
   1189             "^[0-9a-f]{40}$" => lower_hex(string, 40),
   1190             "^/" => Path::new(string).is_absolute(),
   1191             _ => false,
   1192         };
   1193         if !valid {
   1194             return invalid_model();
   1195         }
   1196     }
   1197     if descriptor.get("encoding").and_then(Value::as_str) == Some("canonical_base64url_no_padding")
   1198     {
   1199         let decoded = URL_SAFE_NO_PAD
   1200             .decode(string)
   1201             .map_err(|_| invalid_model_error())?;
   1202         if URL_SAFE_NO_PAD.encode(decoded) != string {
   1203             return invalid_model();
   1204         }
   1205     }
   1206     if let Some(schemes) = descriptor.get("allowed_schemes").and_then(Value::as_array) {
   1207         let parsed = url::Url::parse(string).map_err(|_| invalid_model_error())?;
   1208         if !schemes
   1209             .iter()
   1210             .any(|scheme| scheme.as_str() == Some(parsed.scheme()))
   1211         {
   1212             return invalid_model();
   1213         }
   1214     }
   1215     Ok(())
   1216 }
   1217 
   1218 fn validate_string_union(descriptor: &Value, value: &Value) -> Result<(), MycAdminDocumentError> {
   1219     let string = value.as_str().ok_or_else(invalid_model_error)?;
   1220     if descriptor
   1221         .get("simple_values")
   1222         .and_then(Value::as_array)
   1223         .is_some_and(|values| values.iter().any(|value| value.as_str() == Some(string)))
   1224     {
   1225         return Ok(());
   1226     }
   1227     let kind = string
   1228         .strip_prefix("sign_event:kind:")
   1229         .ok_or_else(invalid_model_error)?;
   1230     if kind.is_empty()
   1231         || (kind.len() > 1 && kind.starts_with('0'))
   1232         || !kind.bytes().all(|byte| byte.is_ascii_digit())
   1233         || kind.parse::<u32>().is_err()
   1234         || string.len()
   1235             > descriptor
   1236                 .get("maximum_utf8_bytes")
   1237                 .and_then(Value::as_u64)
   1238                 .and_then(|value| usize::try_from(value).ok())
   1239                 .unwrap_or(0)
   1240     {
   1241         return invalid_model();
   1242     }
   1243     Ok(())
   1244 }
   1245 
   1246 fn validate_array(
   1247     descriptor: &Value,
   1248     value: &Value,
   1249     depth: usize,
   1250 ) -> Result<(), MycAdminDocumentError> {
   1251     let values = value.as_array().ok_or_else(invalid_model_error)?;
   1252     let maximum = descriptor
   1253         .get("maximum_items")
   1254         .and_then(Value::as_u64)
   1255         .and_then(|value| usize::try_from(value).ok())
   1256         .unwrap_or(0);
   1257     if values.len() > maximum {
   1258         return invalid_model();
   1259     }
   1260     let item_type = descriptor
   1261         .get("items")
   1262         .and_then(Value::as_str)
   1263         .ok_or_else(invalid_model_error)?;
   1264     for item in values {
   1265         validate_type(item_type, item, depth)?;
   1266     }
   1267     if descriptor.get("unique").and_then(Value::as_bool) == Some(true) {
   1268         let mut unique = BTreeSet::new();
   1269         for item in values {
   1270             let encoded = serde_json::to_vec(item).map_err(|_| invalid_model_error())?;
   1271             if !unique.insert(encoded) {
   1272                 return invalid_model();
   1273             }
   1274         }
   1275     }
   1276     if descriptor.get("canonical_sort").is_some() {
   1277         let rendered = values
   1278             .iter()
   1279             .map(|value| value.as_str().ok_or_else(invalid_model_error))
   1280             .collect::<Result<Vec<_>, _>>()?;
   1281         if !rendered.windows(2).all(|pair| pair[0] < pair[1]) {
   1282             return invalid_model();
   1283         }
   1284     }
   1285     Ok(())
   1286 }
   1287 
   1288 fn validate_delimited_set(
   1289     descriptor: &Value,
   1290     value: &Value,
   1291     depth: usize,
   1292 ) -> Result<(), MycAdminDocumentError> {
   1293     let rendered = value.as_str().ok_or_else(invalid_model_error)?;
   1294     let maximum_bytes = descriptor
   1295         .get("maximum_utf8_bytes")
   1296         .and_then(Value::as_u64)
   1297         .and_then(|value| usize::try_from(value).ok())
   1298         .unwrap_or(0);
   1299     if rendered.len() > maximum_bytes {
   1300         return invalid_model();
   1301     }
   1302     if rendered.is_empty() {
   1303         return if descriptor.get("empty_allowed").and_then(Value::as_bool) == Some(true) {
   1304             Ok(())
   1305         } else {
   1306             invalid_model()
   1307         };
   1308     }
   1309     let delimiter = descriptor
   1310         .get("delimiter")
   1311         .and_then(Value::as_str)
   1312         .filter(|delimiter| delimiter.len() == 1)
   1313         .ok_or_else(invalid_model_error)?;
   1314     let items = rendered.split(delimiter).collect::<Vec<_>>();
   1315     let maximum_items = descriptor
   1316         .get("maximum_items")
   1317         .and_then(Value::as_u64)
   1318         .and_then(|value| usize::try_from(value).ok())
   1319         .unwrap_or(0);
   1320     if items.is_empty()
   1321         || items.len() > maximum_items
   1322         || items.iter().any(|item| item.is_empty())
   1323         || !items.windows(2).all(|pair| pair[0] < pair[1])
   1324     {
   1325         return invalid_model();
   1326     }
   1327     let item_type = descriptor
   1328         .get("items")
   1329         .and_then(Value::as_str)
   1330         .ok_or_else(invalid_model_error)?;
   1331     for item in items {
   1332         validate_type(item_type, &Value::String(item.to_owned()), depth)?;
   1333     }
   1334     Ok(())
   1335 }
   1336 
   1337 fn validate_map(
   1338     descriptor: &Value,
   1339     value: &Value,
   1340     depth: usize,
   1341 ) -> Result<(), MycAdminDocumentError> {
   1342     let values = value.as_object().ok_or_else(invalid_model_error)?;
   1343     let maximum_entries = descriptor
   1344         .get("maximum_entries")
   1345         .and_then(Value::as_u64)
   1346         .and_then(|value| usize::try_from(value).ok())
   1347         .unwrap_or(0);
   1348     if values.len() > maximum_entries {
   1349         return invalid_model();
   1350     }
   1351     let key_type = descriptor
   1352         .get("key")
   1353         .and_then(Value::as_str)
   1354         .ok_or_else(invalid_model_error)?;
   1355     let value_type = descriptor
   1356         .get("value")
   1357         .and_then(Value::as_str)
   1358         .ok_or_else(invalid_model_error)?;
   1359     for (key, value) in values {
   1360         validate_type(key_type, &Value::String(key.clone()), depth)?;
   1361         validate_type(value_type, value, depth)?;
   1362     }
   1363     Ok(())
   1364 }
   1365 
   1366 fn validate_closed_object(
   1367     descriptor: &Value,
   1368     value: &Value,
   1369     depth: usize,
   1370 ) -> Result<(), MycAdminDocumentError> {
   1371     let values = value.as_object().ok_or_else(invalid_model_error)?;
   1372     let fields = descriptor
   1373         .get("fields")
   1374         .and_then(Value::as_object)
   1375         .ok_or_else(invalid_model_error)?;
   1376     if values.keys().any(|key| !fields.contains_key(key)) {
   1377         return invalid_model();
   1378     }
   1379     for (field, type_name) in fields {
   1380         let type_name = type_name.as_str().ok_or_else(invalid_model_error)?;
   1381         match values.get(field) {
   1382             Some(value) => validate_type(type_name, value, depth)?,
   1383             None if type_descriptor(type_name)?
   1384                 .get("kind")
   1385                 .and_then(Value::as_str)
   1386                 == Some("optional") => {}
   1387             None => return invalid_model(),
   1388         }
   1389     }
   1390     Ok(())
   1391 }
   1392 
   1393 fn validate_tagged_union(
   1394     descriptor: &Value,
   1395     value: &Value,
   1396     depth: usize,
   1397 ) -> Result<(), MycAdminDocumentError> {
   1398     let object = value.as_object().ok_or_else(invalid_model_error)?;
   1399     let discriminator = descriptor
   1400         .get("discriminator")
   1401         .and_then(Value::as_str)
   1402         .ok_or_else(invalid_model_error)?;
   1403     let selected = object.get(discriminator).ok_or_else(invalid_model_error)?;
   1404     let variants = descriptor
   1405         .get("variants")
   1406         .and_then(Value::as_array)
   1407         .ok_or_else(invalid_model_error)?;
   1408     let mut matched = None;
   1409     for variant in variants {
   1410         let variant = variant.as_str().ok_or_else(invalid_model_error)?;
   1411         let fields = type_descriptor(variant)?
   1412             .get("fields")
   1413             .and_then(Value::as_object)
   1414             .ok_or_else(invalid_model_error)?;
   1415         let discriminator_type = fields
   1416             .get(discriminator)
   1417             .and_then(Value::as_str)
   1418             .ok_or_else(invalid_model_error)?;
   1419         if type_descriptor(discriminator_type)?.get("value") == Some(selected)
   1420             && matched.replace(variant).is_some()
   1421         {
   1422             return invalid_model();
   1423         }
   1424     }
   1425     validate_type(matched.ok_or_else(invalid_model_error)?, value, depth)
   1426 }
   1427 
   1428 fn bounded_id(value: &str) -> bool {
   1429     (1..=128).contains(&value.len())
   1430         && value
   1431             .as_bytes()
   1432             .first()
   1433             .is_some_and(u8::is_ascii_alphanumeric)
   1434         && value
   1435             .bytes()
   1436             .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b':' | b'-'))
   1437 }
   1438 
   1439 fn safe_code(value: &str) -> bool {
   1440     (1..=64).contains(&value.len())
   1441         && value.as_bytes().first().is_some_and(u8::is_ascii_lowercase)
   1442         && value
   1443             .bytes()
   1444             .all(|byte| byte.is_ascii_lowercase() || byte.is_ascii_digit() || byte == b'_')
   1445 }
   1446 
   1447 fn lower_hex(value: &str, exact: usize) -> bool {
   1448     value.len() == exact
   1449         && value
   1450             .bytes()
   1451             .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
   1452 }
   1453 
   1454 fn invalid_model<T>() -> Result<T, MycAdminDocumentError> {
   1455     Err(invalid_model_error())
   1456 }
   1457 
   1458 const fn invalid_model_error() -> MycAdminDocumentError {
   1459     MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel)
   1460 }
   1461 
   1462 const DUPLICATE_MARKER: &str = "myc_admin_duplicate_field";
   1463 const NULL_MARKER: &str = "myc_admin_null_forbidden";
   1464 
   1465 fn strict_json(bytes: &[u8]) -> Result<Value, MycAdminDocumentError> {
   1466     let mut deserializer = serde_json::Deserializer::from_slice(bytes);
   1467     let value = StrictValueSeed
   1468         .deserialize(&mut deserializer)
   1469         .map_err(|error| {
   1470             let message = error.to_string();
   1471             if message.contains(DUPLICATE_MARKER) {
   1472                 MycAdminDocumentError::new(MycAdminDocumentErrorKind::DuplicateField)
   1473             } else if message.contains(NULL_MARKER) {
   1474                 MycAdminDocumentError::new(MycAdminDocumentErrorKind::NullForbidden)
   1475             } else {
   1476                 MycAdminDocumentError::new(MycAdminDocumentErrorKind::Malformed)
   1477             }
   1478         })?;
   1479     deserializer
   1480         .end()
   1481         .map_err(|_| MycAdminDocumentError::new(MycAdminDocumentErrorKind::Malformed))?;
   1482     Ok(value)
   1483 }
   1484 
   1485 struct StrictValueSeed;
   1486 
   1487 impl<'de> DeserializeSeed<'de> for StrictValueSeed {
   1488     type Value = Value;
   1489 
   1490     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
   1491     where
   1492         D: serde::Deserializer<'de>,
   1493     {
   1494         deserializer.deserialize_any(StrictValueVisitor)
   1495     }
   1496 }
   1497 
   1498 struct StrictValueVisitor;
   1499 
   1500 impl<'de> Visitor<'de> for StrictValueVisitor {
   1501     type Value = Value;
   1502 
   1503     fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
   1504         formatter.write_str("a non-null JSON value")
   1505     }
   1506 
   1507     fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
   1508         Ok(Value::Bool(value))
   1509     }
   1510 
   1511     fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
   1512         Ok(Value::from(value))
   1513     }
   1514 
   1515     fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
   1516         Ok(Value::from(value))
   1517     }
   1518 
   1519     fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
   1520     where
   1521         E: de::Error,
   1522     {
   1523         serde_json::Number::from_f64(value)
   1524             .map(Value::Number)
   1525             .ok_or_else(|| E::custom("invalid JSON number"))
   1526     }
   1527 
   1528     fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> {
   1529         Ok(Value::String(value.to_owned()))
   1530     }
   1531 
   1532     fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
   1533         Ok(Value::String(value))
   1534     }
   1535 
   1536     fn visit_none<E>(self) -> Result<Self::Value, E>
   1537     where
   1538         E: de::Error,
   1539     {
   1540         Err(E::custom(NULL_MARKER))
   1541     }
   1542 
   1543     fn visit_unit<E>(self) -> Result<Self::Value, E>
   1544     where
   1545         E: de::Error,
   1546     {
   1547         Err(E::custom(NULL_MARKER))
   1548     }
   1549 
   1550     fn visit_seq<A>(self, mut sequence: A) -> Result<Self::Value, A::Error>
   1551     where
   1552         A: SeqAccess<'de>,
   1553     {
   1554         let mut values = Vec::new();
   1555         while let Some(value) = sequence.next_element_seed(StrictValueSeed)? {
   1556             values.push(value);
   1557         }
   1558         Ok(Value::Array(values))
   1559     }
   1560 
   1561     fn visit_map<A>(self, mut object: A) -> Result<Self::Value, A::Error>
   1562     where
   1563         A: MapAccess<'de>,
   1564     {
   1565         let mut values = Map::new();
   1566         while let Some(key) = object.next_key::<String>()? {
   1567             if values.contains_key(&key) {
   1568                 return Err(de::Error::custom(DUPLICATE_MARKER));
   1569             }
   1570             let value = object.next_value_seed(StrictValueSeed)?;
   1571             values.insert(key, value);
   1572         }
   1573         Ok(Value::Object(values))
   1574     }
   1575 }
   1576 
   1577 #[cfg(test)]
   1578 mod tests {
   1579     use super::*;
   1580 
   1581     fn sample_model(model_name: &str) -> Value {
   1582         let fields = model_fields(model_name).expect("governed model");
   1583         let mut object = Map::new();
   1584         for (name, field) in fields {
   1585             if field.get("presence").and_then(Value::as_str) == Some("required") {
   1586                 let type_name = field
   1587                     .get("type")
   1588                     .and_then(Value::as_str)
   1589                     .expect("field type");
   1590                 object.insert(name.clone(), sample_type(type_name).expect("required type"));
   1591             }
   1592         }
   1593         Value::Object(object)
   1594     }
   1595 
   1596     fn sample_type(type_name: &str) -> Option<Value> {
   1597         let descriptor = type_descriptor(type_name).expect("governed type");
   1598         match descriptor
   1599             .get("kind")
   1600             .and_then(Value::as_str)
   1601             .expect("type kind")
   1602         {
   1603             "literal" => Some(descriptor.get("value").expect("literal value").clone()),
   1604             "boolean" => Some(Value::Bool(false)),
   1605             "integer" => Some(Value::from(
   1606                 descriptor
   1607                     .get("minimum")
   1608                     .and_then(Value::as_u64)
   1609                     .unwrap_or(0),
   1610             )),
   1611             "string" => {
   1612                 let value = if descriptor.get("encoding").is_some() {
   1613                     "AA".to_owned()
   1614                 } else if descriptor.get("allowed_schemes").is_some() {
   1615                     "https://example.test/".to_owned()
   1616                 } else if descriptor.get("pattern").and_then(Value::as_str) == Some("^/") {
   1617                     "/tmp/myc".to_owned()
   1618                 } else if let Some(length) = descriptor.get("utf8_bytes").and_then(Value::as_u64) {
   1619                     "0".repeat(usize::try_from(length).expect("bounded sample length"))
   1620                 } else {
   1621                     "x".to_owned()
   1622                 };
   1623                 Some(Value::String(value))
   1624             }
   1625             "enum" => descriptor
   1626                 .get("values")
   1627                 .and_then(Value::as_array)
   1628                 .and_then(|values| values.first())
   1629                 .cloned(),
   1630             "string_union" => descriptor
   1631                 .get("simple_values")
   1632                 .and_then(Value::as_array)
   1633                 .and_then(|values| values.first())
   1634                 .cloned(),
   1635             "array" => Some(Value::Array(Vec::new())),
   1636             "canonical_delimited_set" => Some(Value::String(String::new())),
   1637             "map" | "canonical_json_object" => Some(Value::Object(Map::new())),
   1638             "closed_object" => {
   1639                 let mut object = Map::new();
   1640                 for (field, field_type) in descriptor
   1641                     .get("fields")
   1642                     .and_then(Value::as_object)
   1643                     .expect("closed fields")
   1644                 {
   1645                     if let Some(value) = sample_type(field_type.as_str().expect("closed type")) {
   1646                         object.insert(field.clone(), value);
   1647                     }
   1648                 }
   1649                 Some(Value::Object(object))
   1650             }
   1651             "tagged_union" => descriptor
   1652                 .get("variants")
   1653                 .and_then(Value::as_array)
   1654                 .and_then(|variants| variants.first())
   1655                 .and_then(Value::as_str)
   1656                 .and_then(sample_type),
   1657             "alias" => descriptor
   1658                 .get("target")
   1659                 .and_then(Value::as_str)
   1660                 .and_then(sample_type),
   1661             "optional" => None,
   1662             kind => panic!("unsupported governed kind {kind}"),
   1663         }
   1664     }
   1665 
   1666     fn response_document(route: MycAdminRoute) -> MycAdminResponseDocument {
   1667         let value = sample_model(route.response_model());
   1668         validate_model(route.response_model(), &value).expect("generated response model");
   1669         let bytes = serde_json::to_vec(&value).expect("canonical response bytes");
   1670         MycAdminResponseDocument::from_canonical_bytes(route, &bytes)
   1671             .expect("admitted response document")
   1672     }
   1673 
   1674     #[test]
   1675     fn complete_route_and_model_inventory_matches_the_machine_contract() {
   1676         assert!(operator_route_inventory_is_exact());
   1677         assert_eq!(MycAdminRoute::ALL.len(), 19);
   1678         let referenced = MycAdminRoute::ALL
   1679             .into_iter()
   1680             .flat_map(|route| [route.request_model(), route.response_model()])
   1681             .collect::<BTreeSet<_>>();
   1682         let governed = operator_contract()["admin"]["models"]
   1683             .as_object()
   1684             .expect("model inventory")
   1685             .keys()
   1686             .map(String::as_str)
   1687             .collect::<BTreeSet<_>>();
   1688         assert_eq!(referenced, governed);
   1689         assert_eq!(governed.len(), 32);
   1690         for model in governed {
   1691             let value = sample_model(model);
   1692             validate_model(model, &value).expect("minimum exact model");
   1693         }
   1694     }
   1695 
   1696     #[test]
   1697     fn strict_response_admission_rejects_duplicates_null_and_noncanonical_bytes() {
   1698         let route = MycAdminRoute::IdentityPublic;
   1699         let valid = response_document(route);
   1700         assert_eq!(valid.route(), route);
   1701         assert!(!valid.canonical_bytes().is_empty());
   1702 
   1703         let duplicate = br#"{"generation":0,"generation":1,"public_key":"0000000000000000000000000000000000000000000000000000000000000000","role":"transport"}"#;
   1704         assert_eq!(
   1705             MycAdminResponseDocument::from_canonical_bytes(route, duplicate)
   1706                 .expect_err("duplicate key")
   1707                 .kind(),
   1708             MycAdminDocumentErrorKind::DuplicateField
   1709         );
   1710         let nested_null = br#"{"generation":0,"public_key":null,"role":"transport"}"#;
   1711         assert_eq!(
   1712             MycAdminResponseDocument::from_canonical_bytes(route, nested_null)
   1713                 .expect_err("nested null")
   1714                 .kind(),
   1715             MycAdminDocumentErrorKind::NullForbidden
   1716         );
   1717         let noncanonical = format!(" {}", String::from_utf8_lossy(valid.canonical_bytes()));
   1718         assert_eq!(
   1719             MycAdminResponseDocument::from_canonical_bytes(route, noncanonical.as_bytes())
   1720                 .expect_err("whitespace")
   1721                 .kind(),
   1722             MycAdminDocumentErrorKind::NonCanonical
   1723         );
   1724         let invalid = br#"{"generation":0,"public_key":"0000000000000000000000000000000000000000000000000000000000000000","role":"administrator"}"#;
   1725         assert_eq!(
   1726             MycAdminResponseDocument::from_canonical_bytes(route, invalid)
   1727                 .expect_err("invalid model")
   1728                 .kind(),
   1729             MycAdminDocumentErrorKind::InvalidModel
   1730         );
   1731         assert_eq!(
   1732             MycAdminResponseDocument::from_canonical_bytes(route, b"")
   1733                 .expect_err("empty response")
   1734                 .kind(),
   1735             MycAdminDocumentErrorKind::Malformed
   1736         );
   1737         let oversized = vec![b' '; MYC_ADMIN_RESPONSE_BODY_MAX_UTF8_BYTES + 1];
   1738         assert_eq!(
   1739             MycAdminResponseDocument::from_canonical_bytes(route, &oversized)
   1740                 .expect_err("oversized response")
   1741                 .kind(),
   1742             MycAdminDocumentErrorKind::TooLarge
   1743         );
   1744         assert_eq!(
   1745             format!("{valid:?}"),
   1746             "MycAdminResponseDocument { route: IdentityPublic, model: \"[redacted]\" }"
   1747         );
   1748     }
   1749 
   1750     #[test]
   1751     fn query_and_nested_type_admission_is_exact_and_bounded() {
   1752         let connections = query_model(
   1753             MycAdminRoute::ConnectionsList,
   1754             Some("cursor=AA&limit=200&state=approved"),
   1755         )
   1756         .expect("canonical query");
   1757         validate_model("connections_query_v1", &connections).expect("query model");
   1758         for invalid in [
   1759             "limit=01",
   1760             "limit=201",
   1761             "limit=1&limit=2",
   1762             "unknown=x",
   1763             "cursor=%",
   1764             "state=administrator",
   1765         ] {
   1766             let result = query_model(MycAdminRoute::ConnectionsList, Some(invalid))
   1767                 .and_then(|value| validate_model("connections_query_v1", &value));
   1768             assert!(result.is_err(), "query `{invalid}` unexpectedly passed");
   1769         }
   1770         for valid in [
   1771             "",
   1772             "nip04_decrypt",
   1773             "sign_event:kind:0",
   1774             "nip04_decrypt,sign_event:kind:1",
   1775         ] {
   1776             validate_type("permission_set", &Value::String(valid.to_owned()), 0)
   1777                 .expect("permission set");
   1778         }
   1779         for invalid in [
   1780             "sign_event:kind:00",
   1781             "sign_event:kind:4294967296",
   1782             "sign_event:kind:1,nip04_decrypt",
   1783             "nip04_decrypt,nip04_decrypt",
   1784         ] {
   1785             assert!(
   1786                 validate_type("permission_set", &Value::String(invalid.to_owned()), 0).is_err()
   1787             );
   1788         }
   1789         assert!(
   1790             validate_type(
   1791                 "safe_url",
   1792                 &Value::String("http://example.test/".to_owned()),
   1793                 0
   1794             )
   1795             .is_err()
   1796         );
   1797         assert!(validate_type("bounded_id", &Value::String("../escape".to_owned()), 0).is_err());
   1798     }
   1799 
   1800     #[test]
   1801     fn public_diagnostics_are_source_free_and_content_free() {
   1802         let document = MycAdminDocumentError::new(MycAdminDocumentErrorKind::InvalidModel);
   1803         let handler = MycAdminHandlerError::new(MycAdminHandlerErrorKind::Internal);
   1804         let server = MycAdminServerError::new(MycAdminServerErrorKind::Bind);
   1805         for rendered in [
   1806             format!("{document}"),
   1807             format!("{document:?}"),
   1808             format!("{handler}"),
   1809             format!("{handler:?}"),
   1810             format!("{server}"),
   1811             format!("{server:?}"),
   1812         ] {
   1813             assert!(!rendered.contains("/tmp/protected"));
   1814             assert!(!rendered.contains("credential"));
   1815         }
   1816         assert!(Error::source(&document).is_none());
   1817         assert!(Error::source(&handler).is_none());
   1818         assert!(Error::source(&server).is_none());
   1819         assert_eq!(server.code(), "admin_bind_failed");
   1820     }
   1821 
   1822     #[cfg(any(target_os = "linux", target_os = "macos"))]
   1823     mod native {
   1824         use core::sync::atomic::{AtomicUsize, Ordering};
   1825         use std::fs;
   1826         use std::sync::Mutex;
   1827 
   1828         use radroots_service_host::{AdminClient, AdminClientTarget, AdminTransportLimits};
   1829 
   1830         use super::*;
   1831         use tokio::io::{AsyncReadExt, AsyncWriteExt};
   1832 
   1833         const CONFIG: &str = include_str!("../contracts/services_hardening/config.v1.example.toml");
   1834 
   1835         type FixtureCall = (MycAdminRoute, Option<String>, Box<[u8]>);
   1836 
   1837         struct FixtureHandler {
   1838             calls: Mutex<Vec<FixtureCall>>,
   1839             invalid_cursor: AtomicUsize,
   1840             decoded_parameter: AtomicUsize,
   1841         }
   1842 
   1843         impl FixtureHandler {
   1844             fn new() -> Self {
   1845                 Self {
   1846                     calls: Mutex::new(Vec::new()),
   1847                     invalid_cursor: AtomicUsize::new(0),
   1848                     decoded_parameter: AtomicUsize::new(0),
   1849                 }
   1850             }
   1851         }
   1852 
   1853         impl MycAdminHandler for FixtureHandler {
   1854             fn handle<'a>(&'a self, request: MycAdminRequestDocument) -> MycAdminFuture<'a> {
   1855                 Box::pin(async move {
   1856                     if request.route() == MycAdminRoute::ConnectionsList
   1857                         && request
   1858                             .model_bytes()
   1859                             .windows(4)
   1860                             .any(|window| window == b"\"eA\"")
   1861                     {
   1862                         self.invalid_cursor.fetch_add(1, Ordering::SeqCst);
   1863                         return Err(MycAdminHandlerError::new(
   1864                             MycAdminHandlerErrorKind::InvalidCursor,
   1865                         ));
   1866                     }
   1867                     if request.operation_id() == Some("conflict") {
   1868                         return Err(MycAdminHandlerError::new(
   1869                             MycAdminHandlerErrorKind::OperationIdConflict,
   1870                         ));
   1871                     }
   1872                     if request.parameter("connection_id") == Some("connection-encoded") {
   1873                         self.decoded_parameter.fetch_add(1, Ordering::SeqCst);
   1874                         return Ok(response_document(request.route()));
   1875                     }
   1876                     self.calls.lock().expect("calls").push((
   1877                         request.route(),
   1878                         request.operation_id().map(str::to_owned),
   1879                         request.model_bytes().into(),
   1880                     ));
   1881                     Ok(response_document(request.route()))
   1882                 })
   1883             }
   1884         }
   1885 
   1886         fn runtime_context() -> (
   1887             tempfile::TempDir,
   1888             crate::MycRuntimeContext,
   1889             crate::MycConfigDocumentV1,
   1890         ) {
   1891             let root = tempfile::Builder::new()
   1892                 .prefix("myc-admin-")
   1893                 .tempdir_in("/tmp")
   1894                 .expect("short runtime root");
   1895             let root_path = root.path().to_str().expect("UTF-8 test root");
   1896             let invocation = crate::parse_myc_cli_v1_from([
   1897                 "myc",
   1898                 "--profile",
   1899                 "repo-local",
   1900                 "--instance",
   1901                 "primary",
   1902                 "--repo-local-root",
   1903                 root_path,
   1904                 "run",
   1905             ])
   1906             .expect("test CLI");
   1907             let resolver = crate::RadrootsPathResolver::new(
   1908                 crate::RadrootsPlatform::Linux,
   1909                 crate::RadrootsHostEnvironment::default(),
   1910             );
   1911             let runtime = crate::resolve_myc_runtime_context(&resolver, &invocation)
   1912                 .expect("test runtime context");
   1913             fs::create_dir_all(runtime.context().paths().run()).expect("runtime directory");
   1914             let configuration =
   1915                 crate::parse_myc_config_v1(CONFIG.as_bytes(), crate::MycConfigProfile::RepoLocal)
   1916                     .expect("test configuration");
   1917             (root, runtime, configuration)
   1918         }
   1919 
   1920         fn target_for(route: MycAdminRoute, request: &Value) -> AdminClientTarget {
   1921             let path = route
   1922                 .path()
   1923                 .replace("{connection_id}", "connection-1")
   1924                 .replace("{challenge_id}", "challenge-1");
   1925             if !matches!(route.method(), MycAdminMethod::Get)
   1926                 || request.as_object().is_some_and(Map::is_empty)
   1927             {
   1928                 return AdminClientTarget::new(path).expect("route target");
   1929             }
   1930             let mut serializer = url::form_urlencoded::Serializer::new(String::new());
   1931             for (name, value) in request.as_object().expect("query object") {
   1932                 let rendered = value
   1933                     .as_str()
   1934                     .map(str::to_owned)
   1935                     .unwrap_or_else(|| value.to_string());
   1936                 serializer.append_pair(name, &rendered);
   1937             }
   1938             AdminClientTarget::new(format!("{path}?{}", serializer.finish())).expect("query target")
   1939         }
   1940 
   1941         async fn raw_post(socket: &Path, body: &str) -> String {
   1942             let mut stream = tokio::net::UnixStream::connect(socket)
   1943                 .await
   1944                 .expect("raw connection");
   1945             let request = format!(
   1946                 "POST /v1/discovery/render HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{body}",
   1947                 body.len()
   1948             );
   1949             stream
   1950                 .write_all(request.as_bytes())
   1951                 .await
   1952                 .expect("raw request");
   1953             let mut response = Vec::new();
   1954             stream
   1955                 .read_to_end(&mut response)
   1956                 .await
   1957                 .expect("raw response");
   1958             String::from_utf8(response).expect("HTTP response")
   1959         }
   1960 
   1961         #[tokio::test]
   1962         async fn all_nineteen_routes_round_trip_over_the_hardened_unix_boundary() {
   1963             let (_root, runtime, configuration) = runtime_context();
   1964             let socket = runtime.artifacts().admin_socket().to_path_buf();
   1965             let handler = Arc::new(FixtureHandler::new());
   1966             let server = MycAdminServer::new(&configuration, Arc::clone(&handler))
   1967                 .expect("production admin server")
   1968                 .bind(&runtime)
   1969                 .await
   1970                 .expect("canonical admin binding");
   1971             let cancellation = MycAdminCancellationToken::new();
   1972             let server_cancellation = cancellation.clone();
   1973             let task = tokio::spawn(async move {
   1974                 server
   1975                     .serve(server_cancellation)
   1976                     .await
   1977                     .expect("serve Myc admin");
   1978             });
   1979             let client =
   1980                 AdminClient::new(&socket, AdminTransportLimits::DEFAULT).expect("admin client");
   1981 
   1982             for (index, route) in MycAdminRoute::ALL.into_iter().enumerate() {
   1983                 let request = sample_model(route.request_model());
   1984                 let target = target_for(route, &request);
   1985                 let response = match route.method() {
   1986                     MycAdminMethod::Get => client.get::<Value>(&target).await.expect("GET route"),
   1987                     MycAdminMethod::Post => {
   1988                         let operation_id = AdminOperationId::new(format!("operation-{index}"))
   1989                             .expect("operation ID");
   1990                         client
   1991                             .mutate::<_, Value>(&target, operation_id, None, &request)
   1992                             .await
   1993                             .expect("POST route")
   1994                     }
   1995                 };
   1996                 validate_model(route.response_model(), response.result())
   1997                     .expect("route response model");
   1998             }
   1999 
   2000             let cursor_target =
   2001                 AdminClientTarget::new("/v1/connections?cursor=eA&limit=1").expect("cursor target");
   2002             let cursor_error = client
   2003                 .get::<Value>(&cursor_target)
   2004                 .await
   2005                 .expect_err("handler rejects unbound cursor");
   2006             assert_eq!(
   2007                 cursor_error
   2008                     .failure()
   2009                     .expect("failure envelope")
   2010                     .error()
   2011                     .code()
   2012                     .as_str(),
   2013                 "invalid_cursor"
   2014             );
   2015             assert_eq!(handler.invalid_cursor.load(Ordering::SeqCst), 1);
   2016 
   2017             let conflict_target =
   2018                 AdminClientTarget::new("/v1/discovery/render").expect("mutation target");
   2019             let conflict_error = client
   2020                 .mutate::<_, Value>(
   2021                     &conflict_target,
   2022                     AdminOperationId::new("conflict").expect("operation ID"),
   2023                     None,
   2024                     sample_model("discovery_render_request_v1"),
   2025                 )
   2026                 .await
   2027                 .expect_err("operation conflict");
   2028             assert_eq!(
   2029                 conflict_error
   2030                     .failure()
   2031                     .expect("failure envelope")
   2032                     .error()
   2033                     .code()
   2034                     .as_str(),
   2035                 "operation_id_conflict"
   2036             );
   2037 
   2038             for body in [
   2039                 r#"{"contract_version":1,"operation_id":"duplicate","request":{"expected_generation":0,"expected_generation":1}}"#,
   2040                 r#"{"contract_version":1,"operation_id":"null","request":{"expected_generation":null}}"#,
   2041             ] {
   2042                 let response = raw_post(&socket, body).await;
   2043                 assert!(response.starts_with("HTTP/1.1 400 "), "{response}");
   2044             }
   2045 
   2046             let encoded_target =
   2047                 AdminClientTarget::new("/v1/connections/connection%2Dencoded/approve")
   2048                     .expect("encoded parameter target");
   2049             client
   2050                 .mutate::<_, Value>(
   2051                     &encoded_target,
   2052                     AdminOperationId::new("encoded-parameter").expect("operation ID"),
   2053                     None,
   2054                     sample_model("connection_approve_request_v1"),
   2055                 )
   2056                 .await
   2057                 .expect("percent-decoded path parameter");
   2058             assert_eq!(handler.decoded_parameter.load(Ordering::SeqCst), 1);
   2059 
   2060             {
   2061                 let calls = handler.calls.lock().expect("calls");
   2062                 assert_eq!(calls.len(), 19);
   2063                 for (index, (route, operation_id, request)) in calls.iter().enumerate() {
   2064                     assert_eq!(*route, MycAdminRoute::ALL[index]);
   2065                     assert_eq!(operation_id.is_some(), route.is_mutation());
   2066                     validate_model(
   2067                         route.request_model(),
   2068                         &serde_json::from_slice(request).expect("retained request model"),
   2069                     )
   2070                     .expect("retained exact model");
   2071                 }
   2072             }
   2073             cancellation.cancel();
   2074             task.await.expect("server task");
   2075             assert!(!socket.exists());
   2076         }
   2077 
   2078         #[test]
   2079         fn production_server_projects_exact_validated_admin_limits() {
   2080             let (_root, _runtime, configuration) = runtime_context();
   2081             assert_eq!(
   2082                 admin_transport_limits(&configuration).expect("admin limits"),
   2083                 AdminTransportLimits::DEFAULT
   2084             );
   2085         }
   2086     }
   2087 }