# AS-01 — propuesta de autoridad, revocación y frescura para P1

**Diseño de referencia:** AS-01-proposal-01, 2026-10-19. **Estado actual:**
A1–A6 / D04–D06 [adoptadas como dirección](https://xcim.org/standardization/source/ACCEPTED-A1-A6.md) por instrucción
explícita del usuario. [AS01-F01](https://xcim.org/standardization/as01/README.md) concreta schemas y fixtures;
las [dependencias](https://xcim.org/standardization/as01/DEPENDENCIES.md) y el cierre M/O siguen pendientes.
Este texto conserva el razonamiento y alternativas del diseño. No cambia
WD-02-E1, los objetos P1-01 ni sus 135 casos. Los sitios distribuyen material
de desarrollo; no hay verificador de anchor AS ni autoridad operativa acreditada.

## 1. Recomendación concreta y decisión solicitada

Recomiendo desarrollar **AS-01 como perfil nuevo explícito**: raíz de confianza
provisionada por el receiver, manifiesto de autoridad firmado por esa raíz,
checkpoint que vincule permiso y autoridad del mismo corte y una cabeza de
control firmada con otra clave. El checkpoint requiere publicación anclada
independientemente verificada. La presentación puede adjuntar la evidencia o
permitir recuperarla de mirrors; no exige consultar al issuer por mensaje.

| Decisión | Recomendación | Alternativas | Motivo y coste |
|---|---|---|---|
| D04 — bootstrap y autoridad | Pins locales explícitos por issuer/log como mínimo; raíz de mantenimiento y recuperación separadas; roles y ámbitos verificables. Dejar una ruta de registry autenticado para una extensión posterior. | Descubrimiento HTTPS autoautorizado; registry universal obligatorio; Web PKI/DNS como única identidad de app; pins sin lifecycle. | Evita inventar una autoridad global. Requiere distribuir pins y updates autenticados; un certificado HTTPS no acredita al Consent Issuer. |
| D05 — estado y frescura | Estados probados del mismo corte, expiración exclusiva, deadlines por evidencia, high-water marks persistentes y resultado sin señal positiva ante dependencia ausente. | Status HTTP por mensaje; CRL/lista completa; sólo expiración de MSA/MP; extender caché en fallos. | Permite caché/stapling acotados y revocación de permisos y claves. Cuesta generar y transportar pruebas; no ofrece revocación instantánea. |
| D06 — publicación | Checkpoint compuesto nuevo con anclaje externo seleccionado explícitamente. Mantener Amoy como entorno experimental; diseñar su adaptador AS antes de probarlo. | Sólo firma del issuer; log con monitores/testigos; nuevo perfil sin cadena; reinterpretar el anchor Amoy 0.1. | Conserva la exigencia de publicación del core. Necesita adaptador/ABI y política de finality nuevos; una firma o log aislado no elimina split views. |

**Dirección adoptada:** A1–A6 de §12, registrada en ACCEPTED-A1-A6.md. La recomendación es A1/A2/A3/A4
como aquí, A5 con parámetros iniciales medibles y A6 con pins locales primero.
La adopción habilitó schemas y vectores AS; no cierra G04–G06 M/O.

## 2. Garantías y límites

El receiver debe poder responder cinco preguntas separadas:

1. ¿Acepto a este issuer y este log bajo mi política, para este perfil?
2. ¿Qué clave podía firmar cada objeto al emitirlo y conserva autoridad actual?
3. ¿Siguen activos la app/epoch, los dominios, la MSA y su clave MP?
4. ¿Sigue activo exactamente este permiso del destinatario/app/propósito?
5. ¿Hasta cuándo es utilizable esta evidencia, y he observado algo posterior?

No se prueba la veracidad del consentimiento frente a un issuer deshonesto.
Un anchor autentica compromisos y orden bajo su política; no valida la
autorización del cambio de estado ni la verdad de sus hojas. El receiver sigue
confiando en las atestaciones de autoridad/consentimiento y, salvo que replique
y compruebe todo el log, en la proyección firmada del estado. Se requieren
monitores para detectar transiciones inválidas. Separar claves dentro del
mismo operador no equivale a operadores independientes.

Una revocación desconocida puede quedar oculta durante la ventana de evidencia
todavía válida. La propuesta ofrece una **cota de antigüedad**, no conocimiento
instantáneo del último estado mundial. Si se observa una revocación o cabeza
más nueva, no se puede seguir usando una anterior aunque aún no haya vencido.

## 3. Contratos candidatos y bytes

Se proponen siete contratos principales C1–C7 y un registro de lifecycle C8.
Los schemas y fixtures ejecutables actuales se publican en AS01-F01, con
concreciones de C1/C7 documentadas en su CONTRACT.md. Falta el Proof verifier
con anchor vivo; los checks de AS y P1 son offline y no emiten XCIM_PASS.

Para nuevos objetos AS: JSON estricto/E1, JCS y enteros seguros; tiempos
`iat`, `exp`, `this_update`, `next_update`, `effective_at` en segundos Unix UTC.
Intervalos `[inicio, fin)`. Identificadores existentes se comparan exactamente;
hashes/thumbprints nuevos son base64url canónico de 32 octetos. No emitir
direcciones ni PII en los objetos públicos. Los objetos son cerrados salvo
uniones enumeradas aquí; un campo crítico desconocido no se ignora.

Payloads firmados usan `proposal_version: "as-01"`, `object_type` exacto,
`issuer_id` y `log_id` donde corresponda. JWS flattened de P1 para una firma;
para quórum, objeto cerrado `{payload, signatures}` y firmas cerradas
`{protected, signature}`, ambas cadenas base64url. Cada protected es
`{alg, kid, typ}`, JCS, `alg: "Ed25519"`; `kid` selecciona una clave previamente
autorizada, nunca una URL. Distintos firmantes se cuentan por thumbprint, no
por cantidad de firmas. `typ` candidato `application/xcim-as-{object_type}+jcs`,
sin registro IANA ni sufijo aprobado. G07/G10 deben revisar estos bytes.

```text
H = SHA-256; J = JCS; U = UTF-8; b64u = base64url sin padding
commit(type, payload) = b64u(H(U("XCIM-AS-01-" + type + "\0") || J(payload)))
```

Tags exactos de tipo: `GENESIS`, `MANIFEST`, `CHECKPOINT`, `CONTROL-HEAD`, `EVENT`,
`STATE-VALUE`, `LOCATOR`, `MATERIAL`. El compromiso es del **payload** validado,
no del JWS completo. Los compromisos RBA/MSA/MP de P1 no cambian. `MATERIAL`
compromete el objeto canónico `{format, value}`: `format` es
`p1-jws-envelope` para la MSA completa firmada, o `as-record` para registros
app/clave/dominio. Cualquier comparación debe identificar ambos tipo y bytes.

### C1 — ReceiverTrustPolicy (configuración local)

No se recibe como autoridad desde un email. Campos locales obligatorios:
`policy_id`, `policy_epoch`, `issuer_id`, `log_id`, `profile_id`,
`root_keys`, `root_threshold`, `recovery_keys`, `recovery_threshold`,
`trusted_genesis_commitment`, `accepted_manifest_epoch_floor`,
`anchor_policy`, `fetch_origins`, `valid_until`, `max_clock_uncertainty` y
los límites de §7. `profile_id: "as-01-anchored"` es nombre candidato.
Cada pin identifica alg/key/thumbprint y rol. Sin pin público por defecto.

El genesis AS es el payload cerrado `{issuer_id, log_id, profile_id,
origin_nonce, anchor_policy_id}`. Su compromiso usa tag `GENESIS`, nonce de
32 octetos y política de anchor ya aceptada; no incluye hashes de manifiestos
o checkpoints que lo referencien. C2/C3/C4 incluyen `genesis_commitment` además
de sus campos enumerados abajo y deben coincidir con C1. Así el origen se liga
al perfil sin compromisos circulares. Un nuevo log_id/genesis exige nueva
aceptación local; no lo elige libremente un mensaje.

Recomendación inicial: raíz de mantenimiento con quórum 2 de 3 y recuperación
2 de 3 **disjunta**; las claves online no pertenecen a esos conjuntos. Un equipo
puede configurar otro quórum explícitamente, documentando menor tolerancia.
Se requiere al menos un ancla inicial de historia aceptada y el control de
la distribución local de políticas; reinstalar no permite resetear floors.

Una rotación ordinaria de raíz requiere quórum de raíz vieja y nueva sobre
el mismo documento de transición `{issuer_id, old_policy_epoch,
new_policy_epoch, old_set_commitment, new_set_commitment, effective_at}`.
La recuperación utiliza el conjunto de recuperación ya provisionado y eleva
`policy_epoch`; suspende positivos hasta instalar nueva raíz/genesis o un
sucesor verificado. No se acepta una recovery key anunciada por la raíz
comprometida. Si se compromete también el quórum de recuperación, hace falta
reprovisionamiento externo; la especificación no puede reconstruir confianza.

Registry opcional futuro: raíz de registry aceptada localmente → acreditación
vigente y acotada a issuer/perfil → raíz del issuer. Profundidad máxima dos
delegaciones después de la raíz local, sin ciclos ni fallback automático a
otro registry. El contrato de estado del registry y sus propias revocaciones
debe diseñarse antes de habilitar esa ruta. No se presupone que exista hoy.

### C2 — AuthorityManifest (raíz → roles online)

Payload cerrado: campos comunes, `manifest_epoch`, `previous_manifest_commitment`
(null sólo en origen aceptado), `root_policy_epoch`, `keys`, `publication_profile`,
`fetch_origins`, `iat`, `exp`. `keys` es lista finita única por kid/thumbprint
con `{kid, alg, public_jwk, thumbprint, role, valid_from, valid_until, status}`;
`status` es `active`, `retired` o `revoked`. Una clave tiene un solo rol AS.

Roles: `receipt`, `recipient_binding`, `authority_attestation`,
`state_checkpoint` y `control_head`. Claves `state_checkpoint` y `control_head`
deben tener thumbprints distintos. `app_control`/`message_presentation` no se
obtienen de discovery: sus autoridades específicas están en C5. La raíz
autoriza el manifiesto por quórum; verificar hash de JWK y límites de cada
descriptor. El manifiesto nunca autoriza a sus claves a reemplazar la raíz.

El receiver conserva el mayor epoch/commitment aceptado. Mismo epoch con otro
compromiso implica conflicto; epoch menor no restaura autoridad. Nuevos epochs
requieren la cadena completa de manifiestos o un floor reprovisionado por raíz
aceptada; no se salta un revocado. Discovery sólo localiza bytes. El manifiesto
define orígenes de transporte, limitados además por la allowlist local.

**Límite de seguridad:** las claves C3/C4 se revocan en C2 o mediante política
de recuperación C1, nunca por una hoja que ellas mismas autentican. C2 tiene
edad máxima candidata de 24 horas. Un atacante que oculte un C2 más nuevo puede
conservar un C2 anterior aún válido hasta ese límite. No se promete retirar
esas claves en cinco minutos; raíz/recuperación y sus canales deben ensayarse.

### C3 — ControlHead (cabeza reciente, firma separada)

Payload cerrado: campos comunes, `head_sequence`, `previous_head_commitment`,
`manifest_epoch`, `manifest_commitment`, `checkpoint_sequence`,
`checkpoint_commitment`, `checkpoint_key_thumbprint`, `this_update`,
`next_update`. La primera cabeza referencia null sólo en el origen aceptado;
las demás avanzan exactamente en uno con historial recuperable.

Se firma con `control_head` bajo C2 vigente. Cada cabeza referencia **un solo**
checkpoint C4 exacto del mismo issuer/log/manifiesto. No puede declarar vigente
otro C2. `checkpoint_key_thumbprint` debe coincidir con el firmante C4 autorizado.
No es una prueba de terceros ni una nueva raíz: limita la capacidad de una
clave de checkpoint comprometida de inventar por sí sola una publicación actual.
Comprometer ambos roles anula esa separación; C1/C2 siguen siendo necesarios.

`this_update` de C3 debe ser igual al `this_update` C4, y `next_update` no lo
excede. Una cabeza creada después **no** renueva el corte. Para renovar se
genera un nuevo C4, aun sin eventos, y se verifica nuevamente su anclaje.

### C4 — StateCheckpoint (corte consistente y publicación)

Payload cerrado: campos comunes, `checkpoint_sequence`,
`previous_checkpoint_commitment`, `manifest_epoch`, `manifest_commitment`,
`snapshot_id` (32 octetos aleatorios), `permission_batch`, `authority_history`,
`authority_state_root`, `this_update`, `next_update`, `publication_profile`.
Firma `state_checkpoint`; secuencia inicia en uno y avanza en uno, con null
predecesor sólo en genesis aceptado. No hay URL ni evidencia de anchor dentro
del payload que será comprometido por ese mismo anchor.

`permission_batch` es objeto cerrado `{batch_sequence, batch_manifest_commitment,
tree_size, event_root, state_root, created_at}`. Identifica el payload exacto de
un batch WD 0.1 verificado con su clave batch autorizada por la política de
compatibilidad; se agrega rol `legacy_batch` explícito en C1 para ese caso,
sin confundirlo con `state_checkpoint`. Se conserva el compromiso establecido
`XCIM-BATCH-MANIFEST-0.1\0`; no se renombra como hash AS. Validar schema, firma,
todos los campos, continuidad y pruebas de receipt/permiso WD existentes.

`authority_history` es `{tree_size, event_root}` de la historia AS (§5).
Permisos conservan su árbol/estado WD; app, dominios, MSA y claves usan un árbol
AS separado. **No** se introducen tipos nuevos en los schemas/raíces WD cerrados.
`permission_batch.created_at == this_update` C4; ambos se sellan sobre el mismo
corte lógico de escritura. El productor debe impedir cambios concurrentes a
cualquiera de las dos proyecciones hasta sellarlas o abortar y reintentar.
La firma atestigua esa atomicidad: por sí sola no la demuestra a un tercero.

Un checkpoint sin eventos nuevos requiere nuevo batch WD de cero eventos y
nuevo C4/anclaje. Debe comprobarse que raíces/tamaños no cambiaron; no se permite
referenciar un viejo batch y cambiarle sólo el reloj. `next_update` candidato
como máximo `this_update + 300`. Un timestamp de wrapper/descarga no lo extiende.

**Anchor AS nuevo:** el adaptador elegido debe autenticar al menos
`(profile_id, issuer_id, log_id, checkpoint_sequence, checkpoint_commitment,
previous_checkpoint_commitment)` y comprobar red, contrato/código, firmante,
transacción/evento exactos, bloque canónico, finalidad y variantes conflictivas.
El hash C4 ya compromete ambas proyecciones y sus raíces; no hay ciclo.
La identidad/genesis del adaptador está fijada en C1 y referida por C2/C4.

No se define aquí un ABI final ni se despliega un contrato. El anchor Amoy 0.1
no se reinterpreta como anchor AS. Su validación histórica continúa intacta.
Seleccionar red/contrato/finalidad y fijar los bytes exactos del adaptador es
una dependencia **bloqueante de G06-M**, no un detalle de configuración oculto.

### C5 — AuthorityStateValue y materiales

La hoja de estado AS es cerrada: `proposal_version`, `object_type:
"authority_state_value"`, `issuer_id`, `log_id`, `locator`, `state_epoch`,
`status`, `effective_at`, `valid_until`, `material_commitment`,
`latest_event_commitment`. El `locator` se deriva del objeto esperado, nunca
se copia sin verificar de la prueba. No hay `next_update` autodeclarado por hoja.
Frescura viene de C4/C3; `valid_until` agrega un deadline, no lo prolonga.

| Tipo / locator cerrado | Material autenticado que se debe presentar | Regla decisiva |
|---|---|---|
| `application`: `{kind, app_id}` | `{app_id, app_epoch, authority_epoch, control_key_thumbprint}` | Hoja actual de la app, no buscada sólo por viejo epoch. El epoch esperado por MSA/MP debe ser el actual. |
| `key`: `{kind, owner_id, kid}` | `{owner_id, kid, thumbprint, public_jwk, alg, role, app_epoch, authority_epoch, valid_from, valid_until}` | `kid` nunca se reutiliza para otro material; issuer roles usan epochs null, app roles epochs enteros. Comparar rol y propietario exactos. |
| `domain`: `{kind, app_id, domain, role}` | `{app_id, app_epoch, domain, domain_epoch, role, observation_commitment, observed_at, recheck_by}` | Dominio A-label exacto y role WD exacto; evidencia de challenge observada por autoridad aceptada. Vence también en `recheck_by`. |
| `msa`: `{kind, app_id, authorization_id}` | Envelope MSA P1 completo mediante `MATERIAL` | Hash, scope, app/authority epochs, kid y thumbprint idénticos. No basta una hoja por ID con otra MSA. |

`owner_id` identifica issuer o app sin inferirlo del dominio. Un rol no se
expande a otro. Para P1 se requieren dominio `rfc5322_from` y `dkim_signing`,
además de `consent_presentation_delegate` cuando corresponda a la delegación.
Los nombres organizacionales no sustituyen esos roles. La clave DKIM real se
verifica bajo DKIM/DNS y política del receiver; una hoja XCIM de dominio no
reemplaza esa comprobación. DNSSEC no se presume.

El registro de dominio se atestigua con `authority_attestation` después de un
challenge contextual de 32 octetos, vida candidata 600 s, ligado a issuer/app,
dominio/rol y clave de control. Requiere consulta DNS por el observador, nombre
de registro y respuesta exactos, sin aceptar un resultado aportado por sender.
Nombre TXT, payload firmado de observación, resolvers/validación y política
ante transferencia deben fijarse antes de G04-M; aquí no se inventa prueba DNS.
Rechequeo candidato cada 86400 s: no garantiza detectar una transferencia entre
observaciones; ese riesgo debe aceptarse o reducirse explícitamente.

Al MSA la firma la clave `app_control` vigente de su app; no el issuer ni el ESP
por afirmación propia. Su alta exige prueba de posesión de la clave MP sobre
`{issuer_id, app_id, app_epoch, authority_epoch, authorization_id,
msa_commitment_p1, challenge, expires_at}`; challenge de un uso y hasta 600 s.
La evidencia de posesión no otorga consentimiento. `authority_attestation`
valida y atestigua el registro; C5 autentica su estado vigente.

Permisos siguen usando el estado WD: comprobar receipt, `permission_id`,
app/epoch, pairwise ID, propósito/clase y evento de emisión. Para cada permiso
exigir además la app actual, su `authority_epoch`, las claves y MSA actuales.
No hay una hoja global por dirección de email ni búsqueda pública de direcciones.

### C6 — StateWitness (prueba, no firma ni trust root)

Objeto cerrado: `proposal_version`, `object_type: "authority_state_witness"`,
`issuer_id`, `log_id`, `checkpoint_commitment`, `locator`, `present`, `value`,
`siblings`. `present` booleano; `value` es C5 sólo si true, null si false;
`siblings` contiene exactamente 256 hashes de 32 octetos, orden hoja→raíz.
Pruebas comprimidas/multiproof quedan para otra revisión; no mezclar formatos.

```text
K = H(U("XCIM-AS-01-STATE-KEY\0") || J({issuer_id, log_id, locator}))
L(value) = H(U("XCIM-AS-01-STATE-LEAF\0") || K ||
             H(U("XCIM-AS-01-STATE-VALUE\0") || J(value)))
E[0] = H(U("XCIM-AS-01-STATE-EMPTY\0"))
N(l,r) = H(U("XCIM-AS-01-STATE-NODE\0") || l || r)
E[n+1] = N(E[n], E[n])
```

Árbol binario sparse de profundidad 256; camino raíz→hoja por bits de K
MSB-first, cero a izquierda. Al reconstruir hoja→raíz usar primero el bit
menos significativo (índice 255 en el camino) y consumir cada sibling una vez.
Ausencia parte de `E[0]`, no de una hoja «unknown»; raíz vacía `E[256]`.
No duplicar el hash `STATE-VALUE`: es la misma fórmula que commit de §3,
decodificada a 32 octetos. Verificar checkpoint/raíz, locator, status y material.

Ausencia válida significa que el estado requerido no está registrado en ese
corte. No significa activo, ni necesariamente revocado. Falta de prueba no
significa ausencia probada. Revocados conservan tombstones; un activo no puede
reaparecer por borrado. La ausencia de la MSA actual nunca permite usar otra
por coincidencia de clave. Las pruebas de permiso WD usan su propio algoritmo.

### C7 — EvidenceSet y recuperación

Wrapper cerrado: `proposal_version`, `object_type: "authority_evidence_set"`,
`profile_id`, `manifest`, `control_head`, `checkpoint`, `anchor_evidence`,
`permission_evidence`, `authority_evidence`, `history_evidence`. `manifest` es
JWS/quórum C2; C3/C4 JWS. Cada entrada de autoridad es `{witness, material,
event, event_inclusion}`. Todo objeto debe pertenecer al mismo corte C4 o a la
historia autenticada que lo precede; objetos válidos de cortes distintos no se
pueden combinar. El wrapper no está firmado y no crea frescura.

`permission_evidence` transporta componentes WD de receipt/evento/pruebas/batch;
su autenticación externa viene del **nuevo** perfil AS que compromete el batch
exacto. No se etiqueta ese wrapper como proof WD/Amoy 0.1. Su schema final y la
matriz de compatibilidad son dependencias de G06/G07. `anchor_evidence` e
`history_evidence` se seleccionan estrictamente por perfil, sin JSON arbitrario
tratado como válido. `history_evidence` debe llevar continuidad de C2/C3/C4,
consistencia de ambos logs y pruebas de transición necesarias para los floors
que el receiver ya conoce. No seguir enlaces desde headers a orígenes libres.

Transporte propuesto en orígenes aceptados: `GET /as-01/manifest`,
`GET /as-01/head`, `GET /as-01/objects/{type}/{commitment}` y
`POST /as-01/evidence` con `{checkpoint_commitment, locators}`. Son rutas
candidatas de un issuer/mirror, **no endpoints implementados en xcim.org**.
El cliente selecciona previamente issuer/log y endpoints; HTTPS protege
transporte, las firmas/pruebas autentican contenido. Soporte de POST y acceso
deben declararse; no hay búsqueda de email. Consultas por locators opacos siguen
pudiendo correlacionar permisos; preferir caché compartida y prueba adjunta.

Límites iniciales para ensayo: HTTPS sólo puerto 443, sin redirects, userinfo,
fragmentos ni direcciones privadas/loopback/link-local/multicast; comprobar
resoluciones y destino de conexión contra DNS rebinding. Nada de URL desde
`kid`, JWK, receipt, Reference o Proof. Hasta 8 conexiones, 2 s por operación,
5 s totales, 1 MiB descomprimido por EvidenceSet y profundidad JSON 32.
No hay fallback a un endpoint comercial ni dependencia de API privada.

Una prueba sparse sin comprimir puede requerir más de 8 KiB por hoja antes
de base64/JSON. Evidencia de varias autoridades puede exceder Proof (49152
octetos raw) de P1. No subir ese límite silenciosamente: resolver por transporte
acotado o diseñar multiproofs y medirlas en G16. Reference y sus compromisos
P1 permanecen iguales. El checker actual sigue rechazando Proof con
`PROOF_VALIDATOR_PENDING`; esta propuesta no cambia ese comportamiento.

### C8 — LifecycleEvent (cambio autorizado e historial)

Payload cerrado: campos comunes, `sequence_number`, `locator`, `state_epoch`,
`previous_event_commitment` (null sólo al alta), `previous_state_commitment`
(null sólo al alta), `new_state_core`, `effective_at`, `reason`,
`authorization_evidence_commitment`. `new_state_core` es C5 sin
`latest_event_commitment`; éste se deriva del compromiso de C8 para construir
la hoja. Así no se introduce un ciclo evento↔estado. Razones candidatas
`registration`, `rotation`, `recipient_revocation`, `owner_revocation`,
`compromise`, `expiry`, `suspension`, `erasure`.

El evento lo atestigua `authority_attestation`; se conserva la solicitud y
evidencia firmada del actor autorizado de §6 bajo su compromiso, sin publicarla
si revela PII. El receiver autentica evento/inclusión/hoja y confía en esa
atestación de validación; el monitor puede exigir evidencias auditables con
acceso autorizado. Una prueba de inclusión no demuestra que el actor tenía
derecho al cambio. Grants/revocaciones del permiso siguen su lifecycle WD.

Locator/epochs/tiempos de C8 y su `new_state_core` deben coincidir; la hoja
reproduce exactamente ese core más el compromiso C8.

## 4. Grafo de validación sin autoautorización

```text
Política local C1 --quórum raíz--> Manifest C2
  |                                | roles separados
  |                           Head C3 + Checkpoint C4
  |                                   | commits
  +--genesis/anchor policy------------>| permiso WD + autoridad AS
                                      |
                           estados/pruebas C5/C6 + historia C8
                                      |
                 app actual -> control -> MSA + clave MP + dominios
                                      |
                    receipt + RBA + MSA + MP + DKIM de P1
```

La aceptación completa requiere todas las aristas. RBA/receipt se validan con
sus roles C2 más su estado C5; la clave de app/control y la MP con su estado
específico. C3/C4 se autorizan directamente desde C2, **no** mediante hojas
firmadas por sí mismas. La clave batch legacy se configura explícitamente en
C1; su futura migración a manifiesto nuevo requiere G07, no reutilizar el rol
de checkpoint. Su descriptor local incluye vigencia/thumbprint y su estado
`key` C5 puede retirar, pero nunca ampliar, esa autoridad provisionada.
Una clave retirada puede servir a auditoría histórica sólo bajo
una política histórica; no aporta autoridad actual para PASS P1.

## 5. Historia, cortes, rollback y equivocación

Historia AS: árbol acumulativo, `sequence_number` desde uno, índice cero-based
`sequence_number - 1`. Payload C8 completo como hoja. Forma recursiva/split en
la mayor potencia de dos estrictamente menor, sin duplicar hojas impares:

```text
MTH([]) = H(U("XCIM-AS-01-EVENT-EMPTY\0"))
leaf(e) = H(U("XCIM-AS-01-EVENT-LEAF\0") || J(e))
node(l,r) = H(U("XCIM-AS-01-EVENT-NODE\0") || l || r)
```

Inclusion y consistency usan orden de RFC 6962 con tags AS. No son bytes CT;
RFC 9162 es comparación de transparencia, no sustitución de fórmulas WD/AS.
El checkpoint compromete raíz/tamaño AS y batch WD del mismo corte. Verificar
consistencia de ambos árboles contra el origen/floor previamente aceptado,
rechazando siblings extra, tamaño menor, secuencia duplicada con otro hash o
predecesor inválido. Un log consistente no demuestra que la proyección sparse
sea correcta: publicar eventos permite reconstrucción/auditoría por monitores.

Guardar durablemente por issuer/log `policy_epoch`, C2 epoch/hash, C3 sequence/hash,
C4 sequence/hash, tamaños/raíces de ambos logs y máximo `state_epoch`/tombstones
de cada locator observado. Ordenar primero por las cadenas autenticadas, no
por timestamps de sender. Persistir floors antes de reutilizar positivamente
la evidencia; un fallo del store retira la señal. Perder el store requiere
resincronización contra un floor externo aceptado, no TOFU desde el mensaje.

El productor mantiene chains completas recuperables. Un receiver puede saltar
varias publicaciones de red, pero debe validar los enlaces/pruebas omitidos
o un checkpoint de recuperación aceptado fuera de banda. Una cabeza más nueva
observada invalida la anterior para nuevas evaluaciones; el timestamp por sí
solo no establece cuál es más nueva. Mismo número y distinto compromiso es
evidencia de conflicto: poner en cuarentena ese issuer/log; no elegir el primer
mirror. La restauración requiere resolución autenticada bajo C1, sin borrar
la evidencia de conflicto.

Ante bifurcación/reorg, no bajar el floor para resucitar permiso. Detener señal
positiva hasta establecer una continuación anclada y resolución aceptada. Dos
RPC pueden coincidir y estar equivocados; se debe declarar si la finalidad se
verifica con cliente de consenso/light client o corroboración RPC acotada.

## 6. Máquina de estados y revocaciones

Estados AS: `active`, `suspended`, `revoked`, `expired`, `erased`. La ausencia
no es estado. Alta válida crea epoch 1; cada transición aumenta `state_epoch`
en uno y enlaza el evento/estado anteriores. `effective_at` no puede moverse
al pasado para ampliar autoridad. Una revocación por compromiso puede declarar
una fecha de compromiso anterior en evidencia de incidente, pero no reescribe
`effective_at` ni hace verificable una hora de firma no atestiguada.

| Recurso | Quién puede solicitar / atestiguar cambio | Efecto que debe comprobar el receiver |
|---|---|---|
| Permiso | Destinatario autenticado para revocar; issuer valida/atestigua. App no concede ni reactiva consentimiento. | Revocado terminal para ese permission ID; nuevo consentimiento explícito requiere nuevo receipt/permiso, sin borrar historia. |
| MSA | App control actual, o issuer por compromiso/suspensión de autoridad. MP no puede autorizarse a sí misma. | Revocada terminal para authorization ID. Nueva MSA requiere nuevo ID y posesión; mismo kid no la reactiva. |
| Clave MP/control | Control autorizado según transición y atestación issuer; compromiso de control exige recuperación de app verificada. | `revoked` terminal por kid/thumbprint; no reutilizar kid. Bloquear firmas actuales aunque MP declare `iat` anterior. |
| App | Clave de control y atestación de continuidad del issuer; recuperación exige revalidación. | Cambio de control eleva `authority_epoch` y `app_epoch` según regla conservadora WD; consentimientos de otro app epoch no se heredan. |
| Dominio | Control de app más challenge observado; issuer puede suspender por fallo/transferencia. | Elevar `domain_epoch` al cambio de owner; requerir nuevos bindings. Vigencia pasada no prueba control presente. |
| Claves C3/C4 y raíz | Manifiesto/raíz C2 o recuperación C1; no hoja de esas mismas claves. | Retirar confianza al observar el cambio; cota de ocultamiento distinta (§7). |

`active → suspended/revoked/expired/erased`; `suspended → active` sólo para
app/dominio y con evidencia nueva/epoch superior. Para una MSA suspendida,
reemitir otra con ID nuevo para evitar reanimación accidental. `revoked`,
`expired` y `erased` no vuelven a active. Tombstones sobreviven a la eliminación
de material privado; erasión no borra el hecho público ni revierte una negativa.

La elección inicial conservadora ante cambio de control puede exigir renovar
consentimientos aunque el propietario siga siendo el mismo: es un coste real,
no una obligación textual de WD de incrementar epoch en toda rotación. La
alternativa es continuidad de control con firmas de ambas claves, posesión,
atestación de mismo owner y `authority_epoch` nuevo conservando `app_epoch`.
Requiere fijar cómo se conserva el binding `app_key_id` del receipt histórico;
A6 debe aceptar el coste conservador o definir esa continuidad antes de M.

Rotación MP ordinaria: crear clave/ID MSA nuevos, publicar activación y probar
ambas; overlap candidato máximo 3600 s si no hubo compromiso, acotado por todas
las vigencias. Retirar vieja de forma terminal. Al comprometer una clave, no
hay overlap ni aceptación de firma backdated: P1 exige autoridad **actual** y
`iat` no es un sello temporal independiente. Conservar auditoría histórica sin
confundirla con permiso para nueva entrega. Rotación de control sigue el
comportamiento conservador WD; una alternativa que preserve grants tras
rotación de control necesita decisión/versionado explícitos.

La solicitud de revocación no se da por «publicada» al escribir en una cola.
El operador distingue `received`, `authenticated`, `committed`, `anchored`,
`available`. Los ACK internos nunca son proofs ni resultados de protocolo.
Un timeout del anchor no permite declarar vigente un checkpoint nuevo.

## 7. Frescura, reloj y propagación

Parámetros **candidatos para ensayo**, sin mediciones ni SLA productivo:

| Parámetro | Propuesta inicial | Límite y criterio para ratificar |
|---|---|---|
| Incertidumbre del reloj `u` | Hasta 60 s | Ensayo con offset/rollback/NTP perdido. Si no se puede acotar, no hay positivo. |
| Edad de C2 / autoridad de C3/C4 | Hasta 86400 s | Medir firma por quórum, disponibilidad y recuperación. No venderla como revocación de cinco minutos. |
| Estado de permiso/autoridad C3/C4 | Hasta 300 s desde el corte | Anclaje final y publicación deben caber dentro; si no caben, ese perfil no es viable con esa ventana. |
| Cadencia de snapshot | Objetivo 60 s | Probar vacío y con carga, retrasos y revocaciones concurrentes. No renueva un snapshot viejo. |
| Propagación tras solicitud autenticada | Objetivo p99 ≤ 120 s hasta evidence disponible/anclada | Medir por separado cola, corte, anchor/finality y mirrors. No es cota garantizada ni reemplaza expiración. |
| DNS domain recheck | Hasta 86400 s | Revisar riesgo de transferencia; fallos no extienden observación previa. |
| MSA/RBA/MP | Mantener límites P1-01 | Hasta 604800 s MSA y 86400 s RBA/MP; no sustituyen estado de 300 s. |

Sean `t` reloj local y `u` cota de incertidumbre. Para estado que afirma validez
desde `s`, exigir `s <= t-u`; para toda expiración exclusiva `e`, exigir
`t+u < e`. Un snapshot todavía «del futuro» puede reevaluarse al avanzar reloj,
sin consumir nonce. Este criterio conservador usa **todo** el intervalo de
incertidumbre, no añade grace a la expiración. Para las firmas P1 existentes
con tolerancia `iat <= now+60`, conservar su gate de emisión, pero exigir
además que la autoridad de cada firmante cubra el `iat` declarado; esa
tolerancia no amplía expiración ni frescura de C3/C4.

```text
state_deadline = min(C3.next_update, C4.next_update,
                     C4.this_update + min(300, local_max_state_age))
manifest_deadline = min(C2.exp, C2.iat + min(86400, local_max_manifest_age))
effective_deadline = min(state_deadline, manifest_deadline,
    C1.valid_until, receipt.exp, RBA.exp, MSA.exp, MP.exp,
    each_required_key.valid_until, each_required_state.valid_until,
    each_required_domain.recheck_by, selected_anchor_policy_deadline)
```

Convertir tiempos WD RFC3339 a instante exacto sin truncar fracciones ni
reescribir bytes firmados. Si la política de anchor no define deadline temporal,
usa infinito **sólo para ese término**: igualmente debe estar verificada y la
finalidad no renueva el tiempo del corte. C3/C4/C2 deben cumplir `s < e` y sus
edades máximas al evaluarse. Intersectar también las vigencias de claves al
emitir **y** ahora; una clave puede estar autorizada a emitir hasta antes de
que expire el objeto, pero no a sostener señal positiva tras su propio retiro.

Ejemplo: corte 12:00, vence 12:05, `u=30 s`; a 12:04:29 puede ser utilizable si
todas las demás pruebas pasan; a 12:04:30 deja de ser positivo. Descargarlo
12:04:59 no lo renueva. Recibirlo a 12:00:10 con esa incertidumbre es demasiado
temprano para afirmar que el corte ya ocurrió; se puede esperar/reevaluar.

Con autoridad honesta, reloj acotado y cortes atómicos, una revocación ocurrida
inmediatamente después de un corte puede ocultarse hasta el deadline de ese
corte, como máximo la ventana de 300 s propuesta. Detener publicaciones hace
caducar la señal; no prolonga permiso. Si se compromete C3/C4 o su autoridad,
esa cota deja de aplicar: el límite de C2 puede alcanzar 24 horas y un issuer
o quórum raíz deshonesto puede emitir estado falso. Recuperación/denies locales
pueden actuar antes, pero no se promete entrega instantánea de esa información.

Revalidar la intersección inmediatamente antes de aceptación SMTP/commit del
nonce y al reutilizar un resultado exportado. Trabajo asíncrono, `304`, ETag,
`Age`, hora de descarga o manifest de release no extienden ningún término.
Si se usan cachés entre MX, compartir floors, tombstones y política de invalidez;
el ledger de replay sigue siendo otra transacción pendiente en G16.

## 8. Ausencia, fallos y resultado compuesto

Proponer internamente `{validation, permission, authority, freshness,
publication, replay, effective_deadline, diagnostics}`. Son dimensiones locales
de diagnóstico, no nuevos códigos registrados. Conservar todos los fallos
válidamente comprobados; no transformar un error de transporte en revocación.

Orden candidato determinista para retirar la señal: parseo/límites/perfil →
trust/firmas/compromisos → conflicto/rollback/prueba inválida → negativa
autenticada de permiso/autoridad → evidencia vencida → dependencia ausente o
inaccesible → todas las condiciones satisfechas. Cada etapa sólo produce
hechos después de autenticar sus prerrequisitos; un estado «revoked» en JSON
no autenticado no tiene precedencia. Si hay varios fallos de una etapa, ordenar
por rol/locator canónico y conservar la lista completa.

Una revocación de permiso autenticada puede retirar permiso sin anchor, como
permite el core, pero el resultado debe indicar que **no** es verificación de
publicación completa. No permitir que un anchor caído tape esa negativa; tampoco
emitir revocado si la prueba está ligada a otro contexto. Ausencia autenticada
de MSA/clave/app retira autoridad y no se etiqueta `XCIM_REVOKED` del permiso.

Para el protocolo, conservar el registro vigente: `XCIM_REVOKED` sólo cuando
corresponda al permiso, `XCIM_STATUS_STALE` para evidencia vencida,
`XCIM_STATUS_INDETERMINATE` para insuficiencia, `XCIM_ANCHOR_UNAVAILABLE`
cuando falte el anchor requerido y `XCIM_LOG_PROOF_FAIL` para una prueba
inválida autenticablemente atribuible al contexto. D09/D12 deben ratificar
el mapeo completo de conflictos/autoridad y multifallos antes de afirmar
conformidad. El código P1 de fixture sigue sin emitir PASS.

## 9. Alternativas y condiciones para reconsiderarlas

| Alternativa | Qué gana | Qué no resuelve / por qué no es el primer camino |
|---|---|---|
| Consulta firmada online por mensaje, estilo status responder | Revocación de baja latencia y payload pequeño | Disponibilidad, correlación y coste por mensaje; debe autenticar autoridad/frescura, no basta HTTP. Puede ser optimización opt-in futura. |
| Listas de revocación completas/deltas | Caché/broadcast fáciles; menos consultas por locator | Tamaño, composición de deltas y prueba de lista completa/actual; no basta «no aparece». Comparar con sparse para cohortes pequeñas. |
| Tokens muy cortos MSA/MP | Menos estado separado | Retiro sólo al vencer; seguiría faltando revocación de app/control/dominio y abuso de clave comprometida. |
| Un único firmante de checkpoint y «su estado» en la misma raíz | Menos roles y firmas | Autoatestación tras compromiso; no elegirlo como lifecycle suficiente. C3 agrega un dominio de compromiso, sin eliminar confianza en issuer. |
| Log y testigos independientes sin blockchain | Posible menor latencia y coste | Requiere quórum, operadores independientes, política de witness/gossip y análisis de split views; sería perfil nuevo sin cadena revisado, no omisión de core. |
| Sólo firma de issuer, sin publicación independiente | Desarrollo inicial simple | No cumple la publicación exigida; se podría ensayar como fixture sin señal pública, nunca llamarlo AS anchored. |
| Anclar sólo raíz de permisos WD y adjuntar autoridad sin compromiso | Reutiliza el anchor de hoy | Permite mezclar/manipular autoridad de otro corte. AS compromete ambas en C4; requiere adaptador nuevo explícito. |

La separación `thisUpdate`/`nextUpdate` de OCSP inspira el vocabulario de estado,
sin adoptar su ASN.1 ni su modelo de trust. La raíz como input local y las
dificultades de recuperación se comparan con PKIX/DNSSEC. La propuesta AS es
diseño XCIM, no un perfil ya validado por esos RFCs.

## 10. Criterios de cierre por brecha

| Brecha / hito | Entregable necesario | Evidencia que permite cerrarlo |
|---|---|---|
| G04-M | D04 aceptada; schemas cerrados C1/C2/C5/C8 y materiales; matriz exacta de roles/alg/typ; contratos DNS, posesión, rotación/recuperación y transporte | Fixtures de cada lifecycle y límites de confianza; otro implementador reproduce bootstrap y cambio/compromiso de cada rol sin API privada. Sin resolver DNS/registry opcional no se afirma cobertura de esos caminos. |
| G05-M | D05 aceptada; schemas C3/C4/C6/C7, fórmulas y algoritmo completo de vigencias/fallos, floors durables y ausencia | Vectores con reloj/futuros/expiración exacta, cortes mezclados, revoked/absent/missing/stale, no-renovación por wrapper, conflicto y reinicio; mismos bytes/resultados en dos implementaciones. |
| G05-O | Operación continuamente renovada y objetivo de revocación declarado | Ensayo de 7 días propuesto con carga y clocks declarados; revocaciones bajo concurrencia y pérdida de publicación, p99/máximos/fallos reportados; ningún positivo tras deadline/negativa conocida. Recuperación sin borrar floors. |
| G06-M | D06 aceptada, perfil/anchor adapter exactos, genesis/ABI/política de finality, relación WD→C4 sin ciclos y límites | Verificador de evidencia completo que rechace wrong-chain, evento/firmante/hash/sequence falsos, forks/reorg/variantes, raíces inventadas y split view. Pruebas en otro verifier sin RPC privado. |
| G06-O (junto G14–G16) | Monitor y ensayo de disponibilidad/latencia/DoS/finalidad | Revisión externa de la construcción y ensayo con fallos inducidos, operadores declarados y medición de tamaño/CPU/red; sin llamar a Amoy red productiva. |

Duración/carga/p99 son propuesta de ensayo, no garantías medidas. Una autoprueba
puede completar evidencia interna, pero no satisface por sí sola «otro
implementador», revisión externa ni operación entre equipos independientes.
El primer envío S puede declarar estas brechas abiertas; no hay envío implícito.

## 11. Catálogo de pruebas por escribir, no resultados

Casos planificados AS-T01–AS-T24; no están sumados a los 135 casos P1 existentes:

| ID | Caso | Criterio observable esperado |
|---|---|---|
| AS-T01 | Bootstrap con pins aceptados y todo el grafo válido | Evidencia fixture completa, sin autoridad de producción por usar claves sintéticas. |
| AS-T02 | Manifest autoafirmado / registry no aceptado / otro issuer | No crear trust ni seguir ruta de fallback. |
| AS-T03 | Cambiar rol, kid o JWK conservando firma válida de otro rol | Retirar autoridad, aun con firma matemáticamente correcta. |
| AS-T04 | MSA material sustituido, mismo authorization ID | Compromiso o scope no coincide; negar. |
| AS-T05 | MP firmada por clave revocada con iat backdated | No aceptar firma para nueva entrega. |
| AS-T06 | Rotación MP con overlap y posterior retiro | Sólo intervalos/scope vigentes; no reanimar la clave vieja. |
| AS-T07 | Cambio de control/app epoch / transferencia de dominio | No heredar grants de otro epoch ni bindings previos. |
| AS-T08 | Reusar challenge / observar DNS aportado por sender | Fallar registro/observación; no autoprobar control. |
| AS-T09 | MSA, clave, app o dominio ausentes con proof válida | Ausencia sin autoridad; distinguir de proof faltante. |
| AS-T10 | Reordenar sibling, bit order, locator, issuer o root sparse | Fallar prueba; no aceptar raíz suministrada por ella misma. |
| AS-T11 | Mezclar permiso de un corte y autoridad de otro | Fallar C4/roots/compromisos. |
| AS-T12 | Revocación concurrente entre snapshot y firma | Incluir consistentemente o abortar; ningún corte mixto publicado. |
| AS-T13 | Wrapper nuevo, HTTP304 o re-download tras caducidad | Deadline original; nunca renovar. |
| AS-T14 | Bordes `t-u == this_update`, `t+u == exp` y reloj sin cota | Igualdad de inicio admitida; igualdad de fin no positiva; reloj no acotado no positivo. |
| AS-T15 | Checkpoint/key expirados y receipt válido por años | Intersección retira señal; no priorizar sólo receipt. |
| AS-T16 | Checkpoint sin eventos nuevo / reloj cambiado en uno viejo | Nuevo corte/anclaje válido o rechazo; no refrescar batch viejo. |
| AS-T17 | Checkpoint comprometido sin segunda firma C3 | No fabricar evidencia actual sólo con esa clave. |
| AS-T18 | Control head viejo retenido, nuevo ya observado | Floor impide rollback aun antes de expiración. |
| AS-T19 | Compromiso de ambos roles online / raíz recuperada | Mostrar límite de confianza/24h; recuperación externa retira positivos, sin prometer solución por árbol. |
| AS-T20 | Mismo sequence/epoch con distintos hashes, mirrors divididos | Cuarentena/conflicto, no elegir primero. |
| AS-T21 | Reorg, wrong chain, transacción exitosa sin evento exacto | No publicar positivo; no retroceder floor. |
| AS-T22 | Store de floors perdido/no disponible y reinicio | Resync aceptada o sin positivo; no TOFU desde email. |
| AS-T23 | Redirect/SSRF/DNS rebinding/decompression bomb / Proof enorme | Cortar fetch/parsing con presupuestos antes de uso. |
| AS-T24 | Múltiples MX, nonce concurrente y vencimiento antes de SMTP250 | Reevaluar y aceptar atómicamente; G16 sigue pendiente hasta ese ensayo. |

## 12. Dirección adoptada y concreciones pendientes

| ID de trabajo | Elección por cerrar | Recomendación / puerta siguiente |
|---|---|---|
| A1 / D04 | Bootstrap mínimo y registry | Pins locales primero; registry sólo al definir su estado/recuperación. Aceptar roles C1/C2 y quórum explícito antes de schemas. |
| A2 / D04 | Revocación de signers de publicación | C3/C4 separados, revocados por C2/C1. Ratificar riesgo de ocultamiento de C2 ≤24h o diseñar otro canal de autoridad más corto. |
| A3 / D05 | Dos proyecciones del mismo corte | Mantener permiso WD + autoridad AS, checkpoint compuesto. Fijar transacción/snapshot y migración de batch legacy antes de verifier. |
| A4 / D06 | Anchor inicial AS | Nuevo perfil anclado y adaptador de ensayo Amoy explícito; sin reinterpretar evento viejo. Faltan ABI/contrato/red/finalidad exactos, sin despliegue autorizado por publicar esta propuesta. |
| A5 / D05/G16 | 300s/60s/24h y reloj conservador | Usarlos como hipótesis de ensayo, medir viabilidad; no ampliar ventanas a escondidas si finality no cabe. |
| A6 / D04/G07/G09 | DNS, recuperación, tipos/algoritmos y fallos | Resolver payload de observación, roles legacy y matriz de fallos antes de cerrar M; fijar qué parte puede implementar el primer receiver. |

Dirección A1–A6 adoptada; secuencia técnica: schemas AS y evidencia sintética
cerrados → dos verificadores de fórmulas/temporización → adaptador/anclaje
seleccionado → snapshots/rotación/revocación continuos → interop y revisión
externas. En paralelo se puede revisar el diseño con expertos autorizados;
no se enviaron mensajes ni se contactó a IETF por publicar este material.

## 13. Referencias y comparación con estándares

- [Baseline WD-02-E1 core](https://xcim.org/spec/v0.1/wd-02-e1/), §§4,7,10–16: confianza local, autoridad actual, árboles, anclaje y estado fresco.
- [P1-01](https://xcim.org/standardization/p1/CONTRACT.md): bindings aceptados de destinatario/MSA/MP y límites de fixture.
- [RFC 5280 §6.1.1](https://www.rfc-editor.org/rfc/rfc5280.html#section-6.1.1): trust anchor como input a validación; AS no adopta una PKI X.509 propia.
- [RFC 6960 §2.4](https://www.rfc-editor.org/rfc/rfc6960.html#section-2.4): distingue observación de estado, próxima actualización y firma; AS define su propio deadline conservador.
- [RFC 5011 §§2,8](https://www.rfc-editor.org/rfc/rfc5011.html#section-2): actualización/compromiso de anclas y necesidad de recuperación externa en ciertos casos. No se reutiliza su algoritmo DNSSEC.
- [RFC 9162 §§2.1,11.3](https://www.rfc-editor.org/rfc/rfc9162.html#section-11.3): transparencia y límites ante vistas inconsistentes; no demuestra ausencia de equivocación por sí sola.
- [RFC 6962 §2](https://www.rfc-editor.org/rfc/rfc6962.html#section-2): orden/forma de los proofs ya usados por el baseline. RFC 9162 lo reemplaza para CT; conservar fórmulas históricas XCIM no es afirmar uso de CT moderno.

Referencias externas consultadas el 2026-10-19. Las construcciones AS adicionales
son propuesta de proyecto y requieren revisión propia, no aprobación de esos RFCs.

## 14. Concreción propuesta del adaptador AN01-P01

[AN01-P01](https://xcim.org/standardization/anchor-adapter/CONTRACT-PROPOSAL.md) propone el ABI, genesis acíclico,
red y finalidad del adaptador exigido por A4. Sus N1–N6 [fueron adoptadas](https://xcim.org/standardization/source/ACCEPTED-N1-N6.md): contrato inmutable por issuer/log, Amoy opt-in y nodo de consenso
del receiver. Incluye alternativas, gates y 20 casos EVM/red pendientes; [AN01-F01](https://xcim.org/standardization/an01/README.md) implementa contrato/schemas/EVM local, con cobertura
parcial del plan y finalidad viva pendiente. No cambia la adopción A1–A6, C7 F01
sigue null y G04–G06 conservan sus dependencias M/O.
