OverviewFilesCommitsIssuesDocsReleasesPeers

P2P-Hiverelay / packages / blind-client / test / describe.test.js

1219 lines · javascript ref:
import fs from 'node:fs'
import b4a from 'b4a'
import sodium from 'sodium-universal'
import test from 'brittle'
import {
  AUXILIARY_SIGNATURE_DOMAIN_ID,
  FAMILY,
  FRAME_KIND,
  OPERATION,
  PRIVACY_PROFILE,
  PROTOCOL,
  RESULT_SIGNATURE_DOMAIN_ID,
  TRANSPORT_ID,
  TRANSPORT_SUPPORT,
  admissionParametersHash,
  auxiliarySignaturePayload,
  blake2b256,
  blindHealthChallengeV1,
  blindHealthResultV1,
  blindExternalCommitWitnessV1,
  blindReceiptV1,
  blindServiceDescriptorV1,
  decodeCanonical,
  decodeOuterEnvelope,
  durabilityContinuityBindingV1,
  durabilityContinuityHash,
  durabilityProfileHash,
  durabilityProfileV1,
  encodeCanonical,
  encodeDispatchFrame,
  encodeOuterEnvelope,
  operationBit,
  persistentResultCommitment,
  relayIdentityTransitionV1,
  resultSignaturePayload,
  serviceDescriptorHash
} from '@hiverelay/blind-protocol'
import { admissionParametersV1 } from '@hiverelay/blind-protocol/schemas'
import {
  BlindDescriptorBootstrapHttpClient,
  BlindDirectHttpClient,
  BlindRelayQualifier,
  DescriptorTrustStore,
  DurableAttempt,
  DurabilityTracker,
  EncryptedIntentStore,
  INTENT_STATE,
  MemoryIntentBackend,
  RelayCandidatePool,
  createCellReplica,
  createAesGcmIntentSealer,
  createClientIntent,
  createHealthChallenge,
  qualifyDescribeControlEndpoint,
  qualifyRelay,
  journalSignedIntent,
  trustedAdmissionProfile,
  trustedDescriptorValidity,
  verifyAdmissionParametersBytes,
  verifyDescriptorBytes,
  verifiedAdmissionParametersValidity,
  verifyHealthResultBytes,
  verifiedHealthValidity,
  verifyOperationResult,
  verifiedEndpointContext
} from '../control.js'
import { createNodeCryptoRuntime } from '../runtime/node.js'

const runtime = createNodeCryptoRuntime()
const descriptorVector = fs.readFileSync(new URL(
  '../../blind-protocol/vectors/draft/describe/service-descriptor.bin', import.meta.url))
const admissionVector = fs.readFileSync(new URL(
  '../../blind-protocol/vectors/draft/describe/admission-parameters.bin', import.meta.url))

function keyPair (seedByte) {
  const publicKey = b4a.alloc(32)
  const secretKey = b4a.alloc(64)
  sodium.crypto_sign_seed_keypair(publicKey, secretKey, b4a.alloc(32, seedByte))
  return { publicKey, secretKey }
}

function signedValue (encoding, value, domainId, secretKey) {
  value.signature = b4a.alloc(64)
  const complete = encodeCanonical(encoding, value)
  const unsigned = complete.subarray(0, complete.byteLength - 64)
  sodium.crypto_sign_detached(value.signature, resultSignaturePayload(domainId, unsigned), secretKey)
  return encodeCanonical(encoding, value)
}

function signAuxiliaryValue (encoding, value, domainId, secretKey) {
  value.signature = b4a.alloc(64)
  const complete = encodeCanonical(encoding, value)
  const unsigned = complete.subarray(0, complete.byteLength - 64)
  sodium.crypto_sign_detached(value.signature, auxiliarySignaturePayload(domainId, unsigned), secretKey)
  return value
}

function signedIdentityTransition (oldKeys, newKeys, oldIdentitySequence) {
  const value = {
    version: 1,
    oldRelayKey: b4a.from(oldKeys.publicKey),
    newRelayKey: b4a.from(newKeys.publicKey),
    oldIdentitySequence,
    newIdentitySequence: oldIdentitySequence + 1n,
    validFromEpoch: 101,
    reasonCode: 1,
    transitionNonce: b4a.alloc(32, 0x81),
    oldSignature: b4a.alloc(64),
    newSignature: b4a.alloc(64)
  }
  const complete = encodeCanonical(relayIdentityTransitionV1, value)
  const unsigned = complete.subarray(0, complete.byteLength - 128)
  const payload = auxiliarySignaturePayload(AUXILIARY_SIGNATURE_DOMAIN_ID.IDENTITY_TRANSITION, unsigned)
  sodium.crypto_sign_detached(value.oldSignature, payload, oldKeys.secretKey)
  sodium.crypto_sign_detached(value.newSignature, payload, newKeys.secretKey)
  return value
}

function signedAdmission (keys) {
  const value = decodeCanonical(admissionParametersV1, admissionVector, { copyBytes: true })
  value.relayPublicKey = b4a.from(keys.publicKey)
  value.profileId = 7
  value.schemeId = 9
  value.roleBits = 1
  value.validFromEpoch = 100
  value.expiresEpoch = 104
  const bytes = signedValue(admissionParametersV1, value,
    RESULT_SIGNATURE_DOMAIN_ID.ADMISSION_PARAMETERS, keys.secretKey)
  return { bytes, value, hash: admissionParametersHash(bytes) }
}

function continuityBinding (durability) {
  return {
    version: 1,
    profileId: durability.profileId,
    externalJournalId: durability.externalJournalId,
    externalWitnessPublicKey: durability.externalWitnessPublicKey,
    externalJournalReplicationClass: durability.externalJournalReplicationClass,
    externalJournalFailureGroupId: durability.externalJournalFailureGroupId,
    restoreEvidenceFeedId: durability.restoreEvidenceFeedId
  }
}

function profile2Durability (witnessPublicKey) {
  const descriptor = decodeCanonical(blindServiceDescriptorV1, descriptorVector, { copyBytes: true })
  return {
    ...descriptor.durability,
    profileId: 2,
    externalJournalId: b4a.alloc(32, 0xa1),
    externalWitnessPublicKey: b4a.from(witnessPublicKey),
    externalJournalReplicationClass: 1,
    externalJournalFailureGroupId: b4a.alloc(32, 0xa2),
    externalCheckpointAgeBand: 1,
    externalJournalTopologyUrl: b4a.from('https://evidence.example:443/external-journal.cenc'),
    externalJournalTopologyHash: b4a.alloc(32, 0xa3)
  }
}

function signedDescriptor (keys, admission, changes = {}) {
  const value = decodeCanonical(blindServiceDescriptorV1, descriptorVector, { copyBytes: true })
  value.relayPublicKey = b4a.from(keys.publicKey)
  value.protocols.push({
    protocolId: FAMILY.CELL,
    major: 1,
    minor: 0,
    featureBits: 0n,
    profileHash: b4a.alloc(32, 0x27)
  })
  value.admissionProfiles[0].parameterHash = b4a.from(admission.hash)
  value.endpoints[0].envelopeClassBits = 0x007e
  Object.assign(value, changes)
  value.durabilityProfileHash = durabilityProfileHash(encodeCanonical(durabilityProfileV1, value.durability))
  value.durabilityContinuityHash = durabilityContinuityHash(encodeCanonical(
    durabilityContinuityBindingV1, continuityBinding(value.durability)))
  const bytes = signedValue(blindServiceDescriptorV1, value,
    RESULT_SIGNATURE_DOMAIN_ID.DESCRIPTOR, keys.secretKey)
  return { bytes, value, hash: serviceDescriptorHash(bytes) }
}

function supportFor (descriptor) {
  return {
    supportedProtocolProfiles: descriptor.protocols.map(value => ({
      protocolId: value.protocolId,
      major: value.major,
      minimumMinor: value.minor,
      profileHash: value.profileHash
    })),
    supportedTransportProfiles: descriptor.endpoints.map(value => ({
      transportId: value.transportId,
      transportSupportBit: value.transportId === TRANSPORT_ID.HTTPS_DIRECT
        ? TRANSPORT_SUPPORT.DIRECT_HTTP
        : TRANSPORT_SUPPORT.DIRECT_NATIVE,
      transportProfileHash: value.transportProfileHash
    }))
  }
}

function signedHealth (keys, descriptor, descriptorHash, challenge, overrides = {}) {
  const value = {
    version: 1,
    relayPublicKey: descriptor.relayPublicKey,
    storeId: descriptor.storeId,
    descriptorSequence: descriptor.descriptorSequence,
    descriptorHash,
    endpointId: challenge.endpointId,
    transportSupportBit: challenge.transportSupportBit,
    durabilityContinuityHash: descriptor.durabilityContinuityHash,
    durabilityProfileHash: descriptor.durabilityProfileHash,
    clientNonce: challenge.clientNonce,
    readyRoleBits: challenge.requestedRoleBits,
    readyOperationBits: challenge.requestedOperationBits,
    clockState: 1,
    effectiveEpochFloor: 100,
    integrityState: 1,
    checkpointAgeBand: 1,
    scrubAgeBand: 1,
    rebalanceState: 0,
    capacityBand: 2,
    challengeEpoch: 101,
    ...overrides,
    signature: b4a.alloc(64)
  }
  return signedValue(blindHealthResultV1, value,
    RESULT_SIGNATURE_DOMAIN_ID.HEALTH_RESULT, keys.secretKey)
}

async function trustedFixture (seedByte = 0x31, descriptorChanges = {}) {
  const keys = keyPair(seedByte)
  const admission = signedAdmission(keys)
  const descriptor = signedDescriptor(keys, admission, {
    storeId: b4a.alloc(32, (seedByte + 1) & 0xff),
    descriptorNonce: b4a.alloc(32, (seedByte + 2) & 0xff),
    ...descriptorChanges
  })
  const verified = verifyDescriptorBytes(descriptor.bytes, {
    nowEpoch: 101,
    ...supportFor(descriptor.value)
  })
  const trust = new DescriptorTrustStore()
  const trusted = await trust.accept(verified, { pinnedDescriptorHash: descriptor.hash })
  return { keys, admission, descriptor, verified, trust, trusted }
}

async function qualifiedCellEndpoint (seedByte, descriptorChanges = {}) {
  const fixture = await trustedFixture(seedByte, descriptorChanges)
  const operation = operationBit(FAMILY.CELL, OPERATION.CELL.PUT)
  const challenge = createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits: operation,
    clientNonce: b4a.alloc(32, seedByte)
  })
  const health = verifyHealthResultBytes(signedHealth(fixture.keys, fixture.descriptor.value,
    fixture.descriptor.hash, challenge.request), fixture.trusted, challenge.request, { nowEpoch: 101 })
  return {
    ...fixture,
    endpoint: qualifyRelay({
      trustedDescriptor: fixture.trusted,
      health,
      nowEpoch: 101,
      familyId: FAMILY.CELL,
      operationId: OPERATION.CELL.PUT,
      endpointId: 1,
      requiredRoleBits: 1,
      privacyProfileBit: PRIVACY_PROFILE.DIRECT,
      transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
    })
  }
}

test('descriptor verification binds canonical bytes, durability hashes, signature and authenticated genesis pin', async t => {
  const fixture = await trustedFixture()
  t.alike(fixture.verified.descriptorHash, fixture.descriptor.hash)
  t.is(fixture.verified.descriptorSequence, 0n)
  t.alike(fixture.trusted.rootRelayPublicKey, fixture.keys.publicKey)

  const changedCopy = fixture.verified.snapshotBytes()
  changedCopy.fill(0)
  t.alike(fixture.verified.descriptorHash, fixture.descriptor.hash)

  const missingMinimum = supportFor(fixture.descriptor.value)
  delete missingMinimum.supportedProtocolProfiles[0].minimumMinor
  t.exception(() => verifyDescriptorBytes(fixture.descriptor.bytes, {
    nowEpoch: 101,
    ...missingMinimum
  }), /minimumMinor/)

  const unpinned = verifyDescriptorBytes(fixture.descriptor.bytes, {
    nowEpoch: 101,
    ...supportFor(fixture.descriptor.value)
  })
  await t.exception(new DescriptorTrustStore().accept(unpinned), /authenticated pin/)

  const tampered = b4a.from(fixture.descriptor.bytes)
  tampered[tampered.byteLength - 1] ^= 1
  t.exception(() => verifyDescriptorBytes(tampered, {
    nowEpoch: 101,
    ...supportFor(fixture.descriptor.value)
  }), /signature is invalid/)
})

test('hash-pinned bootstrap fetch returns only a verified descriptor', async t => {
  const fixture = await trustedFixture(0x32)
  let observed
  const client = new BlindDescriptorBootstrapHttpClient({
    runtime,
    fetch: async (url, init) => {
      observed = { url, init }
      const request = decodeOuterEnvelope(init.body, { copyBody: true })
      const response = encodeOuterEnvelope({
        outerClass: request.outerClass,
        innerDispatch: encodeDispatchFrame({
          frameKind: FRAME_KIND.RESPONSE,
          familyId: FAMILY.DESCRIBE,
          operationId: OPERATION.DESCRIBE.GET,
          requestId: request.frame.requestId,
          body: fixture.descriptor.bytes
        })
      })
      return new Response(response, {
        status: 200,
        headers: new Headers([
          ['content-type', PROTOCOL.mediaType],
          ['content-length', String(response.byteLength)]
        ])
      })
    }
  })
  const verified = await client.fetchVerifiedDescriptor({
    canonicalUrl: fixture.descriptor.value.endpoints[0].canonicalUrl,
    expectedDescriptorHash: fixture.descriptor.hash,
    nowEpoch: 101,
    ...supportFor(fixture.descriptor.value)
  })
  t.alike(verified.descriptorHash, fixture.descriptor.hash)
  t.is(observed.url, 'https://relay.example/api/blind/v1/describe')
  t.alike(observed.init.headers, [['content-type', PROTOCOL.mediaType]])
  t.absent(observed.init.headers.find(([name]) => name === 'authorization'))

  await t.exception(client.fetchVerifiedDescriptor({
    canonicalUrl: fixture.descriptor.value.endpoints[0].canonicalUrl,
    nowEpoch: 101,
    ...supportFor(fixture.descriptor.value)
  }), /expectedDescriptorHash/)
})

test('descriptor trust advances exact sequence/hash and quarantines a same-sequence fork', async t => {
  const fixture = await trustedFixture()
  const next = signedDescriptor(fixture.keys, fixture.admission, {
    storeId: fixture.descriptor.value.storeId,
    descriptorSequence: 1n,
    previousDescriptorHash: fixture.descriptor.hash,
    descriptorNonce: b4a.alloc(32, 0x73)
  })
  const verifiedNext = verifyDescriptorBytes(next.bytes, { nowEpoch: 101, ...supportFor(next.value) })
  const continuation = { continuityRootRelayPublicKey: fixture.trusted.rootRelayPublicKey }
  const trustedNext = await fixture.trust.accept(verifiedNext, continuation)
  t.is(trustedNext.descriptorSequence, 1n)

  const fork = signedDescriptor(fixture.keys, fixture.admission, {
    storeId: fixture.descriptor.value.storeId,
    descriptorSequence: 1n,
    previousDescriptorHash: fixture.descriptor.hash,
    descriptorNonce: b4a.alloc(32, 0x74)
  })
  const verifiedFork = verifyDescriptorBytes(fork.bytes, { nowEpoch: 101, ...supportFor(fork.value) })
  await t.exception(fixture.trust.accept(verifiedFork, continuation), /fork detected/)
  await t.exception(fixture.trust.accept(verifiedNext, continuation), /quarantined/)
})

test('relay-chosen store IDs cannot collision-quarantine another continuity root', async t => {
  const storeId = b4a.alloc(32, 0x7a)
  const keysA = keyPair(0x3a)
  const keysB = keyPair(0x3b)
  const admissionA = signedAdmission(keysA)
  const admissionB = signedAdmission(keysB)
  const descriptorA = signedDescriptor(keysA, admissionA, {
    storeId,
    descriptorNonce: b4a.alloc(32, 0x7b)
  })
  const descriptorB = signedDescriptor(keysB, admissionB, {
    storeId,
    descriptorNonce: b4a.alloc(32, 0x7c)
  })
  const verifiedA = verifyDescriptorBytes(descriptorA.bytes, {
    nowEpoch: 101,
    ...supportFor(descriptorA.value)
  })
  const verifiedB = verifyDescriptorBytes(descriptorB.bytes, {
    nowEpoch: 101,
    ...supportFor(descriptorB.value)
  })
  const trust = new DescriptorTrustStore()
  const trustedA = await trust.accept(verifiedA, { pinnedDescriptorHash: descriptorA.hash })
  const trustedB = await trust.accept(verifiedB, { pinnedDescriptorHash: descriptorB.hash })
  t.alike(trustedA.rootRelayPublicKey, keysA.publicKey)
  t.alike(trustedB.rootRelayPublicKey, keysB.publicKey)

  const nextA = signedDescriptor(keysA, admissionA, {
    storeId,
    descriptorSequence: 1n,
    previousDescriptorHash: descriptorA.hash,
    descriptorNonce: b4a.alloc(32, 0x7d)
  })
  const verifiedNextA = verifyDescriptorBytes(nextA.bytes, {
    nowEpoch: 101,
    ...supportFor(nextA.value)
  })
  await t.exception(trust.accept(verifiedNextA), /persisted continuity root/)
  const continuedA = await trust.accept(verifiedNextA, {
    continuityRootRelayPublicKey: trustedA.rootRelayPublicKey
  })
  t.is(continuedA.descriptorSequence, 1n)
})

test('descriptor trust accepts only an exact dual-signed relay identity rotation', async t => {
  const fixture = await trustedFixture(0x34)
  const nextKeys = keyPair(0x35)
  const transition = signedIdentityTransition(
    fixture.keys,
    nextKeys,
    fixture.descriptor.value.identitySequence
  )
  const nextChanges = {
    storeId: fixture.descriptor.value.storeId,
    descriptorSequence: 1n,
    previousDescriptorHash: fixture.descriptor.hash,
    identitySequence: 1n,
    previousRelayKey: fixture.keys.publicKey,
    issuedEpoch: 101,
    expiresEpoch: 105,
    descriptorNonce: b4a.alloc(32, 0x82)
  }
  const invalid = signedDescriptor(nextKeys, fixture.admission, {
    ...nextChanges,
    identityTransition: { ...transition, oldSignature: b4a.alloc(64, 0x83) }
  })
  const invalidVerified = verifyDescriptorBytes(invalid.bytes, {
    nowEpoch: 101,
    ...supportFor(invalid.value)
  })
  const continuation = { continuityRootRelayPublicKey: fixture.trusted.rootRelayPublicKey }
  await t.exception(fixture.trust.accept(invalidVerified, continuation), /old identity transition signature is invalid/)

  const next = signedDescriptor(nextKeys, fixture.admission, {
    ...nextChanges,
    identityTransition: transition
  })
  const verified = verifyDescriptorBytes(next.bytes, { nowEpoch: 101, ...supportFor(next.value) })
  const trusted = await fixture.trust.accept(verified, continuation)
  t.is(trusted.descriptorSequence, 1n)
  t.alike(trusted.rootRelayPublicKey, fixture.keys.publicKey)
})

test('descriptor trust rejects an in-chain durability identity substitution', async t => {
  const fixture = await trustedFixture(0x36)
  const witnessKeys = keyPair(0x37)
  const changed = signedDescriptor(fixture.keys, fixture.admission, {
    storeId: fixture.descriptor.value.storeId,
    descriptorSequence: 1n,
    previousDescriptorHash: fixture.descriptor.hash,
    durability: profile2Durability(witnessKeys.publicKey),
    descriptorNonce: b4a.alloc(32, 0x84)
  })
  const verified = verifyDescriptorBytes(changed.bytes, {
    nowEpoch: 101,
    ...supportFor(changed.value)
  })
  await t.exception(fixture.trust.accept(verified, {
    continuityRootRelayPublicKey: fixture.trusted.rootRelayPublicKey
  }), /changed the trusted durability continuity/)
})

test('fresh signed health and admission parameters qualify one opaque generic endpoint', async t => {
  const fixture = await trustedFixture()
  const operation = operationBit(FAMILY.DESCRIBE, OPERATION.DESCRIBE.GET)
  const challenge = createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits: operation,
    clientNonce: b4a.alloc(32, 0x75)
  })
  const healthBytes = signedHealth(fixture.keys, fixture.descriptor.value,
    fixture.descriptor.hash, challenge.request)
  const decodedHealth = decodeCanonical(blindHealthResultV1, healthBytes, { copyBytes: true })
  t.is(challenge.request.endpointId, 1)
  t.is(challenge.request.transportSupportBit, TRANSPORT_SUPPORT.DIRECT_HTTP)
  t.is(decodedHealth.endpointId, challenge.request.endpointId)
  t.is(decodedHealth.transportSupportBit, challenge.request.transportSupportBit)
  const health = verifyHealthResultBytes(healthBytes, fixture.trusted, challenge.request, { nowEpoch: 101 })
  const descriptorValidity = trustedDescriptorValidity(fixture.trusted)
  t.alike(descriptorValidity, {
    issuedEpoch: fixture.descriptor.value.issuedEpoch,
    expiresEpoch: fixture.descriptor.value.expiresEpoch
  })
  t.is(Object.isFrozen(descriptorValidity), true)
  t.exception(() => trustedDescriptorValidity(
    Object.create(Object.getPrototypeOf(fixture.trusted))), /TrustedDescriptor/)
  const healthValidity = verifiedHealthValidity(health)
  t.is(healthValidity.expiresAtMonotonicMillis - healthValidity.verifiedAtMonotonicMillis,
    10 * 60 * 1000)
  t.is(Object.isFrozen(healthValidity), true)
  t.exception(() => verifiedHealthValidity(
    Object.create(Object.getPrototypeOf(health))), /VerifiedHealth/)
  const endpoint = qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health,
    nowEpoch: 101,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  })
  t.alike(endpoint.relayPublicKey, fixture.keys.publicKey)
  t.is(endpoint.familyId, FAMILY.DESCRIBE)

  const unrelated = await trustedFixture(0x38)
  t.exception(() => qualifyRelay({
    trustedDescriptor: unrelated.trusted,
    health,
    nowEpoch: 101,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  }), /fresh health does not prove requested readiness/)

  const verifiedAdmission = verifyAdmissionParametersBytes(fixture.admission.bytes,
    fixture.trusted, fixture.descriptor.value.admissionProfiles[0], { nowEpoch: 101 })
  t.alike(verifiedAdmission.parameterHash, fixture.admission.hash)
  const admissionValidity = verifiedAdmissionParametersValidity(verifiedAdmission)
  t.alike(admissionValidity, {
    validFromEpoch: fixture.admission.value.validFromEpoch,
    expiresEpoch: fixture.admission.value.expiresEpoch
  })
  t.is(Object.isFrozen(admissionValidity), true)
  t.exception(() => verifiedAdmissionParametersValidity(
    Object.create(Object.getPrototypeOf(verifiedAdmission))), /VerifiedAdmissionParameters/)
  t.exception(() => verifyAdmissionParametersBytes(fixture.admission.bytes,
    fixture.trusted, fixture.descriptor.value.admissionProfiles[0],
    { nowEpoch: fixture.admission.value.expiresEpoch }), /outside their signed epoch window/)
  const advertisedAdmission = trustedAdmissionProfile(fixture.trusted, 7)
  t.alike(advertisedAdmission.parameterHash, fixture.admission.hash)
  advertisedAdmission.parameterHash[0] ^= 0xff
  t.alike(trustedAdmissionProfile(fixture.trusted, 7).parameterHash, fixture.admission.hash)
  t.is(trustedAdmissionProfile(fixture.trusted, 0xffff), null)

  const rogueAdmissionValue = {
    ...fixture.admission.value,
    profileId: 8,
    schemeId: 10,
    signature: b4a.alloc(64)
  }
  const rogueAdmissionBytes = signedValue(admissionParametersV1, rogueAdmissionValue,
    RESULT_SIGNATURE_DOMAIN_ID.ADMISSION_PARAMETERS, fixture.keys.secretKey)
  const rogueAdmissionProfile = {
    ...fixture.descriptor.value.admissionProfiles[0],
    profileId: 8,
    schemeId: 10,
    parameterHash: admissionParametersHash(rogueAdmissionBytes)
  }
  t.exception(() => verifyAdmissionParametersBytes(rogueAdmissionBytes,
    fixture.trusted, rogueAdmissionProfile, { nowEpoch: 101 }), /signed descriptor profile/)

  const boundedHealth = verifyHealthResultBytes(healthBytes,
    fixture.trusted, challenge.request, { nowEpoch: 101, observedMonotonicMillis: 1000 })
  t.exception(() => qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health: boundedHealth,
    nowEpoch: 101,
    nowMonotonicMillis: 601001,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  }), /fresh health does not prove requested readiness/)

  t.exception(() => qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health,
    nowEpoch: fixture.descriptor.value.expiresEpoch,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  }), /descriptor is expired/)

  const invalidHealth = b4a.from(healthBytes)
  invalidHealth[invalidHealth.byteLength - 1] ^= 1
  t.exception(() => verifyHealthResultBytes(invalidHealth,
    fixture.trusted, challenge.request, { nowEpoch: 101 }), /signature is invalid/)

  for (const drift of [
    { endpointId: 2 },
    { transportSupportBit: TRANSPORT_SUPPORT.DIRECT_NATIVE }
  ]) {
    const crossEndpointReplay = signedHealth(fixture.keys, fixture.descriptor.value,
      fixture.descriptor.hash, challenge.request, drift)
    t.exception(() => verifyHealthResultBytes(crossEndpointReplay,
      fixture.trusted, challenge.request, { nowEpoch: 101 }), /does not correlate/)
  }

  t.exception(() => createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits: operationBit(FAMILY.CORE, OPERATION.CORE.OPEN_REPLICATION)
  }), /unsupported by the bound endpoint transport/)
  t.exception(() => createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: 0x40,
    requestedRoleBits: 1,
    requestedOperationBits: operation
  }), /not in the closed registry/)
})

test('trusted descriptor control endpoint breaks the health cycle without authorizing storage', async t => {
  const fixture = await trustedFixture(0x39)
  const requestedOperation = operationBit(FAMILY.CELL, OPERATION.CELL.PUT)
  const challenge = createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits: requestedOperation,
    clientNonce: b4a.alloc(32, 0x77)
  })
  const endpoint = qualifyDescribeControlEndpoint({
    trustedDescriptor: fixture.trusted,
    nowEpoch: 101,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.CHALLENGE,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  })
  const context = verifiedEndpointContext(endpoint)
  t.is(context.familyId, FAMILY.DESCRIBE)
  t.is(context.operationId, OPERATION.DESCRIBE.CHALLENGE)
  t.exception(() => qualifyDescribeControlEndpoint({
    trustedDescriptor: fixture.trusted,
    nowEpoch: 101,
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  }), /only a DESCRIBE operation/)

  const direct = new BlindDirectHttpClient({
    runtime,
    fetch: async (_url, init) => {
      const request = decodeOuterEnvelope(init.body, { copyBody: true })
      const response = encodeOuterEnvelope({
        outerClass: request.outerClass,
        innerDispatch: encodeDispatchFrame({
          frameKind: FRAME_KIND.RESPONSE,
          familyId: FAMILY.DESCRIBE,
          operationId: OPERATION.DESCRIBE.CHALLENGE,
          requestId: request.frame.requestId,
          body: signedHealth(fixture.keys, fixture.descriptor.value,
            fixture.descriptor.hash, challenge.request)
        })
      })
      return new Response(response, {
        status: 200,
        headers: new Headers([
          ['content-type', PROTOCOL.mediaType],
          ['content-length', String(response.byteLength)]
        ])
      })
    }
  })
  const response = await direct.request({
    endpoint,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.CHALLENGE,
    expectedResultBodyBytes: 16384,
    body: challenge.requestBytes
  })
  const health = verifyHealthResultBytes(response.body,
    fixture.trusted, challenge.request, { nowEpoch: 101 })
  const storage = qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health,
    nowEpoch: 101,
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  })
  t.is(verifiedEndpointContext(storage).operationId, OPERATION.CELL.PUT)
})

test('verified health cannot replay across two otherwise valid endpoint transports', async t => {
  const base = decodeCanonical(blindServiceDescriptorV1, descriptorVector, { copyBytes: true }).endpoints[0]
  const fixture = await trustedFixture(0x3a, {
    endpoints: [
      { ...base, envelopeClassBits: 0x007e },
      {
        ...base,
        endpointId: 2,
        transportId: TRANSPORT_ID.DIRECT_PROTOMUX_NOISE,
        transportProfileHash: b4a.alloc(32, 0x7a),
        canonicalUrl: b4a.from('https://native-relay.example:443/api/blind/v1/describe')
      }
    ]
  })
  const requestedOperationBits = operationBit(FAMILY.DESCRIBE, OPERATION.DESCRIBE.GET)
  const challenge = createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits,
    clientNonce: b4a.alloc(32, 0x7b)
  })
  const health = verifyHealthResultBytes(signedHealth(fixture.keys, fixture.descriptor.value,
    fixture.descriptor.hash, challenge.request), fixture.trusted, challenge.request, { nowEpoch: 101 })
  t.exception(() => qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health,
    nowEpoch: 101,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    endpointId: 2,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_NATIVE
  }), /fresh health does not prove requested readiness/)
})

test('generic qualifier composes pinned discovery through fresh operation readiness', async t => {
  const fixture = await trustedFixture(0x3c)
  const observedOperations = []
  const fetch = async (_url, init) => {
    const request = decodeOuterEnvelope(init.body, { copyBody: true })
    observedOperations.push(request.frame.operationId)
    let body
    if (request.frame.operationId === OPERATION.DESCRIBE.GET) {
      body = fixture.descriptor.bytes
    } else {
      const challenge = decodeCanonical(blindHealthChallengeV1, request.frame.body, { copyBytes: true })
      body = signedHealth(fixture.keys, fixture.descriptor.value,
        fixture.descriptor.hash, challenge)
    }
    const response = encodeOuterEnvelope({
      outerClass: request.outerClass,
      innerDispatch: encodeDispatchFrame({
        frameKind: FRAME_KIND.RESPONSE,
        familyId: FAMILY.DESCRIBE,
        operationId: request.frame.operationId,
        requestId: request.frame.requestId,
        body
      })
    })
    return new Response(response, {
      status: 200,
      headers: new Headers([
        ['content-type', PROTOCOL.mediaType],
        ['content-length', String(response.byteLength)]
      ])
    })
  }
  const qualifier = new BlindRelayQualifier({
    runtime,
    fetch,
    nowEpoch: () => 101,
    ...supportFor(fixture.descriptor.value)
  })
  const qualified = await qualifier.qualifyCandidate({
    canonicalUrl: fixture.descriptor.value.endpoints[0].canonicalUrl,
    expectedDescriptorHash: fixture.descriptor.hash
  }, {
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  })
  t.alike(observedOperations, [OPERATION.DESCRIBE.GET, OPERATION.DESCRIBE.CHALLENGE])
  t.is(verifiedEndpointContext(qualified.endpoint).operationId, OPERATION.CELL.PUT)
  t.alike(qualified.continuityRootRelayPublicKey, fixture.keys.publicKey)
})

test('ordinary direct transport accepts a VerifiedEndpoint and derives the fixed listener route', async t => {
  const fixture = await trustedFixture()
  const operation = operationBit(FAMILY.DESCRIBE, OPERATION.DESCRIBE.GET)
  const challenge = createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits: operation,
    clientNonce: b4a.alloc(32, 0x76)
  })
  const health = verifyHealthResultBytes(signedHealth(fixture.keys, fixture.descriptor.value,
    fixture.descriptor.hash, challenge.request), fixture.trusted, challenge.request, { nowEpoch: 101 })
  const endpoint = qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health,
    nowEpoch: 101,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  })
  let observedUrl
  const client = new BlindDirectHttpClient({
    runtime,
    fetch: async (url, init) => {
      observedUrl = url
      const request = decodeOuterEnvelope(init.body, { copyBody: true })
      const response = encodeOuterEnvelope({
        outerClass: request.outerClass,
        innerDispatch: encodeDispatchFrame({
          frameKind: FRAME_KIND.RESPONSE,
          familyId: FAMILY.DESCRIBE,
          operationId: OPERATION.DESCRIBE.GET,
          requestId: request.frame.requestId,
          body: fixture.descriptor.bytes
        })
      })
      return new Response(response, {
        status: 200,
        headers: new Headers([
          ['content-type', PROTOCOL.mediaType],
          ['content-length', String(response.byteLength)]
        ])
      })
    }
  })
  const response = await client.request({
    endpoint,
    familyId: FAMILY.DESCRIBE,
    operationId: OPERATION.DESCRIBE.GET,
    expectedResultBodyBytes: 16384,
    body: b4a.from([1])
  })
  t.ok(response.ok)
  t.alike(response.body, fixture.descriptor.bytes)
  t.is(observedUrl, 'https://relay.example/api/blind/v1/describe')
})

test('closed result verifier accepts one fully bound signed cell receipt and rejects correlation drift', async t => {
  const fixture = await trustedFixture()
  const operation = operationBit(FAMILY.CELL, OPERATION.CELL.PUT)
  const challenge = createHealthChallenge({
    runtime,
    trustedDescriptor: fixture.trusted,
    endpointId: 1,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    requestedRoleBits: 1,
    requestedOperationBits: operation,
    clientNonce: b4a.alloc(32, 0x77)
  })
  const health = verifyHealthResultBytes(signedHealth(fixture.keys, fixture.descriptor.value,
    fixture.descriptor.hash, challenge.request), fixture.trusted, challenge.request, { nowEpoch: 101 })
  const endpoint = qualifyRelay({
    trustedDescriptor: fixture.trusted,
    health,
    nowEpoch: 101,
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    endpointId: 1,
    requiredRoleBits: 1,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP
  })
  const created = await createCellReplica({
    runtime,
    relayPublicKey: fixture.keys.publicKey,
    allocationEpoch: 101,
    sizeClass: 1,
    leaseClass: 1,
    structuredContent: b4a.from('opaque result-verifier fixture'),
    admission: {
      profileId: 7,
      schemeId: 9,
      parameterHash: fixture.admission.hash,
      token: b4a.from([1])
    }
  })
  const relayBinding = {
    version: 1,
    relayPublicKey: fixture.keys.publicKey,
    storeId: fixture.descriptor.value.storeId,
    descriptorSequence: fixture.descriptor.value.descriptorSequence,
    descriptorHash: fixture.descriptor.hash,
    durabilityProfileId: 1,
    durabilityContinuityHash: fixture.descriptor.value.durabilityContinuityHash,
    durabilityProfileHash: fixture.descriptor.value.durabilityProfileHash,
    restoreEvidenceHeadSequence: 0n,
    restoreEvidenceHeadHash: b4a.alloc(32),
    externalCommitWitness: null
  }
  const receipt = {
    version: 1,
    protocol: b4a.from('hiverelay-blind-cell-v1', 'ascii'),
    relayBinding,
    slotCommitment: blake2b256(created.request.storageSlot),
    cellBlobHash: created.request.declaredBlobHash,
    allocationCommitment: created.allocationCommitment,
    requestCommitment: created.requestCommitment,
    sizeClass: created.request.sizeClass,
    allocationEpoch: created.request.allocationEpoch,
    leaseClass: created.request.leaseClass,
    leaseEpoch: 105,
    stateRevision: 0n,
    receiptEpoch: 101,
    requestNonce: created.request.clientNonce,
    result: 1,
    signature: b4a.alloc(64)
  }
  const resultBytes = signedValue(blindReceiptV1, receipt,
    RESULT_SIGNATURE_DOMAIN_ID.CELL_RECEIPT, fixture.keys.secretKey)
  const verified = verifyOperationResult({
    endpoint,
    request: created.request,
    requestCommitment: created.requestCommitment,
    resultBytes
  })
  t.is(verified.familyId, FAMILY.CELL)
  t.alike(verified.snapshotBytes(), resultBytes)
  t.exception(() => verifyOperationResult({
    endpoint,
    request: created.request,
    requestCommitment: b4a.alloc(32, 0x7d),
    resultBytes
  }), /canonical attempted request/)

  const endpointContext = verifiedEndpointContext(endpoint)
  const intent = createClientIntent({
    runtime,
    logicalId: b4a.alloc(32, 0x79),
    continuityRoot: endpointContext.continuityRoot,
    storeId: endpointContext.storeId,
    descriptorHash: endpointContext.descriptorHash,
    descriptorSequence: endpointContext.descriptorSequence,
    endpointId: endpointContext.endpointId,
    transportId: endpointContext.transportId,
    transportSupportBit: endpointContext.transportSupportBit,
    privacyProfileBit: endpointContext.privacyProfileBit,
    familyId: endpointContext.familyId,
    operationId: endpointContext.operationId,
    requestCommitment: created.requestCommitment,
    clientNonce: created.request.clientNonce,
    operationBytes: created.requestBytes
  })
  const intentStore = new EncryptedIntentStore({
    backend: new MemoryIntentBackend(),
    sealer: createAesGcmIntentSealer(runtime, b4a.alloc(32, 0x7a))
  })
  await journalSignedIntent(intentStore, intent, {
    ephemeralSecrets: [created.writeCap.createPrivateKey]
  })
  let sends = 0
  const attempt = new DurableAttempt({
    store: intentStore,
    transport: {
      async request (request) {
        sends++
        t.alike(request.body, created.requestBytes)
        return { ok: true, body: resultBytes }
      }
    }
  })
  const completed = await attempt.execute({ intentId: intent.intentId, endpoint })
  t.is(completed.intent.state, INTENT_STATE.RESULT_VERIFIED)
  t.is(sends, 1)
  const replayed = await attempt.execute({ intentId: intent.intentId, endpoint })
  t.is(replayed.replayed, true)
  t.is(sends, 1)

  const retryIntent = createClientIntent({
    runtime,
    intentId: b4a.alloc(32, 0x7b),
    logicalId: b4a.alloc(32, 0x7c),
    continuityRoot: endpointContext.continuityRoot,
    storeId: endpointContext.storeId,
    descriptorHash: endpointContext.descriptorHash,
    descriptorSequence: endpointContext.descriptorSequence,
    endpointId: endpointContext.endpointId,
    transportId: endpointContext.transportId,
    transportSupportBit: endpointContext.transportSupportBit,
    privacyProfileBit: endpointContext.privacyProfileBit,
    familyId: endpointContext.familyId,
    operationId: endpointContext.operationId,
    requestCommitment: created.requestCommitment,
    clientNonce: created.request.clientNonce,
    operationBytes: created.requestBytes
  })
  await intentStore.create(retryIntent)
  const retryBodies = []
  const retryAttempt = new DurableAttempt({
    store: intentStore,
    transport: {
      async request (request) {
        retryBodies.push(b4a.from(request.body))
        if (retryBodies.length === 1) throw Object.freeze(new Error('simulated response loss'))
        return { ok: true, body: resultBytes }
      }
    }
  })
  await t.exception(retryAttempt.execute({ intentId: retryIntent.intentId, endpoint }), /response loss/)
  t.is((await intentStore.read(retryIntent.intentId)).value.state, INTENT_STATE.PENDING_UNKNOWN)
  const retried = await retryAttempt.execute({ intentId: retryIntent.intentId, endpoint })
  t.is(retried.intent.attemptCount, 2)
  t.alike(retryBodies[0], retryBodies[1])

  const drift = { ...receipt, requestCommitment: b4a.alloc(32, 0x78), signature: b4a.alloc(64) }
  const driftBytes = signedValue(blindReceiptV1, drift,
    RESULT_SIGNATURE_DOMAIN_ID.CELL_RECEIPT, fixture.keys.secretKey)
  t.exception(() => verifyOperationResult({
    endpoint,
    request: created.request,
    requestCommitment: created.requestCommitment,
    resultBytes: driftBytes
  }), /requestCommitment/)
})

test('profile-2 result verification recomputes and verifies the independent commit witness', async t => {
  const witnessKeys = keyPair(0x42)
  const fixture = await qualifiedCellEndpoint(0x43, {
    durability: profile2Durability(witnessKeys.publicKey)
  })
  const context = verifiedEndpointContext(fixture.endpoint)
  const created = await createCellReplica({
    runtime,
    relayPublicKey: fixture.keys.publicKey,
    allocationEpoch: 101,
    sizeClass: 1,
    leaseClass: 1,
    structuredContent: b4a.from('opaque profile-2 result fixture'),
    admission: {
      profileId: 7,
      schemeId: 9,
      parameterHash: fixture.admission.hash,
      token: b4a.from([1])
    }
  })
  const relayBinding = {
    version: 1,
    relayPublicKey: fixture.keys.publicKey,
    storeId: context.storeId,
    descriptorSequence: context.descriptorSequence,
    descriptorHash: context.descriptorHash,
    durabilityProfileId: 2,
    durabilityContinuityHash: context.durabilityContinuityHash,
    durabilityProfileHash: context.durabilityProfileHash,
    restoreEvidenceHeadSequence: 0n,
    restoreEvidenceHeadHash: b4a.alloc(32),
    externalCommitWitness: null
  }
  const receipt = {
    version: 1,
    protocol: b4a.from('hiverelay-blind-cell-v1', 'ascii'),
    relayBinding,
    slotCommitment: blake2b256(created.request.storageSlot),
    cellBlobHash: created.request.declaredBlobHash,
    allocationCommitment: created.allocationCommitment,
    requestCommitment: created.requestCommitment,
    sizeClass: created.request.sizeClass,
    allocationEpoch: created.request.allocationEpoch,
    leaseClass: created.request.leaseClass,
    leaseEpoch: 105,
    stateRevision: 0n,
    receiptEpoch: 101,
    requestNonce: created.request.clientNonce,
    result: 1,
    signature: b4a.alloc(64)
  }
  const absent = encodeCanonical(blindReceiptV1, receipt)
  const resultCommitment = persistentResultCommitment(
    FAMILY.CELL,
    OPERATION.CELL.PUT,
    absent.subarray(0, absent.byteLength - 64)
  )
  const witness = signAuxiliaryValue(blindExternalCommitWitnessV1, {
    version: 1,
    relayPublicKey: fixture.keys.publicKey,
    storeId: context.storeId,
    externalJournalId: context.externalJournalId,
    durabilityContinuityHash: context.durabilityContinuityHash,
    durabilityProfileHash: context.durabilityProfileHash,
    restoreEvidenceHeadSequence: 0n,
    restoreEvidenceHeadHash: b4a.alloc(32),
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    requestCommitment: created.requestCommitment,
    resultCommitment,
    commitWalSequence: 10n,
    commitWalHash: b4a.alloc(32, 0xa4),
    coveringFloorRevision: 1n,
    coveringFloorHash: b4a.alloc(32, 0xa5),
    coveringFloorWalSequence: 11n,
    coveringFloorWalHash: b4a.alloc(32, 0xa6),
    writerEpoch: 1n,
    writerFenceTokenHash: b4a.alloc(32, 0xa7),
    externalLeaseRevision: 1n,
    witnessedUnixMillis: 1n,
    witnessPublicKey: witnessKeys.publicKey,
    signature: b4a.alloc(64)
  }, AUXILIARY_SIGNATURE_DOMAIN_ID.EXTERNAL_COMMIT_WITNESS, witnessKeys.secretKey)
  const resultBytes = signedValue(blindReceiptV1, {
    ...receipt,
    relayBinding: { ...relayBinding, externalCommitWitness: witness }
  }, RESULT_SIGNATURE_DOMAIN_ID.CELL_RECEIPT, fixture.keys.secretKey)
  const verified = verifyOperationResult({
    endpoint: fixture.endpoint,
    request: created.request,
    requestCommitment: created.requestCommitment,
    resultBytes,
    externalWitnessVerifier: ({ resultCommitment: observed }) => b4a.equals(observed, resultCommitment)
  })
  t.alike(verified.snapshotBytes(), resultBytes)

  const missingBytes = signedValue(blindReceiptV1, receipt,
    RESULT_SIGNATURE_DOMAIN_ID.CELL_RECEIPT, fixture.keys.secretKey)
  t.exception(() => verifyOperationResult({
    endpoint: fixture.endpoint,
    request: created.request,
    requestCommitment: created.requestCommitment,
    resultBytes: missingBytes,
    requireExternalWitness: false,
    externalWitnessVerifier: () => true
  }), /omitted its external commit witness/)

  const forgedWitness = { ...witness, signature: b4a.alloc(64, 0xa8) }
  const forgedBytes = signedValue(blindReceiptV1, {
    ...receipt,
    relayBinding: { ...relayBinding, externalCommitWitness: forgedWitness }
  }, RESULT_SIGNATURE_DOMAIN_ID.CELL_RECEIPT, fixture.keys.secretKey)
  t.exception(() => verifyOperationResult({
    endpoint: fixture.endpoint,
    request: created.request,
    requestCommitment: created.requestCommitment,
    resultBytes: forgedBytes,
    externalWitnessVerifier: () => true
  }), /external commit witness signature is invalid/)
})

test('rendezvous selection accepts one unregistered relay, deduplicates continuity and bounds repairs', async t => {
  const fixtures = await Promise.all([0x41, 0x51, 0x61, 0x71].map(qualifiedCellEndpoint))
  const pool = new RelayCandidatePool({
    selectionKey: b4a.alloc(32, 0x21),
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT
  })
  for (const fixture of fixtures) pool.add(fixture.endpoint)
  pool.add(fixtures[0].endpoint)
  const logicalId = b4a.alloc(32, 0x22)
  const first = pool.select(logicalId)
  const second = pool.select(logicalId)
  t.is(first.length, 3)
  t.alike(first.map(value => value.relayPublicKey), second.map(value => value.relayPublicKey))

  const oneRelayPool = new RelayCandidatePool({
    selectionKey: b4a.alloc(32, 0x23),
    familyId: FAMILY.CELL,
    operationId: OPERATION.CELL.PUT,
    transportSupportBit: TRANSPORT_SUPPORT.DIRECT_HTTP,
    privacyProfileBit: PRIVACY_PROFILE.DIRECT
  })
  oneRelayPool.add(fixtures[0].endpoint)
  t.is(oneRelayPool.select(logicalId).length, 1)

  const durability = new DurabilityTracker()
  const stored = durability.observe(logicalId, first[0], { acknowledged: true })
  t.is(stored.remoteStored, true)
  t.is(stored.label, 'remote-stored')
  t.is(durability.observe(logicalId, first[0]).remoteStored, true)
  const operatorGroupId = b4a.alloc(32, 0x24)
  t.is(durability.observe(logicalId, first[0], {
    readbackVerified: true,
    operatorGroupId
  }).label, 'remote-readback-verified')
  t.exception(() => durability.observe(logicalId, first[0], {
    operatorGroupId: b4a.alloc(32, 0x25)
  }), /operator-group evidence changed/)
  const repairs = durability.repairTargets(logicalId, pool)
  t.is(repairs.length, 2)
  t.absent(repairs.some(value => b4a.equals(value.relayPublicKey, first[0].relayPublicKey)))

  pool.recordFailure(first[1], 10)
  t.absent(pool.select(logicalId, { nowTick: 10 }).some(value =>
    b4a.equals(value.relayPublicKey, first[1].relayPublicKey)))
})