rhi

Coordinated trade for connected markets
git clone https://radroots.dev/git/rhi.git
Log | Files | Refs | README | LICENSE

state_catalog.rs (131375B)


      1 //! Immutable RHI schema and migration catalog identity.
      2 
      3 use core::fmt;
      4 use std::error::Error;
      5 
      6 use radroots_service_sqlite::{
      7     MigrationCatalog, MigrationChecksum, MigrationDescriptor, SchemaCatalog, SchemaDigest,
      8     SchemaObject, SchemaObjectKind, SchemaVersionCatalog,
      9 };
     10 
     11 /// The shared create-new baseline written before RHI migrations run.
     12 pub const RHI_STATE_BASE_SCHEMA_VERSION: u32 = 1;
     13 
     14 /// The newest governed RHI state schema understood by this binary.
     15 pub const RHI_STATE_SCHEMA_VERSION: u32 = 11;
     16 
     17 /// The shared metadata and migration-ledger objects present at schema v1.
     18 pub const RHI_STATE_SCHEMA_VERSION_1_OBJECT_COUNT: u32 = 6;
     19 
     20 /// The shared objects plus the bounded append-only RHI configuration history.
     21 pub const RHI_STATE_SCHEMA_VERSION_2_OBJECT_COUNT: u32 = 10;
     22 
     23 /// The shared objects, configuration history, and immutable trade evidence.
     24 pub const RHI_STATE_SCHEMA_VERSION_3_OBJECT_COUNT: u32 = 22;
     25 
     26 /// The shared objects, immutable trade evidence, source cursors, and dirty generations.
     27 pub const RHI_STATE_SCHEMA_VERSION_4_OBJECT_COUNT: u32 = 28;
     28 
     29 /// The shared objects, canonical evidence, cursors, generations, and durable jobs.
     30 pub const RHI_STATE_SCHEMA_VERSION_5_OBJECT_COUNT: u32 = 33;
     31 
     32 /// The shared objects plus immutable reconciliation attempt/source results.
     33 pub const RHI_STATE_SCHEMA_VERSION_6_OBJECT_COUNT: u32 = 39;
     34 
     35 /// The shared objects plus immutable report and publication workflow state.
     36 pub const RHI_STATE_SCHEMA_VERSION_7_OBJECT_COUNT: u32 = 63;
     37 
     38 /// The shared objects plus fail-closed reconciliation-job shape guards.
     39 pub const RHI_STATE_SCHEMA_VERSION_8_OBJECT_COUNT: u32 = 65;
     40 
     41 /// The shared objects plus deterministic durable presence desired state.
     42 pub const RHI_STATE_SCHEMA_VERSION_9_OBJECT_COUNT: u32 = 69;
     43 
     44 /// The shared objects plus durable exact-byte presence delivery state.
     45 pub const RHI_STATE_SCHEMA_VERSION_10_OBJECT_COUNT: u32 = 80;
     46 
     47 /// The complete v10 state plus the bounded durable admin-operation journal.
     48 pub const RHI_STATE_SCHEMA_VERSION_11_OBJECT_COUNT: u32 = 82;
     49 
     50 /// SHA-256 identity of the ordered migration catalog rooted at schema v1.
     51 pub const RHI_MIGRATION_CATALOG_SHA256: [u8; 32] = [
     52     0xe6, 0xcb, 0xac, 0xbd, 0x1e, 0xb6, 0x36, 0xc1, 0xa5, 0x60, 0xf8, 0x5e, 0xf8, 0xe5, 0x1e, 0x89,
     53     0xc9, 0xff, 0xe3, 0xb3, 0x42, 0xe6, 0x6b, 0xc5, 0xc0, 0xb4, 0x7a, 0xb3, 0x4e, 0x90, 0xc8, 0x18,
     54 ];
     55 
     56 /// SHA-256 identity of the exact schema-v1 object snapshot.
     57 pub const RHI_STATE_SCHEMA_VERSION_1_SHA256: [u8; 32] = [
     58     0x94, 0xdc, 0x66, 0xfb, 0xca, 0x60, 0x16, 0x79, 0x61, 0x5c, 0x05, 0x52, 0x29, 0xdc, 0x0d, 0xb6,
     59     0x11, 0x9f, 0x5b, 0xd9, 0x2b, 0x04, 0x39, 0x0c, 0x67, 0xf6, 0x98, 0xa0, 0x36, 0xfa, 0x78, 0xae,
     60 ];
     61 
     62 /// SHA-256 identity of the schema-v2 configuration-binding migration.
     63 pub const RHI_STATE_SCHEMA_VERSION_2_MIGRATION_SHA256: [u8; 32] = [
     64     0xa2, 0xc1, 0xaa, 0x53, 0xf7, 0xfe, 0xee, 0x03, 0x85, 0xe7, 0x74, 0xde, 0x20, 0xe0, 0x72, 0x52,
     65     0x0f, 0x49, 0x26, 0xc5, 0x59, 0xc6, 0x42, 0x1a, 0xab, 0x59, 0x0e, 0x92, 0xba, 0x14, 0x4c, 0x55,
     66 ];
     67 
     68 /// SHA-256 identity of the exact schema-v2 object snapshot.
     69 pub const RHI_STATE_SCHEMA_VERSION_2_SHA256: [u8; 32] = [
     70     0xbc, 0xcb, 0xf1, 0xe6, 0x2f, 0xe7, 0x64, 0x4c, 0x9c, 0x37, 0x72, 0x05, 0xb2, 0x5a, 0x92, 0x29,
     71     0x8e, 0x08, 0x8b, 0x8c, 0x26, 0xd1, 0x5b, 0xa4, 0x51, 0x33, 0xca, 0x5e, 0x9b, 0x73, 0x15, 0xa9,
     72 ];
     73 
     74 /// SHA-256 identity of the schema-v3 trade-evidence migration.
     75 pub const RHI_STATE_SCHEMA_VERSION_3_MIGRATION_SHA256: [u8; 32] = [
     76     0x07, 0xb0, 0x98, 0xc3, 0x93, 0x14, 0x0a, 0xfe, 0xc2, 0x22, 0xfc, 0xe7, 0x6e, 0xc6, 0x68, 0x69,
     77     0x8d, 0x50, 0xf1, 0xd2, 0x37, 0x85, 0x85, 0x68, 0x73, 0xe3, 0x04, 0x45, 0xaf, 0x1a, 0x01, 0x3f,
     78 ];
     79 
     80 /// SHA-256 identity of the exact schema-v3 object snapshot.
     81 pub const RHI_STATE_SCHEMA_VERSION_3_SHA256: [u8; 32] = [
     82     0xfd, 0x96, 0x22, 0x64, 0x05, 0xab, 0x68, 0x65, 0x5a, 0xee, 0x00, 0xf6, 0x83, 0xf6, 0x02, 0x3c,
     83     0x7a, 0xab, 0x2d, 0xbd, 0x23, 0xfe, 0xad, 0xac, 0x16, 0x53, 0x33, 0x49, 0x0d, 0x6f, 0x0a, 0xd5,
     84 ];
     85 
     86 /// SHA-256 identity of the schema-v4 source-checkpoint migration.
     87 pub const RHI_STATE_SCHEMA_VERSION_4_MIGRATION_SHA256: [u8; 32] = [
     88     0x24, 0x41, 0xf7, 0xc4, 0xc1, 0x15, 0x94, 0xc6, 0xfd, 0xe7, 0x87, 0xdb, 0xb9, 0x4e, 0x44, 0xba,
     89     0x00, 0xb7, 0x2d, 0x2c, 0x97, 0x9b, 0x0e, 0x7f, 0xd3, 0xc7, 0x33, 0xea, 0xe9, 0x14, 0x4d, 0x78,
     90 ];
     91 
     92 /// SHA-256 identity of the exact schema-v4 object snapshot.
     93 pub const RHI_STATE_SCHEMA_VERSION_4_SHA256: [u8; 32] = [
     94     0x9c, 0xa7, 0x8a, 0x54, 0xb0, 0xea, 0x20, 0x13, 0xe7, 0xaa, 0x70, 0xd0, 0x9b, 0xea, 0xdc, 0xfb,
     95     0x6c, 0xdd, 0xe0, 0x7c, 0x40, 0x42, 0x9d, 0xff, 0xe9, 0x1c, 0xb8, 0x3c, 0x2a, 0x42, 0x5c, 0xea,
     96 ];
     97 
     98 /// SHA-256 identity of the schema-v5 reconciliation-job migration.
     99 pub const RHI_STATE_SCHEMA_VERSION_5_MIGRATION_SHA256: [u8; 32] = [
    100     0x82, 0x75, 0xff, 0xb3, 0xd5, 0xc9, 0xfa, 0x0c, 0x76, 0x48, 0xf8, 0x9e, 0x8b, 0xfb, 0x92, 0x87,
    101     0x7b, 0x0d, 0xcd, 0x5e, 0xf3, 0xbf, 0x0b, 0x52, 0x54, 0xb7, 0xff, 0xd2, 0x58, 0x0b, 0xd4, 0x5d,
    102 ];
    103 
    104 /// SHA-256 identity of the exact schema-v5 object snapshot.
    105 pub const RHI_STATE_SCHEMA_VERSION_5_SHA256: [u8; 32] = [
    106     0xee, 0xf6, 0x7b, 0x48, 0x40, 0x0d, 0xee, 0x23, 0x4f, 0x6c, 0x36, 0xd4, 0x22, 0x55, 0x1c, 0x7e,
    107     0x99, 0x83, 0x15, 0x0b, 0x88, 0x7f, 0x26, 0x42, 0x50, 0xf9, 0xc8, 0x7a, 0x1a, 0x31, 0x3e, 0x60,
    108 ];
    109 
    110 /// SHA-256 identity of the schema-v6 reconciliation-result migration.
    111 pub const RHI_STATE_SCHEMA_VERSION_6_MIGRATION_SHA256: [u8; 32] = [
    112     0x48, 0xa1, 0x4b, 0x27, 0x44, 0xc4, 0x11, 0x86, 0x49, 0x6d, 0x59, 0x7e, 0xc7, 0x80, 0xad, 0x99,
    113     0x8f, 0xa9, 0x30, 0x8a, 0x9c, 0x9d, 0x75, 0x40, 0xd4, 0x75, 0xdb, 0x3f, 0x4d, 0xcf, 0xc4, 0xbb,
    114 ];
    115 
    116 /// SHA-256 identity of the exact schema-v6 object snapshot.
    117 pub const RHI_STATE_SCHEMA_VERSION_6_SHA256: [u8; 32] = [
    118     0x5d, 0x1f, 0xa9, 0x50, 0x8b, 0x5b, 0x8a, 0x0c, 0x80, 0x65, 0xfd, 0x37, 0xf1, 0x1c, 0x68, 0x66,
    119     0xd5, 0x1f, 0x92, 0x94, 0xc7, 0x52, 0x72, 0x04, 0x1f, 0x34, 0x9e, 0x95, 0xce, 0xd5, 0x0f, 0xb4,
    120 ];
    121 
    122 /// SHA-256 identity of the schema-v7 report/publication migration.
    123 pub const RHI_STATE_SCHEMA_VERSION_7_MIGRATION_SHA256: [u8; 32] = [
    124     0x9d, 0xeb, 0xf4, 0xf3, 0xca, 0xad, 0x4d, 0x01, 0x83, 0x11, 0xcb, 0x16, 0x9b, 0xf9, 0x28, 0x22,
    125     0x64, 0xd6, 0xab, 0xfc, 0x49, 0xe7, 0x18, 0x84, 0x0b, 0x9c, 0xbf, 0xad, 0x42, 0xed, 0x35, 0x7c,
    126 ];
    127 
    128 /// SHA-256 identity of the exact schema-v7 object snapshot.
    129 pub const RHI_STATE_SCHEMA_VERSION_7_SHA256: [u8; 32] = [
    130     0x84, 0x0a, 0xa8, 0x3c, 0x68, 0x9f, 0x9d, 0xf9, 0x9d, 0x26, 0xc5, 0xb4, 0xef, 0x11, 0x71, 0x31,
    131     0xc2, 0x70, 0xef, 0x75, 0x22, 0x67, 0x40, 0x37, 0xde, 0xf7, 0x96, 0x28, 0xa2, 0xb0, 0x39, 0x46,
    132 ];
    133 
    134 /// SHA-256 identity of the schema-v8 reconciliation-job shape-guard migration.
    135 pub const RHI_STATE_SCHEMA_VERSION_8_MIGRATION_SHA256: [u8; 32] = [
    136     0x6d, 0x3a, 0xa0, 0x6e, 0x69, 0x08, 0xe4, 0x28, 0x1b, 0x50, 0x66, 0xed, 0x4a, 0x13, 0xe2, 0x28,
    137     0x7b, 0xda, 0xec, 0x05, 0xb0, 0xe5, 0x39, 0x21, 0x58, 0x91, 0x89, 0x2a, 0x5a, 0xfb, 0x58, 0x3b,
    138 ];
    139 
    140 /// SHA-256 identity of the exact schema-v8 object snapshot.
    141 pub const RHI_STATE_SCHEMA_VERSION_8_SHA256: [u8; 32] = [
    142     0x7c, 0xef, 0x55, 0x9a, 0xe1, 0xe6, 0xef, 0xe1, 0x58, 0xc5, 0xd1, 0xde, 0x50, 0x11, 0x4e, 0xba,
    143     0xcc, 0xac, 0x90, 0x53, 0x8e, 0x0c, 0xd4, 0x9a, 0x4e, 0xe2, 0x14, 0xcb, 0x0a, 0x39, 0xc6, 0x18,
    144 ];
    145 
    146 /// SHA-256 identity of the schema-v9 presence desired-state migration.
    147 pub const RHI_STATE_SCHEMA_VERSION_9_MIGRATION_SHA256: [u8; 32] = [
    148     0x32, 0xda, 0xbe, 0x77, 0x72, 0x89, 0xe0, 0xfb, 0x6e, 0x64, 0xa4, 0xc1, 0xf8, 0x25, 0x78, 0x43,
    149     0xfc, 0x08, 0x01, 0x83, 0x21, 0xc3, 0xb7, 0xec, 0x5c, 0xa5, 0x84, 0xfa, 0x18, 0x62, 0xbd, 0xcc,
    150 ];
    151 
    152 /// SHA-256 identity of the exact schema-v9 object snapshot.
    153 pub const RHI_STATE_SCHEMA_VERSION_9_SHA256: [u8; 32] = [
    154     0x55, 0x51, 0xe8, 0x79, 0x05, 0x44, 0xa7, 0xc7, 0x8c, 0x83, 0x76, 0xc5, 0xcc, 0xf8, 0x3d, 0xd2,
    155     0xa8, 0x48, 0x6d, 0x2d, 0xc0, 0x8b, 0x6a, 0x78, 0x08, 0xbb, 0x20, 0x07, 0xc9, 0x43, 0x35, 0xec,
    156 ];
    157 
    158 /// SHA-256 identity of the schema-v10 presence-publication migration.
    159 pub const RHI_STATE_SCHEMA_VERSION_10_MIGRATION_SHA256: [u8; 32] = [
    160     0x54, 0x1a, 0xd1, 0x3b, 0x2c, 0xb0, 0x8d, 0x59, 0x85, 0x72, 0x05, 0xe6, 0xff, 0xae, 0xc1, 0x9b,
    161     0x74, 0xde, 0x08, 0x53, 0x24, 0x0f, 0xdf, 0x11, 0xfa, 0x13, 0x40, 0xe4, 0x06, 0xc7, 0x11, 0x4e,
    162 ];
    163 
    164 /// SHA-256 identity of the exact schema-v10 object snapshot.
    165 pub const RHI_STATE_SCHEMA_VERSION_10_SHA256: [u8; 32] = [
    166     0xd2, 0xae, 0xd5, 0x1d, 0x0a, 0x6a, 0x2c, 0x01, 0xed, 0xa1, 0x84, 0x46, 0x08, 0x47, 0x2b, 0x2d,
    167     0xcd, 0x50, 0x2a, 0xba, 0xa8, 0xa4, 0xca, 0x30, 0xa4, 0x82, 0x35, 0x35, 0xb8, 0xbd, 0x0e, 0x45,
    168 ];
    169 
    170 /// SHA-256 identity of the schema-v11 admin-operation-journal migration.
    171 pub const RHI_STATE_SCHEMA_VERSION_11_MIGRATION_SHA256: [u8; 32] = [
    172     0xe3, 0xfb, 0xde, 0x51, 0x1e, 0x84, 0x24, 0xc9, 0x70, 0x80, 0xbe, 0x2c, 0x09, 0xed, 0x81, 0x0a,
    173     0xe2, 0x84, 0x63, 0x1d, 0x75, 0xeb, 0x25, 0xc2, 0xe8, 0x8a, 0x60, 0x76, 0xb7, 0x00, 0xaa, 0xef,
    174 ];
    175 
    176 /// SHA-256 identity of the exact schema-v11 object snapshot.
    177 pub const RHI_STATE_SCHEMA_VERSION_11_SHA256: [u8; 32] = [
    178     0xc2, 0x5e, 0xc6, 0x3b, 0x33, 0xb4, 0x11, 0x61, 0x80, 0x68, 0xee, 0x06, 0xa0, 0x4c, 0x99, 0xee,
    179     0x71, 0x66, 0xe0, 0x01, 0x4d, 0x97, 0x90, 0x39, 0xfa, 0xea, 0xea, 0x4d, 0xc1, 0xac, 0x7e, 0x62,
    180 ];
    181 
    182 /// SHA-256 identity of the schema catalog bound to the migration catalog.
    183 pub const RHI_STATE_SCHEMA_CATALOG_SHA256: [u8; 32] = [
    184     0xae, 0xc4, 0x82, 0x81, 0x8b, 0xd9, 0xa6, 0xf3, 0x3f, 0xd9, 0x2b, 0x55, 0xd1, 0x42, 0xc6, 0xb8,
    185     0x5a, 0xa6, 0xf0, 0x86, 0x85, 0x57, 0x01, 0xdf, 0xc4, 0xb7, 0x8f, 0x2a, 0x7e, 0xf5, 0xcf, 0x6d,
    186 ];
    187 
    188 macro_rules! rhi_config_bindings_table_sql {
    189     () => {
    190         r#"CREATE TABLE rhi_config_bindings (
    191     generation INTEGER NOT NULL PRIMARY KEY CHECK (generation BETWEEN 1 AND 1024),
    192     normalized_config_sha256 BLOB NOT NULL CHECK (length(normalized_config_sha256) = 32),
    193     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
    194     service_public_key TEXT NOT NULL
    195         CHECK (length(CAST(service_public_key AS BLOB)) = 64)
    196         CHECK (service_public_key NOT GLOB '*[^0-9a-f]*'),
    197     config_contract_version INTEGER NOT NULL
    198         CHECK (config_contract_version BETWEEN 1 AND 4294967295),
    199     state_contract_version INTEGER NOT NULL
    200         CHECK (state_contract_version BETWEEN 1 AND 4294967295),
    201     admin_contract_version INTEGER NOT NULL
    202         CHECK (admin_contract_version BETWEEN 1 AND 4294967295),
    203     status_contract_version INTEGER NOT NULL
    204         CHECK (status_contract_version BETWEEN 1 AND 4294967295),
    205     provider_contract_version INTEGER NOT NULL
    206         CHECK (provider_contract_version BETWEEN 1 AND 4294967295),
    207     applied_at_unix_s INTEGER NOT NULL
    208         CHECK (applied_at_unix_s BETWEEN 0 AND 9223372036854775807),
    209     service_version TEXT NOT NULL
    210         CHECK (length(CAST(service_version AS BLOB)) BETWEEN 1 AND 128),
    211     service_commit TEXT NOT NULL
    212         CHECK (length(CAST(service_commit AS BLOB)) = 40),
    213     lib_revision TEXT NOT NULL
    214         CHECK (length(CAST(lib_revision AS BLOB)) = 40),
    215     rust_version TEXT NOT NULL
    216         CHECK (length(CAST(rust_version AS BLOB)) BETWEEN 1 AND 128),
    217     target TEXT NOT NULL CHECK (length(CAST(target AS BLOB)) BETWEEN 1 AND 128),
    218     feature_profile TEXT NOT NULL
    219         CHECK (length(CAST(feature_profile AS BLOB)) BETWEEN 1 AND 128)
    220 ) STRICT"#
    221     };
    222 }
    223 
    224 macro_rules! rhi_config_bindings_guard_insert_sql {
    225     () => {
    226         r#"CREATE TRIGGER rhi_config_bindings_guard_insert
    227 BEFORE INSERT ON rhi_config_bindings
    228 WHEN NEW.generation != COALESCE(
    229         (SELECT MAX(generation) + 1 FROM rhi_config_bindings), 1
    230     )
    231     OR (SELECT COUNT(*) FROM rhi_config_bindings) >= 1024
    232     OR NEW.applied_at_unix_s < COALESCE(
    233         (SELECT MAX(applied_at_unix_s) FROM rhi_config_bindings), 0
    234     )
    235 BEGIN
    236     SELECT RAISE(ABORT, 'configuration binding sequence is invalid');
    237 END"#
    238     };
    239 }
    240 
    241 macro_rules! rhi_config_bindings_no_update_sql {
    242     () => {
    243         r#"CREATE TRIGGER rhi_config_bindings_no_update
    244 BEFORE UPDATE ON rhi_config_bindings
    245 BEGIN
    246     SELECT RAISE(ABORT, 'configuration binding history is immutable');
    247 END"#
    248     };
    249 }
    250 
    251 macro_rules! rhi_config_bindings_no_delete_sql {
    252     () => {
    253         r#"CREATE TRIGGER rhi_config_bindings_no_delete
    254 BEFORE DELETE ON rhi_config_bindings
    255 BEGIN
    256     SELECT RAISE(ABORT, 'configuration binding history is retained');
    257 END"#
    258     };
    259 }
    260 
    261 pub(crate) const CREATE_RHI_CONFIG_BINDINGS_TABLE_SQL: &str = rhi_config_bindings_table_sql!();
    262 const CREATE_RHI_CONFIG_BINDINGS_GUARD_INSERT_SQL: &str = rhi_config_bindings_guard_insert_sql!();
    263 const CREATE_RHI_CONFIG_BINDINGS_NO_UPDATE_SQL: &str = rhi_config_bindings_no_update_sql!();
    264 const CREATE_RHI_CONFIG_BINDINGS_NO_DELETE_SQL: &str = rhi_config_bindings_no_delete_sql!();
    265 const CREATE_RHI_CONFIG_BINDINGS_MIGRATION_SQL: &str = concat!(
    266     rhi_config_bindings_table_sql!(),
    267     ";\n",
    268     rhi_config_bindings_guard_insert_sql!(),
    269     ";\n",
    270     rhi_config_bindings_no_update_sql!(),
    271     ";\n",
    272     rhi_config_bindings_no_delete_sql!(),
    273     ";",
    274 );
    275 
    276 macro_rules! trade_mutations_table_sql {
    277     () => {
    278         r#"CREATE TABLE trade_mutations (
    279     mutation_id BLOB NOT NULL PRIMARY KEY CHECK (length(mutation_id) = 32),
    280     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
    281     contract_id TEXT NOT NULL CHECK (contract_id IN (
    282         'radroots.trade.proposal.v1',
    283         'radroots.trade.decision.v1',
    284         'radroots.trade.revision_proposal.v1',
    285         'radroots.trade.revision_decision.v1',
    286         'radroots.trade.cancellation.v1'
    287     )),
    288     schema_version INTEGER NOT NULL CHECK (schema_version = 1),
    289     event_kind INTEGER NOT NULL CHECK (event_kind IN (3470, 3471, 3472, 3473, 3474)),
    290     author_pubkey BLOB NOT NULL CHECK (length(author_pubkey) = 32),
    291     canonical_content BLOB NOT NULL
    292         CHECK (length(canonical_content) BETWEEN 1 AND 131072)
    293 ) STRICT"#
    294     };
    295 }
    296 
    297 macro_rules! trade_mutations_by_trade_sql {
    298     () => {
    299         r#"CREATE INDEX trade_mutations_by_trade
    300 ON trade_mutations (trade_id, mutation_id)"#
    301     };
    302 }
    303 
    304 macro_rules! nostr_events_table_sql {
    305     () => {
    306         r#"CREATE TABLE nostr_events (
    307     event_id BLOB NOT NULL CHECK (length(event_id) = 32),
    308     event_signature BLOB NOT NULL CHECK (length(event_signature) = 64),
    309     mutation_id BLOB NOT NULL CHECK (length(mutation_id) = 32)
    310         REFERENCES trade_mutations (mutation_id),
    311     author_pubkey BLOB NOT NULL CHECK (length(author_pubkey) = 32),
    312     event_kind INTEGER NOT NULL CHECK (event_kind IN (3470, 3471, 3472, 3473, 3474)),
    313     authored_at_unix_s INTEGER NOT NULL
    314         CHECK (authored_at_unix_s BETWEEN 0 AND 9223372036854775807),
    315     canonical_event_json BLOB NOT NULL
    316         CHECK (length(canonical_event_json) BETWEEN 1 AND 524288),
    317     PRIMARY KEY (event_id, event_signature)
    318 ) STRICT"#
    319     };
    320 }
    321 
    322 macro_rules! nostr_events_by_mutation_sql {
    323     () => {
    324         r#"CREATE INDEX nostr_events_by_mutation
    325 ON nostr_events (mutation_id, authored_at_unix_s, event_id)"#
    326     };
    327 }
    328 
    329 macro_rules! relay_observations_table_sql {
    330     () => {
    331         r#"CREATE TABLE relay_observations (
    332     source_id TEXT NOT NULL
    333         CHECK (length(CAST(source_id AS BLOB)) BETWEEN 1 AND 64)
    334         CHECK (source_id NOT GLOB '*[^a-z0-9_-]*')
    335         CHECK (substr(source_id, 1, 1) GLOB '[a-z]'),
    336     selector_id TEXT NOT NULL CHECK (selector_id = 'trade_mutation_lineage_v1'),
    337     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
    338     event_id BLOB NOT NULL CHECK (length(event_id) = 32),
    339     event_signature BLOB NOT NULL CHECK (length(event_signature) = 64),
    340     observed_at_unix_s INTEGER NOT NULL
    341         CHECK (observed_at_unix_s BETWEEN 1 AND 9223372036854775807),
    342     FOREIGN KEY (event_id, event_signature)
    343         REFERENCES nostr_events (event_id, event_signature),
    344     PRIMARY KEY (
    345         source_id, selector_id, evidence_policy_sha256, event_id, event_signature,
    346         observed_at_unix_s
    347     )
    348 ) STRICT"#
    349     };
    350 }
    351 
    352 macro_rules! relay_observations_by_event_sql {
    353     () => {
    354         r#"CREATE INDEX relay_observations_by_event
    355 ON relay_observations (event_id, event_signature, observed_at_unix_s, source_id)"#
    356     };
    357 }
    358 
    359 macro_rules! immutable_no_update_sql {
    360     ($trigger:literal, $table:literal, $message:literal) => {
    361         concat!(
    362             "CREATE TRIGGER ",
    363             $trigger,
    364             "\nBEFORE UPDATE ON ",
    365             $table,
    366             "\nBEGIN\n    SELECT RAISE(ABORT, '",
    367             $message,
    368             "');\nEND"
    369         )
    370     };
    371 }
    372 
    373 macro_rules! immutable_no_delete_sql {
    374     ($trigger:literal, $table:literal, $message:literal) => {
    375         concat!(
    376             "CREATE TRIGGER ",
    377             $trigger,
    378             "\nBEFORE DELETE ON ",
    379             $table,
    380             "\nBEGIN\n    SELECT RAISE(ABORT, '",
    381             $message,
    382             "');\nEND"
    383         )
    384     };
    385 }
    386 
    387 pub(crate) const CREATE_TRADE_MUTATIONS_TABLE_SQL: &str = trade_mutations_table_sql!();
    388 const CREATE_TRADE_MUTATIONS_BY_TRADE_SQL: &str = trade_mutations_by_trade_sql!();
    389 pub(crate) const CREATE_NOSTR_EVENTS_TABLE_SQL: &str = nostr_events_table_sql!();
    390 const CREATE_NOSTR_EVENTS_BY_MUTATION_SQL: &str = nostr_events_by_mutation_sql!();
    391 pub(crate) const CREATE_RELAY_OBSERVATIONS_TABLE_SQL: &str = relay_observations_table_sql!();
    392 const CREATE_RELAY_OBSERVATIONS_BY_EVENT_SQL: &str = relay_observations_by_event_sql!();
    393 const CREATE_TRADE_MUTATIONS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
    394     "trade_mutations_no_update",
    395     "trade_mutations",
    396     "trade mutation evidence is immutable"
    397 );
    398 const CREATE_TRADE_MUTATIONS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
    399     "trade_mutations_no_delete",
    400     "trade_mutations",
    401     "trade mutation evidence is retained"
    402 );
    403 const CREATE_NOSTR_EVENTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
    404     "nostr_events_no_update",
    405     "nostr_events",
    406     "signed event evidence is immutable"
    407 );
    408 const CREATE_NOSTR_EVENTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
    409     "nostr_events_no_delete",
    410     "nostr_events",
    411     "signed event evidence is retained"
    412 );
    413 const CREATE_RELAY_OBSERVATIONS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
    414     "relay_observations_no_update",
    415     "relay_observations",
    416     "source observation evidence is immutable"
    417 );
    418 const CREATE_RELAY_OBSERVATIONS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
    419     "relay_observations_no_delete",
    420     "relay_observations",
    421     "source observation evidence is retained"
    422 );
    423 const CREATE_TRADE_EVIDENCE_MIGRATION_SQL: &str = concat!(
    424     trade_mutations_table_sql!(),
    425     ";\n",
    426     trade_mutations_by_trade_sql!(),
    427     ";\n",
    428     nostr_events_table_sql!(),
    429     ";\n",
    430     nostr_events_by_mutation_sql!(),
    431     ";\n",
    432     relay_observations_table_sql!(),
    433     ";\n",
    434     relay_observations_by_event_sql!(),
    435     ";\n",
    436     immutable_no_update_sql!(
    437         "trade_mutations_no_update",
    438         "trade_mutations",
    439         "trade mutation evidence is immutable"
    440     ),
    441     ";\n",
    442     immutable_no_delete_sql!(
    443         "trade_mutations_no_delete",
    444         "trade_mutations",
    445         "trade mutation evidence is retained"
    446     ),
    447     ";\n",
    448     immutable_no_update_sql!(
    449         "nostr_events_no_update",
    450         "nostr_events",
    451         "signed event evidence is immutable"
    452     ),
    453     ";\n",
    454     immutable_no_delete_sql!(
    455         "nostr_events_no_delete",
    456         "nostr_events",
    457         "signed event evidence is retained"
    458     ),
    459     ";\n",
    460     immutable_no_update_sql!(
    461         "relay_observations_no_update",
    462         "relay_observations",
    463         "source observation evidence is immutable"
    464     ),
    465     ";\n",
    466     immutable_no_delete_sql!(
    467         "relay_observations_no_delete",
    468         "relay_observations",
    469         "source observation evidence is retained"
    470     ),
    471     ";",
    472 );
    473 
    474 macro_rules! relay_checkpoints_table_sql {
    475     () => {
    476         r#"CREATE TABLE relay_checkpoints (
    477     source_id TEXT NOT NULL
    478         CHECK (length(CAST(source_id AS BLOB)) BETWEEN 1 AND 64)
    479         CHECK (source_id NOT GLOB '*[^a-z0-9_-]*')
    480         CHECK (substr(source_id, 1, 1) GLOB '[a-z]'),
    481     selector_id TEXT NOT NULL CHECK (selector_id = 'trade_mutation_lineage_v1'),
    482     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
    483     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
    484     cursor_created_at_unix_s INTEGER NOT NULL
    485         CHECK (cursor_created_at_unix_s BETWEEN 0 AND 9223372036854775807),
    486     cursor_event_id BLOB NOT NULL CHECK (length(cursor_event_id) = 32),
    487     revision INTEGER NOT NULL CHECK (revision BETWEEN 1 AND 9223372036854775807),
    488     completed_at_unix_s INTEGER NOT NULL
    489         CHECK (completed_at_unix_s BETWEEN 1 AND 9223372036854775807),
    490     PRIMARY KEY (source_id, selector_id, evidence_policy_sha256, trade_id)
    491 ) STRICT"#
    492     };
    493 }
    494 
    495 macro_rules! relay_checkpoints_guard_update_sql {
    496     () => {
    497         r#"CREATE TRIGGER relay_checkpoints_guard_update
    498 BEFORE UPDATE ON relay_checkpoints
    499 WHEN NEW.source_id != OLD.source_id
    500     OR NEW.selector_id != OLD.selector_id
    501     OR NEW.evidence_policy_sha256 != OLD.evidence_policy_sha256
    502     OR NEW.trade_id != OLD.trade_id
    503     OR NEW.revision != OLD.revision + 1
    504     OR NEW.completed_at_unix_s < OLD.completed_at_unix_s
    505     OR NEW.cursor_created_at_unix_s < OLD.cursor_created_at_unix_s
    506     OR (
    507         NEW.cursor_created_at_unix_s = OLD.cursor_created_at_unix_s
    508         AND NEW.cursor_event_id <= OLD.cursor_event_id
    509     )
    510 BEGIN
    511     SELECT RAISE(ABORT, 'relay checkpoint transition is invalid');
    512 END"#
    513     };
    514 }
    515 
    516 macro_rules! trade_dirty_generations_table_sql {
    517     () => {
    518         r#"CREATE TABLE trade_dirty_generations (
    519     trade_id BLOB NOT NULL PRIMARY KEY CHECK (length(trade_id) = 16),
    520     generation INTEGER NOT NULL CHECK (generation BETWEEN 1 AND 9223372036854775807),
    521     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
    522     updated_at_unix_s INTEGER NOT NULL
    523         CHECK (updated_at_unix_s BETWEEN 0 AND 9223372036854775807)
    524 ) STRICT"#
    525     };
    526 }
    527 
    528 macro_rules! trade_dirty_generations_guard_update_sql {
    529     () => {
    530         r#"CREATE TRIGGER trade_dirty_generations_guard_update
    531 BEFORE UPDATE ON trade_dirty_generations
    532 WHEN NEW.trade_id != OLD.trade_id
    533     OR NEW.generation != OLD.generation + 1
    534     OR NEW.updated_at_unix_s < OLD.updated_at_unix_s
    535 BEGIN
    536     SELECT RAISE(ABORT, 'trade dirty generation transition is invalid');
    537 END"#
    538     };
    539 }
    540 
    541 pub(crate) const CREATE_RELAY_CHECKPOINTS_TABLE_SQL: &str = relay_checkpoints_table_sql!();
    542 const CREATE_RELAY_CHECKPOINTS_GUARD_UPDATE_SQL: &str = relay_checkpoints_guard_update_sql!();
    543 const CREATE_RELAY_CHECKPOINTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
    544     "relay_checkpoints_no_delete",
    545     "relay_checkpoints",
    546     "relay checkpoints are retained"
    547 );
    548 pub(crate) const CREATE_TRADE_DIRTY_GENERATIONS_TABLE_SQL: &str =
    549     trade_dirty_generations_table_sql!();
    550 const CREATE_TRADE_DIRTY_GENERATIONS_GUARD_UPDATE_SQL: &str =
    551     trade_dirty_generations_guard_update_sql!();
    552 const CREATE_TRADE_DIRTY_GENERATIONS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
    553     "trade_dirty_generations_no_delete",
    554     "trade_dirty_generations",
    555     "trade dirty generations are retained"
    556 );
    557 const CREATE_SOURCE_CHECKPOINT_MIGRATION_SQL: &str = concat!(
    558     relay_checkpoints_table_sql!(),
    559     ";\n",
    560     relay_checkpoints_guard_update_sql!(),
    561     ";\n",
    562     immutable_no_delete_sql!(
    563         "relay_checkpoints_no_delete",
    564         "relay_checkpoints",
    565         "relay checkpoints are retained"
    566     ),
    567     ";\n",
    568     trade_dirty_generations_table_sql!(),
    569     ";\n",
    570     trade_dirty_generations_guard_update_sql!(),
    571     ";\n",
    572     immutable_no_delete_sql!(
    573         "trade_dirty_generations_no_delete",
    574         "trade_dirty_generations",
    575         "trade dirty generations are retained"
    576     ),
    577     ";",
    578 );
    579 
    580 macro_rules! reconciliation_jobs_table_sql {
    581     () => {
    582         r#"CREATE TABLE reconciliation_jobs (
    583     job_id BLOB NOT NULL PRIMARY KEY CHECK (length(job_id) = 32),
    584     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
    585     input_generation INTEGER NOT NULL
    586         CHECK (input_generation BETWEEN 1 AND 9223372036854775807),
    587     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
    588     state TEXT NOT NULL
    589         CHECK (state IN ('ready', 'leased', 'exhausted', 'superseded', 'completed')),
    590     revision INTEGER NOT NULL CHECK (revision BETWEEN 1 AND 9223372036854775807),
    591     attempt_count INTEGER NOT NULL CHECK (attempt_count BETWEEN 0 AND 100),
    592     failure_count INTEGER NOT NULL CHECK (failure_count BETWEEN 0 AND attempt_count),
    593     max_attempts INTEGER NOT NULL CHECK (max_attempts BETWEEN 1 AND 100),
    594     lease_duration_ms INTEGER NOT NULL CHECK (lease_duration_ms BETWEEN 1000 AND 300000),
    595     lease_renewal_ms INTEGER NOT NULL CHECK (lease_renewal_ms BETWEEN 100 AND 150000),
    596     initial_backoff_ms INTEGER NOT NULL CHECK (initial_backoff_ms BETWEEN 1 AND 60000),
    597     maximum_backoff_ms INTEGER NOT NULL CHECK (maximum_backoff_ms BETWEEN 1 AND 3600000),
    598     next_attempt_unix_ms INTEGER,
    599     lease_owner BLOB,
    600     lease_expires_unix_ms INTEGER,
    601     created_at_unix_ms INTEGER NOT NULL
    602         CHECK (created_at_unix_ms BETWEEN 0 AND 9223372036854775807),
    603     updated_at_unix_ms INTEGER NOT NULL
    604         CHECK (updated_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807),
    605     FOREIGN KEY (trade_id) REFERENCES trade_dirty_generations (trade_id),
    606     CHECK (lease_renewal_ms < lease_duration_ms),
    607     CHECK (initial_backoff_ms <= maximum_backoff_ms),
    608     CHECK (
    609         (state = 'ready'
    610             AND attempt_count < max_attempts
    611             AND next_attempt_unix_ms BETWEEN 0 AND 9223372036854775807
    612             AND lease_owner IS NULL
    613             AND lease_expires_unix_ms IS NULL)
    614         OR (state = 'leased'
    615             AND attempt_count BETWEEN 1 AND max_attempts
    616             AND next_attempt_unix_ms IS NULL
    617             AND length(lease_owner) = 16
    618             AND lease_expires_unix_ms BETWEEN 1 AND 9223372036854775807)
    619         OR (state IN ('exhausted', 'superseded', 'completed')
    620             AND next_attempt_unix_ms IS NULL
    621             AND lease_owner IS NULL
    622             AND lease_expires_unix_ms IS NULL)
    623     )
    624 ) STRICT"#
    625     };
    626 }
    627 
    628 macro_rules! reconciliation_jobs_one_active_sql {
    629     () => {
    630         r#"CREATE UNIQUE INDEX reconciliation_jobs_one_active_per_trade
    631 ON reconciliation_jobs (trade_id)
    632 WHERE state IN ('ready', 'leased')"#
    633     };
    634 }
    635 
    636 macro_rules! reconciliation_jobs_schedule_sql {
    637     () => {
    638         r#"CREATE INDEX reconciliation_jobs_by_schedule
    639 ON reconciliation_jobs (
    640     state, next_attempt_unix_ms, lease_expires_unix_ms,
    641     created_at_unix_ms, job_id
    642 )"#
    643     };
    644 }
    645 
    646 macro_rules! reconciliation_jobs_guard_update_sql {
    647     () => {
    648         r#"CREATE TRIGGER reconciliation_jobs_guard_update
    649 BEFORE UPDATE ON reconciliation_jobs
    650 WHEN NEW.job_id != OLD.job_id
    651     OR NEW.trade_id != OLD.trade_id
    652     OR NEW.input_generation != OLD.input_generation
    653     OR NEW.evidence_policy_sha256 != OLD.evidence_policy_sha256
    654     OR NEW.max_attempts != OLD.max_attempts
    655     OR NEW.lease_duration_ms != OLD.lease_duration_ms
    656     OR NEW.lease_renewal_ms != OLD.lease_renewal_ms
    657     OR NEW.initial_backoff_ms != OLD.initial_backoff_ms
    658     OR NEW.maximum_backoff_ms != OLD.maximum_backoff_ms
    659     OR NEW.created_at_unix_ms != OLD.created_at_unix_ms
    660     OR NEW.revision != OLD.revision + 1
    661     OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms
    662     OR NOT (
    663         (OLD.state = 'ready' AND NEW.state IN ('leased', 'superseded'))
    664         OR (OLD.state = 'leased'
    665             AND NEW.state IN ('leased', 'ready', 'exhausted', 'superseded', 'completed'))
    666         OR (OLD.state = 'exhausted' AND NEW.state = 'superseded')
    667     )
    668 BEGIN
    669     SELECT RAISE(ABORT, 'reconciliation job transition is invalid');
    670 END"#
    671     };
    672 }
    673 
    674 pub(crate) const CREATE_RECONCILIATION_JOBS_TABLE_SQL: &str = reconciliation_jobs_table_sql!();
    675 const CREATE_RECONCILIATION_JOBS_ONE_ACTIVE_SQL: &str = reconciliation_jobs_one_active_sql!();
    676 const CREATE_RECONCILIATION_JOBS_SCHEDULE_SQL: &str = reconciliation_jobs_schedule_sql!();
    677 const CREATE_RECONCILIATION_JOBS_GUARD_UPDATE_SQL: &str = reconciliation_jobs_guard_update_sql!();
    678 const CREATE_RECONCILIATION_JOBS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
    679     "reconciliation_jobs_no_delete",
    680     "reconciliation_jobs",
    681     "reconciliation jobs are retained"
    682 );
    683 const CREATE_RECONCILIATION_JOBS_MIGRATION_SQL: &str = concat!(
    684     reconciliation_jobs_table_sql!(),
    685     ";\n",
    686     reconciliation_jobs_one_active_sql!(),
    687     ";\n",
    688     reconciliation_jobs_schedule_sql!(),
    689     ";\n",
    690     reconciliation_jobs_guard_update_sql!(),
    691     ";\n",
    692     immutable_no_delete_sql!(
    693         "reconciliation_jobs_no_delete",
    694         "reconciliation_jobs",
    695         "reconciliation jobs are retained"
    696     ),
    697     ";",
    698 );
    699 
    700 macro_rules! reconciliation_jobs_shape_guard_insert_sql {
    701     () => {
    702         r#"CREATE TRIGGER reconciliation_jobs_shape_guard_insert
    703 BEFORE INSERT ON reconciliation_jobs
    704 WHEN (NEW.state = 'ready' AND (
    705         NEW.attempt_count >= NEW.max_attempts
    706         OR typeof(NEW.next_attempt_unix_ms) != 'integer'
    707         OR NEW.next_attempt_unix_ms NOT BETWEEN 0 AND 9223372036854775807
    708         OR NEW.lease_owner IS NOT NULL
    709         OR NEW.lease_expires_unix_ms IS NOT NULL
    710     ))
    711     OR (NEW.state = 'leased' AND (
    712         NEW.attempt_count NOT BETWEEN 1 AND NEW.max_attempts
    713         OR NEW.next_attempt_unix_ms IS NOT NULL
    714         OR typeof(NEW.lease_owner) != 'blob'
    715         OR length(NEW.lease_owner) != 16
    716         OR typeof(NEW.lease_expires_unix_ms) != 'integer'
    717         OR NEW.lease_expires_unix_ms NOT BETWEEN 1 AND 9223372036854775807
    718     ))
    719     OR (NEW.state IN ('exhausted', 'superseded', 'completed') AND (
    720         NEW.next_attempt_unix_ms IS NOT NULL
    721         OR NEW.lease_owner IS NOT NULL
    722         OR NEW.lease_expires_unix_ms IS NOT NULL
    723     ))
    724 BEGIN
    725     SELECT RAISE(ABORT, 'reconciliation job state shape is invalid');
    726 END"#
    727     };
    728 }
    729 
    730 macro_rules! reconciliation_jobs_shape_guard_update_sql {
    731     () => {
    732         r#"CREATE TRIGGER reconciliation_jobs_shape_guard_update
    733 BEFORE UPDATE ON reconciliation_jobs
    734 WHEN (NEW.state = 'ready' AND (
    735         NEW.attempt_count >= NEW.max_attempts
    736         OR typeof(NEW.next_attempt_unix_ms) != 'integer'
    737         OR NEW.next_attempt_unix_ms NOT BETWEEN 0 AND 9223372036854775807
    738         OR NEW.lease_owner IS NOT NULL
    739         OR NEW.lease_expires_unix_ms IS NOT NULL
    740     ))
    741     OR (NEW.state = 'leased' AND (
    742         NEW.attempt_count NOT BETWEEN 1 AND NEW.max_attempts
    743         OR NEW.next_attempt_unix_ms IS NOT NULL
    744         OR typeof(NEW.lease_owner) != 'blob'
    745         OR length(NEW.lease_owner) != 16
    746         OR typeof(NEW.lease_expires_unix_ms) != 'integer'
    747         OR NEW.lease_expires_unix_ms NOT BETWEEN 1 AND 9223372036854775807
    748     ))
    749     OR (NEW.state IN ('exhausted', 'superseded', 'completed') AND (
    750         NEW.next_attempt_unix_ms IS NOT NULL
    751         OR NEW.lease_owner IS NOT NULL
    752         OR NEW.lease_expires_unix_ms IS NOT NULL
    753     ))
    754 BEGIN
    755     SELECT RAISE(ABORT, 'reconciliation job state shape is invalid');
    756 END"#
    757     };
    758 }
    759 
    760 const CREATE_RECONCILIATION_JOBS_SHAPE_GUARD_INSERT_SQL: &str =
    761     reconciliation_jobs_shape_guard_insert_sql!();
    762 const CREATE_RECONCILIATION_JOBS_SHAPE_GUARD_UPDATE_SQL: &str =
    763     reconciliation_jobs_shape_guard_update_sql!();
    764 const CREATE_RECONCILIATION_JOB_SHAPE_GUARDS_MIGRATION_SQL: &str = concat!(
    765     "CREATE TABLE reconciliation_jobs_shape_scan_v1 (\n",
    766     "    invalid INTEGER NOT NULL CHECK (invalid = 0)\n",
    767     ") STRICT;\n",
    768     "INSERT INTO reconciliation_jobs_shape_scan_v1 (invalid)\n",
    769     "SELECT 1 FROM reconciliation_jobs\n",
    770     "WHERE (state = 'ready' AND (\n",
    771     "        attempt_count >= max_attempts\n",
    772     "        OR typeof(next_attempt_unix_ms) != 'integer'\n",
    773     "        OR next_attempt_unix_ms NOT BETWEEN 0 AND 9223372036854775807\n",
    774     "        OR lease_owner IS NOT NULL\n",
    775     "        OR lease_expires_unix_ms IS NOT NULL\n",
    776     "    ))\n",
    777     "    OR (state = 'leased' AND (\n",
    778     "        attempt_count NOT BETWEEN 1 AND max_attempts\n",
    779     "        OR next_attempt_unix_ms IS NOT NULL\n",
    780     "        OR typeof(lease_owner) != 'blob'\n",
    781     "        OR length(lease_owner) != 16\n",
    782     "        OR typeof(lease_expires_unix_ms) != 'integer'\n",
    783     "        OR lease_expires_unix_ms NOT BETWEEN 1 AND 9223372036854775807\n",
    784     "    ))\n",
    785     "    OR (state IN ('exhausted', 'superseded', 'completed') AND (\n",
    786     "        next_attempt_unix_ms IS NOT NULL\n",
    787     "        OR lease_owner IS NOT NULL\n",
    788     "        OR lease_expires_unix_ms IS NOT NULL\n",
    789     "    ))\n",
    790     "LIMIT 1;\n",
    791     "DROP TABLE reconciliation_jobs_shape_scan_v1;\n",
    792     reconciliation_jobs_shape_guard_insert_sql!(),
    793     ";\n",
    794     reconciliation_jobs_shape_guard_update_sql!(),
    795     ";",
    796 );
    797 
    798 macro_rules! presence_desired_state_table_sql {
    799     () => {
    800         r#"CREATE TABLE presence_desired_state (
    801     singleton INTEGER NOT NULL PRIMARY KEY CHECK (singleton = 1),
    802     generation INTEGER NOT NULL
    803         CHECK (generation BETWEEN 1 AND 9223372036854775807),
    804     enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
    805     profile INTEGER NOT NULL CHECK (profile IN (0, 1)),
    806     application_handler INTEGER NOT NULL CHECK (application_handler IN (0, 1)),
    807     target_set_sha256 BLOB NOT NULL CHECK (length(target_set_sha256) = 32),
    808     target_count INTEGER NOT NULL CHECK (target_count BETWEEN 0 AND 32),
    809     required_target_count INTEGER NOT NULL
    810         CHECK (required_target_count BETWEEN 0 AND target_count),
    811     queue_capacity INTEGER NOT NULL CHECK (queue_capacity BETWEEN 0 AND 4096),
    812     desired_sha256 BLOB NOT NULL UNIQUE CHECK (length(desired_sha256) = 32),
    813     CHECK (
    814         (enabled = 0 AND profile = 0 AND application_handler = 0
    815             AND target_count = 0 AND required_target_count = 0
    816             AND queue_capacity = 0)
    817         OR
    818         (enabled = 1 AND (profile = 1 OR application_handler = 1)
    819             AND target_count BETWEEN 1 AND 32
    820             AND queue_capacity BETWEEN 1 AND 4096)
    821     )
    822 ) STRICT"#
    823     };
    824 }
    825 
    826 macro_rules! presence_desired_state_guard_insert_sql {
    827     () => {
    828         r#"CREATE TRIGGER presence_desired_state_guard_insert
    829 BEFORE INSERT ON presence_desired_state
    830 WHEN NEW.generation != 1
    831     OR EXISTS (SELECT 1 FROM presence_desired_state)
    832 BEGIN
    833     SELECT RAISE(ABORT, 'presence desired-state insertion is invalid');
    834 END"#
    835     };
    836 }
    837 
    838 macro_rules! presence_desired_state_guard_update_sql {
    839     () => {
    840         r#"CREATE TRIGGER presence_desired_state_guard_update
    841 BEFORE UPDATE ON presence_desired_state
    842 WHEN NEW.singleton != OLD.singleton
    843     OR OLD.generation >= 9223372036854775807
    844     OR NEW.generation != OLD.generation + 1
    845     OR NEW.desired_sha256 = OLD.desired_sha256
    846 BEGIN
    847     SELECT RAISE(ABORT, 'presence desired-state transition is invalid');
    848 END"#
    849     };
    850 }
    851 
    852 macro_rules! presence_desired_state_no_delete_sql {
    853     () => {
    854         r#"CREATE TRIGGER presence_desired_state_no_delete
    855 BEFORE DELETE ON presence_desired_state
    856 BEGIN
    857     SELECT RAISE(ABORT, 'presence desired state is retained');
    858 END"#
    859     };
    860 }
    861 
    862 const CREATE_PRESENCE_DESIRED_STATE_TABLE_SQL: &str = presence_desired_state_table_sql!();
    863 const CREATE_PRESENCE_DESIRED_STATE_GUARD_INSERT_SQL: &str =
    864     presence_desired_state_guard_insert_sql!();
    865 const CREATE_PRESENCE_DESIRED_STATE_GUARD_UPDATE_SQL: &str =
    866     presence_desired_state_guard_update_sql!();
    867 const CREATE_PRESENCE_DESIRED_STATE_NO_DELETE_SQL: &str = presence_desired_state_no_delete_sql!();
    868 const CREATE_PRESENCE_DESIRED_STATE_MIGRATION_SQL: &str = concat!(
    869     presence_desired_state_table_sql!(),
    870     ";\n",
    871     presence_desired_state_guard_insert_sql!(),
    872     ";\n",
    873     presence_desired_state_guard_update_sql!(),
    874     ";\n",
    875     presence_desired_state_no_delete_sql!(),
    876     ";",
    877 );
    878 
    879 macro_rules! presence_outbox_table_sql {
    880     () => {
    881         r#"CREATE TABLE presence_outbox (
    882     outbox_id BLOB NOT NULL PRIMARY KEY CHECK (length(outbox_id) = 32),
    883     desired_generation INTEGER NOT NULL
    884         CHECK (desired_generation BETWEEN 1 AND 9223372036854775807),
    885     document_kind TEXT NOT NULL
    886         CHECK (document_kind IN ('service_profile', 'application_handler')),
    887     desired_sha256 BLOB NOT NULL CHECK (length(desired_sha256) = 32),
    888     target_set_sha256 BLOB NOT NULL CHECK (length(target_set_sha256) = 32),
    889     event_id BLOB NOT NULL CHECK (length(event_id) = 32),
    890     event_sha256 BLOB NOT NULL CHECK (length(event_sha256) = 32),
    891     exact_signed_event_bytes BLOB NOT NULL
    892         CHECK (length(exact_signed_event_bytes) BETWEEN 1 AND 32768),
    893     authored_at_unix_s INTEGER NOT NULL
    894         CHECK (authored_at_unix_s BETWEEN 0 AND 9223372036854775807),
    895     service_public_key TEXT NOT NULL
    896         CHECK (length(CAST(service_public_key AS BLOB)) = 64)
    897         CHECK (service_public_key NOT GLOB '*[^0-9a-f]*'),
    898     target_count INTEGER NOT NULL CHECK (target_count BETWEEN 1 AND 32),
    899     required_target_count INTEGER NOT NULL
    900         CHECK (required_target_count BETWEEN 0 AND target_count),
    901     max_attempts INTEGER NOT NULL CHECK (max_attempts = 100),
    902     initial_backoff_ms INTEGER NOT NULL CHECK (initial_backoff_ms = 250),
    903     maximum_backoff_ms INTEGER NOT NULL CHECK (maximum_backoff_ms = 30000),
    904     attempt_deadline_ms INTEGER NOT NULL CHECK (attempt_deadline_ms = 15000),
    905     state TEXT NOT NULL
    906         CHECK (state IN ('pending', 'leased', 'complete', 'blocked', 'superseded')),
    907     revision INTEGER NOT NULL CHECK (revision >= 1),
    908     next_attempt_unix_ms INTEGER
    909         CHECK (next_attempt_unix_ms IS NULL
    910             OR next_attempt_unix_ms BETWEEN 0 AND 9223372036854775807),
    911     lease_owner BLOB CHECK (lease_owner IS NULL OR length(lease_owner) = 16),
    912     lease_expires_unix_ms INTEGER
    913         CHECK (lease_expires_unix_ms IS NULL
    914             OR lease_expires_unix_ms BETWEEN 1 AND 9223372036854775807),
    915     created_at_unix_ms INTEGER NOT NULL
    916         CHECK (created_at_unix_ms BETWEEN 0 AND 9223372036854775807),
    917     updated_at_unix_ms INTEGER NOT NULL
    918         CHECK (updated_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807),
    919     UNIQUE (desired_generation, document_kind),
    920     CHECK (
    921         (state = 'pending' AND next_attempt_unix_ms IS NOT NULL
    922             AND lease_owner IS NULL AND lease_expires_unix_ms IS NULL)
    923         OR
    924         (state = 'leased' AND next_attempt_unix_ms IS NULL
    925             AND lease_owner IS NOT NULL AND lease_expires_unix_ms IS NOT NULL)
    926         OR
    927         (state IN ('complete', 'blocked', 'superseded')
    928             AND next_attempt_unix_ms IS NULL
    929             AND lease_owner IS NULL AND lease_expires_unix_ms IS NULL)
    930     )
    931 ) STRICT"#
    932     };
    933 }
    934 
    935 macro_rules! presence_outbox_schedule_sql {
    936     () => {
    937         r#"CREATE INDEX presence_outbox_by_schedule
    938 ON presence_outbox (state, next_attempt_unix_ms, created_at_unix_ms, document_kind, outbox_id)"#
    939     };
    940 }
    941 
    942 macro_rules! presence_outbox_guard_update_sql {
    943     () => {
    944         r#"CREATE TRIGGER presence_outbox_guard_update
    945 BEFORE UPDATE ON presence_outbox
    946 WHEN NEW.outbox_id != OLD.outbox_id
    947     OR NEW.desired_generation != OLD.desired_generation
    948     OR NEW.document_kind != OLD.document_kind
    949     OR NEW.desired_sha256 != OLD.desired_sha256
    950     OR NEW.target_set_sha256 != OLD.target_set_sha256
    951     OR NEW.event_id != OLD.event_id
    952     OR NEW.event_sha256 != OLD.event_sha256
    953     OR NEW.exact_signed_event_bytes != OLD.exact_signed_event_bytes
    954     OR NEW.authored_at_unix_s != OLD.authored_at_unix_s
    955     OR NEW.service_public_key != OLD.service_public_key
    956     OR NEW.target_count != OLD.target_count
    957     OR NEW.required_target_count != OLD.required_target_count
    958     OR NEW.max_attempts != OLD.max_attempts
    959     OR NEW.initial_backoff_ms != OLD.initial_backoff_ms
    960     OR NEW.maximum_backoff_ms != OLD.maximum_backoff_ms
    961     OR NEW.attempt_deadline_ms != OLD.attempt_deadline_ms
    962     OR NEW.created_at_unix_ms != OLD.created_at_unix_ms
    963     OR NEW.revision != OLD.revision + 1
    964     OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms
    965     OR NOT (
    966         (OLD.state = 'pending' AND NEW.state IN ('leased', 'superseded'))
    967         OR (OLD.state = 'leased'
    968             AND NEW.state IN ('pending', 'complete', 'blocked', 'superseded'))
    969         OR (OLD.state = 'blocked' AND NEW.state IN ('pending', 'superseded'))
    970     )
    971 BEGIN
    972     SELECT RAISE(ABORT, 'presence outbox transition is invalid');
    973 END"#
    974     };
    975 }
    976 
    977 macro_rules! presence_targets_table_sql {
    978     () => {
    979         r#"CREATE TABLE presence_targets (
    980     outbox_id BLOB NOT NULL CHECK (length(outbox_id) = 32),
    981     target_ordinal INTEGER NOT NULL CHECK (target_ordinal BETWEEN 0 AND 31),
    982     relay_id TEXT NOT NULL
    983         CHECK (length(CAST(relay_id AS BLOB)) BETWEEN 1 AND 64)
    984         CHECK (relay_id NOT GLOB '*[^a-z0-9_-]*')
    985         CHECK (substr(relay_id, 1, 1) GLOB '[a-z]'),
    986     required INTEGER NOT NULL CHECK (required IN (0, 1)),
    987     state TEXT NOT NULL CHECK (state IN (
    988         'pending', 'submitted', 'accepted', 'rejected',
    989         'rate_limited', 'auth_required', 'failed', 'unknown'
    990     )),
    991     revision INTEGER NOT NULL CHECK (revision >= 1),
    992     attempt_count INTEGER NOT NULL CHECK (attempt_count BETWEEN 0 AND 100),
    993     next_attempt_unix_ms INTEGER
    994         CHECK (next_attempt_unix_ms IS NULL
    995             OR next_attempt_unix_ms BETWEEN 0 AND 9223372036854775807),
    996     last_attempt_id BLOB
    997         CHECK (last_attempt_id IS NULL OR length(last_attempt_id) = 32),
    998     updated_at_unix_ms INTEGER NOT NULL
    999         CHECK (updated_at_unix_ms BETWEEN 0 AND 9223372036854775807),
   1000     PRIMARY KEY (outbox_id, target_ordinal),
   1001     UNIQUE (outbox_id, relay_id),
   1002     FOREIGN KEY (outbox_id) REFERENCES presence_outbox (outbox_id),
   1003     CHECK (
   1004         (state = 'pending' AND attempt_count = 0
   1005             AND next_attempt_unix_ms IS NOT NULL AND last_attempt_id IS NULL)
   1006         OR
   1007         (state = 'submitted' AND attempt_count BETWEEN 1 AND 100
   1008             AND next_attempt_unix_ms IS NULL AND last_attempt_id IS NOT NULL)
   1009         OR
   1010         (state IN ('accepted', 'rejected', 'auth_required')
   1011             AND attempt_count BETWEEN 1 AND 100
   1012             AND next_attempt_unix_ms IS NULL AND last_attempt_id IS NOT NULL)
   1013         OR
   1014         (state IN ('rate_limited', 'failed', 'unknown')
   1015             AND attempt_count BETWEEN 1 AND 99
   1016             AND next_attempt_unix_ms IS NOT NULL AND last_attempt_id IS NOT NULL)
   1017         OR
   1018         (state IN ('rate_limited', 'failed', 'unknown')
   1019             AND attempt_count = 100
   1020             AND next_attempt_unix_ms IS NULL AND last_attempt_id IS NOT NULL)
   1021     )
   1022 ) STRICT"#
   1023     };
   1024 }
   1025 
   1026 macro_rules! presence_targets_schedule_sql {
   1027     () => {
   1028         r#"CREATE INDEX presence_targets_by_schedule
   1029 ON presence_targets (state, next_attempt_unix_ms, outbox_id, target_ordinal)"#
   1030     };
   1031 }
   1032 
   1033 macro_rules! presence_targets_guard_update_sql {
   1034     () => {
   1035         r#"CREATE TRIGGER presence_targets_guard_update
   1036 BEFORE UPDATE ON presence_targets
   1037 WHEN NEW.outbox_id != OLD.outbox_id
   1038     OR NEW.target_ordinal != OLD.target_ordinal
   1039     OR NEW.relay_id != OLD.relay_id
   1040     OR NEW.required != OLD.required
   1041     OR NEW.revision != OLD.revision + 1
   1042     OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms
   1043     OR NOT (
   1044         (OLD.state IN ('pending', 'rate_limited', 'failed', 'unknown')
   1045             AND NEW.state = 'submitted'
   1046             AND NEW.attempt_count = OLD.attempt_count + 1
   1047             AND NEW.last_attempt_id IS NOT NULL
   1048             AND NEW.last_attempt_id IS NOT OLD.last_attempt_id)
   1049         OR
   1050         (OLD.state = 'submitted'
   1051             AND NEW.state IN (
   1052                 'accepted', 'rejected', 'rate_limited',
   1053                 'auth_required', 'failed', 'unknown'
   1054             )
   1055             AND NEW.attempt_count = OLD.attempt_count
   1056             AND NEW.last_attempt_id = OLD.last_attempt_id)
   1057     )
   1058 BEGIN
   1059     SELECT RAISE(ABORT, 'presence target transition is invalid');
   1060 END"#
   1061     };
   1062 }
   1063 
   1064 macro_rules! presence_attempts_table_sql {
   1065     () => {
   1066         r#"CREATE TABLE presence_attempts (
   1067     attempt_id BLOB NOT NULL PRIMARY KEY CHECK (length(attempt_id) = 32),
   1068     outbox_id BLOB NOT NULL CHECK (length(outbox_id) = 32),
   1069     target_ordinal INTEGER NOT NULL CHECK (target_ordinal BETWEEN 0 AND 31),
   1070     attempt_number INTEGER NOT NULL CHECK (attempt_number BETWEEN 1 AND 100),
   1071     event_sha256 BLOB NOT NULL CHECK (length(event_sha256) = 32),
   1072     lease_owner BLOB NOT NULL CHECK (length(lease_owner) = 16),
   1073     started_at_unix_ms INTEGER NOT NULL
   1074         CHECK (started_at_unix_ms BETWEEN 0 AND 9223372036854775807),
   1075     finished_at_unix_ms INTEGER NOT NULL
   1076         CHECK (finished_at_unix_ms BETWEEN started_at_unix_ms AND 9223372036854775807),
   1077     outcome TEXT NOT NULL CHECK (outcome IN (
   1078         'accepted', 'rejected', 'rate_limited',
   1079         'auth_required', 'failed', 'unknown'
   1080     )),
   1081     result_code TEXT NOT NULL
   1082         CHECK (length(CAST(result_code AS BLOB)) BETWEEN 1 AND 64),
   1083     UNIQUE (outbox_id, target_ordinal, attempt_number),
   1084     FOREIGN KEY (outbox_id, target_ordinal)
   1085         REFERENCES presence_targets (outbox_id, target_ordinal)
   1086 ) STRICT"#
   1087     };
   1088 }
   1089 
   1090 const CREATE_PRESENCE_OUTBOX_TABLE_SQL: &str = presence_outbox_table_sql!();
   1091 const CREATE_PRESENCE_OUTBOX_SCHEDULE_SQL: &str = presence_outbox_schedule_sql!();
   1092 const CREATE_PRESENCE_OUTBOX_GUARD_UPDATE_SQL: &str = presence_outbox_guard_update_sql!();
   1093 const CREATE_PRESENCE_OUTBOX_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1094     "presence_outbox_no_delete",
   1095     "presence_outbox",
   1096     "presence outbox rows are retained"
   1097 );
   1098 const CREATE_PRESENCE_TARGETS_TABLE_SQL: &str = presence_targets_table_sql!();
   1099 const CREATE_PRESENCE_TARGETS_SCHEDULE_SQL: &str = presence_targets_schedule_sql!();
   1100 const CREATE_PRESENCE_TARGETS_GUARD_UPDATE_SQL: &str = presence_targets_guard_update_sql!();
   1101 const CREATE_PRESENCE_TARGETS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1102     "presence_targets_no_delete",
   1103     "presence_targets",
   1104     "presence targets are retained"
   1105 );
   1106 const CREATE_PRESENCE_ATTEMPTS_TABLE_SQL: &str = presence_attempts_table_sql!();
   1107 const CREATE_PRESENCE_ATTEMPTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1108     "presence_attempts_no_update",
   1109     "presence_attempts",
   1110     "presence attempts are immutable"
   1111 );
   1112 const CREATE_PRESENCE_ATTEMPTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1113     "presence_attempts_no_delete",
   1114     "presence_attempts",
   1115     "presence attempts are retained"
   1116 );
   1117 
   1118 const CREATE_PRESENCE_PUBLICATION_MIGRATION_SQL: &str = concat!(
   1119     presence_outbox_table_sql!(),
   1120     ";\n",
   1121     presence_outbox_schedule_sql!(),
   1122     ";\n",
   1123     presence_outbox_guard_update_sql!(),
   1124     ";\n",
   1125     immutable_no_delete_sql!(
   1126         "presence_outbox_no_delete",
   1127         "presence_outbox",
   1128         "presence outbox rows are retained"
   1129     ),
   1130     ";\n",
   1131     presence_targets_table_sql!(),
   1132     ";\n",
   1133     presence_targets_schedule_sql!(),
   1134     ";\n",
   1135     presence_targets_guard_update_sql!(),
   1136     ";\n",
   1137     immutable_no_delete_sql!(
   1138         "presence_targets_no_delete",
   1139         "presence_targets",
   1140         "presence targets are retained"
   1141     ),
   1142     ";\n",
   1143     presence_attempts_table_sql!(),
   1144     ";\n",
   1145     immutable_no_update_sql!(
   1146         "presence_attempts_no_update",
   1147         "presence_attempts",
   1148         "presence attempts are immutable"
   1149     ),
   1150     ";\n",
   1151     immutable_no_delete_sql!(
   1152         "presence_attempts_no_delete",
   1153         "presence_attempts",
   1154         "presence attempts are retained"
   1155     ),
   1156     ";"
   1157 );
   1158 
   1159 macro_rules! evidence_reconciliations_table_sql {
   1160     () => {
   1161         r#"CREATE TABLE evidence_reconciliations (
   1162     attempt_id BLOB NOT NULL PRIMARY KEY CHECK (length(attempt_id) = 32),
   1163     job_id BLOB NOT NULL CHECK (length(job_id) = 32),
   1164     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
   1165     input_generation INTEGER NOT NULL
   1166         CHECK (input_generation BETWEEN 1 AND 9223372036854775807),
   1167     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
   1168     attempt_started_unix_ms INTEGER NOT NULL
   1169         CHECK (attempt_started_unix_ms BETWEEN 0 AND 9223372036854775807),
   1170     deadline_unix_ms INTEGER NOT NULL
   1171         CHECK (deadline_unix_ms BETWEEN attempt_started_unix_ms + 1 AND 9223372036854775807),
   1172     source_count INTEGER NOT NULL CHECK (source_count BETWEEN 1 AND 16),
   1173     FOREIGN KEY (job_id) REFERENCES reconciliation_jobs (job_id)
   1174 ) STRICT"#
   1175     };
   1176 }
   1177 
   1178 macro_rules! evidence_reconciliation_sources_table_sql {
   1179     () => {
   1180         r#"CREATE TABLE evidence_reconciliation_sources (
   1181     attempt_id BLOB NOT NULL CHECK (length(attempt_id) = 32),
   1182     request_id BLOB NOT NULL CHECK (length(request_id) = 32),
   1183     source_ordinal INTEGER NOT NULL CHECK (source_ordinal BETWEEN 0 AND 15),
   1184     source_id TEXT NOT NULL
   1185         CHECK (length(CAST(source_id AS BLOB)) BETWEEN 1 AND 64)
   1186         CHECK (source_id NOT GLOB '*[^a-z0-9_-]*')
   1187         CHECK (substr(source_id, 1, 1) GLOB '[a-z]'),
   1188     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
   1189     required INTEGER NOT NULL CHECK (required IN (0, 1)),
   1190     selector_sha256 BLOB NOT NULL CHECK (length(selector_sha256) = 32),
   1191     replay_id BLOB NOT NULL CHECK (length(replay_id) = 32),
   1192     completion TEXT NOT NULL CHECK (completion IN (
   1193         'complete', 'incomplete_timeout', 'incomplete_unavailable',
   1194         'incomplete_resource_limit', 'incomplete_unknown', 'unsupported'
   1195     )),
   1196     started_unix_ms INTEGER NOT NULL
   1197         CHECK (started_unix_ms BETWEEN 0 AND 9223372036854775807),
   1198     finished_unix_ms INTEGER NOT NULL
   1199         CHECK (finished_unix_ms BETWEEN started_unix_ms AND 9223372036854775807),
   1200     accepted_event_count INTEGER NOT NULL CHECK (accepted_event_count BETWEEN 0 AND 4096),
   1201     accepted_event_bytes INTEGER NOT NULL CHECK (accepted_event_bytes BETWEEN 0 AND 8388608),
   1202     accepted_inventory_sha256 BLOB NOT NULL CHECK (length(accepted_inventory_sha256) = 32),
   1203     duplicate_observation_count INTEGER NOT NULL
   1204         CHECK (duplicate_observation_count BETWEEN 0 AND 4096),
   1205     first_observed_unix_s INTEGER
   1206         CHECK (first_observed_unix_s BETWEEN 0 AND 9223372036854775807),
   1207     prior_cursor_created_at_unix_s INTEGER
   1208         CHECK (prior_cursor_created_at_unix_s BETWEEN 0 AND 9223372036854775807),
   1209     prior_cursor_event_id BLOB CHECK (length(prior_cursor_event_id) = 32),
   1210     overlap_seconds INTEGER NOT NULL CHECK (overlap_seconds BETWEEN 1 AND 86400),
   1211     inclusive_since_unix_s INTEGER NOT NULL
   1212         CHECK (inclusive_since_unix_s BETWEEN 0 AND 9223372036854775807),
   1213     candidate_created_at_unix_s INTEGER
   1214         CHECK (candidate_created_at_unix_s BETWEEN 0 AND 9223372036854775807),
   1215     candidate_event_id BLOB CHECK (length(candidate_event_id) = 32),
   1216     checkpoint_advanced INTEGER NOT NULL CHECK (checkpoint_advanced IN (0, 1)),
   1217     PRIMARY KEY (attempt_id, request_id),
   1218     UNIQUE (attempt_id, source_ordinal),
   1219     FOREIGN KEY (attempt_id) REFERENCES evidence_reconciliations (attempt_id),
   1220     CHECK ((accepted_event_count = 0) = (accepted_event_bytes = 0)),
   1221     CHECK ((accepted_event_count = 0) = (first_observed_unix_s IS NULL)),
   1222     CHECK ((accepted_event_count = 0) = (candidate_created_at_unix_s IS NULL)),
   1223     CHECK ((candidate_created_at_unix_s IS NULL) = (candidate_event_id IS NULL)),
   1224     CHECK ((prior_cursor_created_at_unix_s IS NULL) = (prior_cursor_event_id IS NULL)),
   1225     CHECK (checkpoint_advanced = 0 OR completion = 'complete'),
   1226     CHECK (checkpoint_advanced = 0 OR candidate_event_id IS NOT NULL)
   1227 ) STRICT"#
   1228     };
   1229 }
   1230 
   1231 const CREATE_EVIDENCE_RECONCILIATIONS_TABLE_SQL: &str = evidence_reconciliations_table_sql!();
   1232 const CREATE_EVIDENCE_RECONCILIATIONS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1233     "evidence_reconciliations_no_update",
   1234     "evidence_reconciliations",
   1235     "reconciliation attempts are immutable"
   1236 );
   1237 const CREATE_EVIDENCE_RECONCILIATIONS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1238     "evidence_reconciliations_no_delete",
   1239     "evidence_reconciliations",
   1240     "reconciliation attempts are retained"
   1241 );
   1242 const CREATE_EVIDENCE_RECONCILIATION_SOURCES_TABLE_SQL: &str =
   1243     evidence_reconciliation_sources_table_sql!();
   1244 const CREATE_EVIDENCE_RECONCILIATION_SOURCES_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1245     "evidence_reconciliation_sources_no_update",
   1246     "evidence_reconciliation_sources",
   1247     "reconciliation source results are immutable"
   1248 );
   1249 const CREATE_EVIDENCE_RECONCILIATION_SOURCES_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1250     "evidence_reconciliation_sources_no_delete",
   1251     "evidence_reconciliation_sources",
   1252     "reconciliation source results are retained"
   1253 );
   1254 const CREATE_RECONCILIATION_RESULTS_MIGRATION_SQL: &str = concat!(
   1255     evidence_reconciliations_table_sql!(),
   1256     ";\n",
   1257     immutable_no_update_sql!(
   1258         "evidence_reconciliations_no_update",
   1259         "evidence_reconciliations",
   1260         "reconciliation attempts are immutable"
   1261     ),
   1262     ";\n",
   1263     immutable_no_delete_sql!(
   1264         "evidence_reconciliations_no_delete",
   1265         "evidence_reconciliations",
   1266         "reconciliation attempts are retained"
   1267     ),
   1268     ";\n",
   1269     evidence_reconciliation_sources_table_sql!(),
   1270     ";\n",
   1271     immutable_no_update_sql!(
   1272         "evidence_reconciliation_sources_no_update",
   1273         "evidence_reconciliation_sources",
   1274         "reconciliation source results are immutable"
   1275     ),
   1276     ";\n",
   1277     immutable_no_delete_sql!(
   1278         "evidence_reconciliation_sources_no_delete",
   1279         "evidence_reconciliation_sources",
   1280         "reconciliation source results are retained"
   1281     ),
   1282     ";",
   1283 );
   1284 
   1285 macro_rules! evidence_manifests_table_sql {
   1286     () => {
   1287         r#"CREATE TABLE evidence_manifests (
   1288     manifest_sha256 BLOB NOT NULL PRIMARY KEY CHECK (length(manifest_sha256) = 32),
   1289     attempt_id BLOB NOT NULL UNIQUE CHECK (length(attempt_id) = 32),
   1290     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
   1291     trade_generation INTEGER NOT NULL
   1292         CHECK (trade_generation BETWEEN 1 AND 9223372036854775807),
   1293     evidence_policy_sha256 BLOB NOT NULL CHECK (length(evidence_policy_sha256) = 32),
   1294     canonical_manifest BLOB NOT NULL
   1295         CHECK (length(canonical_manifest) BETWEEN 1 AND 16777216),
   1296     observed_at_unix_s INTEGER NOT NULL
   1297         CHECK (observed_at_unix_s BETWEEN 0 AND 9223372036854775807),
   1298     source_count INTEGER NOT NULL CHECK (source_count BETWEEN 1 AND 16),
   1299     observation_count INTEGER NOT NULL CHECK (observation_count BETWEEN 0 AND 65536),
   1300     FOREIGN KEY (attempt_id) REFERENCES evidence_reconciliations (attempt_id)
   1301 ) STRICT"#
   1302     };
   1303 }
   1304 
   1305 macro_rules! trade_projections_table_sql {
   1306     () => {
   1307         r#"CREATE TABLE trade_projections (
   1308     projection_sha256 BLOB NOT NULL PRIMARY KEY CHECK (length(projection_sha256) = 32),
   1309     manifest_sha256 BLOB NOT NULL UNIQUE CHECK (length(manifest_sha256) = 32),
   1310     shared_projection_sha256 BLOB NOT NULL CHECK (length(shared_projection_sha256) = 32),
   1311     reducer_contract TEXT NOT NULL CHECK (reducer_contract = 'radroots.trade.reducer.v1'),
   1312     reducer_contract_version INTEGER NOT NULL CHECK (reducer_contract_version = 1),
   1313     issue_count INTEGER NOT NULL CHECK (issue_count BETWEEN 0 AND 65536),
   1314     FOREIGN KEY (manifest_sha256) REFERENCES evidence_manifests (manifest_sha256)
   1315 ) STRICT"#
   1316     };
   1317 }
   1318 
   1319 macro_rules! attestation_reports_table_sql {
   1320     () => {
   1321         r#"CREATE TABLE attestation_reports (
   1322     statement_sha256 BLOB NOT NULL PRIMARY KEY CHECK (length(statement_sha256) = 32),
   1323     manifest_sha256 BLOB NOT NULL CHECK (length(manifest_sha256) = 32),
   1324     projection_sha256 BLOB NOT NULL CHECK (length(projection_sha256) = 32),
   1325     trade_id BLOB NOT NULL CHECK (length(trade_id) = 16),
   1326     claim_mutation_id BLOB NOT NULL CHECK (length(claim_mutation_id) = 32),
   1327     issuer_public_key BLOB NOT NULL CHECK (length(issuer_public_key) = 32),
   1328     outcome TEXT NOT NULL CHECK (outcome IN ('valid', 'invalid', 'indeterminate')),
   1329     canonical_report BLOB NOT NULL CHECK (length(canonical_report) BETWEEN 1 AND 16384),
   1330     observed_at_unix_s INTEGER NOT NULL
   1331         CHECK (observed_at_unix_s BETWEEN 0 AND 9223372036854775807),
   1332     supersedes_statement_sha256 BLOB CHECK (length(supersedes_statement_sha256) = 32),
   1333     supersedes_event_id BLOB CHECK (length(supersedes_event_id) = 32),
   1334     FOREIGN KEY (manifest_sha256) REFERENCES evidence_manifests (manifest_sha256),
   1335     FOREIGN KEY (projection_sha256) REFERENCES trade_projections (projection_sha256),
   1336     FOREIGN KEY (supersedes_statement_sha256)
   1337         REFERENCES attestation_reports (statement_sha256),
   1338     CHECK ((supersedes_statement_sha256 IS NULL) = (supersedes_event_id IS NULL))
   1339 ) STRICT"#
   1340     };
   1341 }
   1342 
   1343 macro_rules! attestation_reports_supersession_sql {
   1344     () => {
   1345         r#"CREATE UNIQUE INDEX attestation_reports_one_successor
   1346 ON attestation_reports (supersedes_statement_sha256)
   1347 WHERE supersedes_statement_sha256 IS NOT NULL"#
   1348     };
   1349 }
   1350 
   1351 macro_rules! signed_attestation_events_table_sql {
   1352     () => {
   1353         r#"CREATE TABLE signed_attestation_events (
   1354     event_id BLOB NOT NULL PRIMARY KEY CHECK (length(event_id) = 32),
   1355     statement_sha256 BLOB NOT NULL UNIQUE CHECK (length(statement_sha256) = 32),
   1356     event_sha256 BLOB NOT NULL UNIQUE CHECK (length(event_sha256) = 32),
   1357     issuer_public_key BLOB NOT NULL CHECK (length(issuer_public_key) = 32),
   1358     authored_at_unix_s INTEGER NOT NULL
   1359         CHECK (authored_at_unix_s BETWEEN 0 AND 9223372036854775807),
   1360     canonical_event_json BLOB NOT NULL
   1361         CHECK (length(canonical_event_json) BETWEEN 1 AND 32768),
   1362     FOREIGN KEY (statement_sha256) REFERENCES attestation_reports (statement_sha256)
   1363 ) STRICT"#
   1364     };
   1365 }
   1366 
   1367 macro_rules! publication_outbox_table_sql {
   1368     () => {
   1369         r#"CREATE TABLE publication_outbox (
   1370     outbox_id BLOB NOT NULL PRIMARY KEY CHECK (length(outbox_id) = 32),
   1371     event_id BLOB NOT NULL UNIQUE CHECK (length(event_id) = 32),
   1372     event_sha256 BLOB NOT NULL CHECK (length(event_sha256) = 32),
   1373     publication_authority_sha256 BLOB NOT NULL
   1374         CHECK (length(publication_authority_sha256) = 32),
   1375     target_set_sha256 BLOB NOT NULL CHECK (length(target_set_sha256) = 32),
   1376     target_count INTEGER NOT NULL CHECK (target_count BETWEEN 1 AND 32),
   1377     required_target_count INTEGER NOT NULL
   1378         CHECK (required_target_count BETWEEN 0 AND target_count),
   1379     max_attempts INTEGER NOT NULL CHECK (max_attempts BETWEEN 1 AND 100),
   1380     initial_backoff_ms INTEGER NOT NULL CHECK (initial_backoff_ms BETWEEN 1 AND 60000),
   1381     maximum_backoff_ms INTEGER NOT NULL CHECK (maximum_backoff_ms BETWEEN 1 AND 3600000),
   1382     attempt_deadline_ms INTEGER NOT NULL CHECK (attempt_deadline_ms BETWEEN 100 AND 30000),
   1383     state TEXT NOT NULL CHECK (state IN ('pending', 'leased', 'complete', 'blocked')),
   1384     revision INTEGER NOT NULL CHECK (revision BETWEEN 1 AND 9223372036854775807),
   1385     next_attempt_unix_ms INTEGER,
   1386     lease_owner BLOB,
   1387     lease_expires_unix_ms INTEGER,
   1388     created_at_unix_ms INTEGER NOT NULL
   1389         CHECK (created_at_unix_ms BETWEEN 0 AND 9223372036854775807),
   1390     updated_at_unix_ms INTEGER NOT NULL
   1391         CHECK (updated_at_unix_ms BETWEEN created_at_unix_ms AND 9223372036854775807),
   1392     FOREIGN KEY (event_id) REFERENCES signed_attestation_events (event_id),
   1393     CHECK (initial_backoff_ms <= maximum_backoff_ms),
   1394     CHECK (
   1395         (state = 'pending'
   1396             AND next_attempt_unix_ms IS NOT NULL
   1397             AND next_attempt_unix_ms BETWEEN 0 AND 9223372036854775807
   1398             AND lease_owner IS NULL AND lease_expires_unix_ms IS NULL)
   1399         OR (state = 'leased'
   1400             AND next_attempt_unix_ms IS NULL
   1401             AND lease_owner IS NOT NULL
   1402             AND length(lease_owner) = 16
   1403             AND lease_expires_unix_ms IS NOT NULL
   1404             AND lease_expires_unix_ms BETWEEN 1 AND 9223372036854775807)
   1405         OR (state IN ('complete', 'blocked')
   1406             AND next_attempt_unix_ms IS NULL
   1407             AND lease_owner IS NULL AND lease_expires_unix_ms IS NULL)
   1408     )
   1409 ) STRICT"#
   1410     };
   1411 }
   1412 
   1413 macro_rules! publication_outbox_schedule_sql {
   1414     () => {
   1415         r#"CREATE INDEX publication_outbox_by_schedule
   1416 ON publication_outbox (
   1417     state, next_attempt_unix_ms, lease_expires_unix_ms,
   1418     created_at_unix_ms, outbox_id
   1419 )"#
   1420     };
   1421 }
   1422 
   1423 macro_rules! publication_outbox_guard_update_sql {
   1424     () => {
   1425         r#"CREATE TRIGGER publication_outbox_guard_update
   1426 BEFORE UPDATE ON publication_outbox
   1427 WHEN NEW.outbox_id != OLD.outbox_id
   1428     OR NEW.event_id != OLD.event_id
   1429     OR NEW.event_sha256 != OLD.event_sha256
   1430     OR NEW.publication_authority_sha256 != OLD.publication_authority_sha256
   1431     OR NEW.target_set_sha256 != OLD.target_set_sha256
   1432     OR NEW.target_count != OLD.target_count
   1433     OR NEW.required_target_count != OLD.required_target_count
   1434     OR NEW.max_attempts != OLD.max_attempts
   1435     OR NEW.initial_backoff_ms != OLD.initial_backoff_ms
   1436     OR NEW.maximum_backoff_ms != OLD.maximum_backoff_ms
   1437     OR NEW.attempt_deadline_ms != OLD.attempt_deadline_ms
   1438     OR NEW.created_at_unix_ms != OLD.created_at_unix_ms
   1439     OR NEW.revision != OLD.revision + 1
   1440     OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms
   1441     OR NOT (
   1442         (OLD.state = 'pending' AND NEW.state IN ('leased', 'blocked'))
   1443         OR (OLD.state = 'leased'
   1444             AND NEW.state IN ('leased', 'pending', 'complete', 'blocked'))
   1445         OR (OLD.state = 'blocked' AND NEW.state = 'pending')
   1446     )
   1447 BEGIN
   1448     SELECT RAISE(ABORT, 'publication outbox transition is invalid');
   1449 END"#
   1450     };
   1451 }
   1452 
   1453 macro_rules! publication_targets_table_sql {
   1454     () => {
   1455         r#"CREATE TABLE publication_targets (
   1456     outbox_id BLOB NOT NULL CHECK (length(outbox_id) = 32),
   1457     target_ordinal INTEGER NOT NULL CHECK (target_ordinal BETWEEN 0 AND 31),
   1458     relay_id TEXT NOT NULL
   1459         CHECK (length(CAST(relay_id AS BLOB)) BETWEEN 1 AND 64)
   1460         CHECK (relay_id NOT GLOB '*[^a-z0-9_-]*')
   1461         CHECK (substr(relay_id, 1, 1) GLOB '[a-z]'),
   1462     required INTEGER NOT NULL CHECK (required IN (0, 1)),
   1463     state TEXT NOT NULL CHECK (state IN (
   1464         'pending', 'submitted', 'accepted', 'rejected', 'rate_limited',
   1465         'auth_required', 'failed', 'unknown'
   1466     )),
   1467     revision INTEGER NOT NULL CHECK (revision BETWEEN 1 AND 9223372036854775807),
   1468     attempt_count INTEGER NOT NULL CHECK (attempt_count BETWEEN 0 AND 100),
   1469     next_attempt_unix_ms INTEGER
   1470         CHECK (next_attempt_unix_ms BETWEEN 0 AND 9223372036854775807),
   1471     last_attempt_id BLOB CHECK (length(last_attempt_id) = 32),
   1472     updated_at_unix_ms INTEGER NOT NULL
   1473         CHECK (updated_at_unix_ms BETWEEN 0 AND 9223372036854775807),
   1474     PRIMARY KEY (outbox_id, target_ordinal),
   1475     UNIQUE (outbox_id, relay_id),
   1476     FOREIGN KEY (outbox_id) REFERENCES publication_outbox (outbox_id),
   1477     CHECK ((attempt_count = 0) = (last_attempt_id IS NULL))
   1478 ) STRICT"#
   1479     };
   1480 }
   1481 
   1482 macro_rules! publication_targets_schedule_sql {
   1483     () => {
   1484         r#"CREATE INDEX publication_targets_by_schedule
   1485 ON publication_targets (state, next_attempt_unix_ms, updated_at_unix_ms, outbox_id, target_ordinal)"#
   1486     };
   1487 }
   1488 
   1489 macro_rules! publication_targets_guard_update_sql {
   1490     () => {
   1491         r#"CREATE TRIGGER publication_targets_guard_update
   1492 BEFORE UPDATE ON publication_targets
   1493 WHEN NEW.outbox_id != OLD.outbox_id
   1494     OR NEW.target_ordinal != OLD.target_ordinal
   1495     OR NEW.relay_id != OLD.relay_id
   1496     OR NEW.required != OLD.required
   1497     OR NEW.revision != OLD.revision + 1
   1498     OR NEW.attempt_count < OLD.attempt_count
   1499     OR NEW.attempt_count > OLD.attempt_count + 1
   1500     OR NEW.updated_at_unix_ms < OLD.updated_at_unix_ms
   1501     OR OLD.state = 'accepted'
   1502 BEGIN
   1503     SELECT RAISE(ABORT, 'publication target transition is invalid');
   1504 END"#
   1505     };
   1506 }
   1507 
   1508 macro_rules! publication_attempts_table_sql {
   1509     () => {
   1510         r#"CREATE TABLE publication_attempts (
   1511     attempt_id BLOB NOT NULL PRIMARY KEY CHECK (length(attempt_id) = 32),
   1512     outbox_id BLOB NOT NULL CHECK (length(outbox_id) = 32),
   1513     target_ordinal INTEGER NOT NULL CHECK (target_ordinal BETWEEN 0 AND 31),
   1514     attempt_number INTEGER NOT NULL CHECK (attempt_number BETWEEN 1 AND 100),
   1515     event_sha256 BLOB NOT NULL CHECK (length(event_sha256) = 32),
   1516     lease_owner BLOB NOT NULL CHECK (length(lease_owner) = 16),
   1517     started_at_unix_ms INTEGER NOT NULL
   1518         CHECK (started_at_unix_ms BETWEEN 0 AND 9223372036854775807),
   1519     finished_at_unix_ms INTEGER NOT NULL
   1520         CHECK (finished_at_unix_ms BETWEEN started_at_unix_ms AND 9223372036854775807),
   1521     outcome TEXT NOT NULL CHECK (outcome IN (
   1522         'submitted', 'accepted', 'rejected', 'rate_limited',
   1523         'auth_required', 'failed', 'unknown'
   1524     )),
   1525     result_code TEXT NOT NULL
   1526         CHECK (length(CAST(result_code AS BLOB)) BETWEEN 1 AND 64)
   1527         CHECK (result_code NOT GLOB '*[^a-z0-9_]*')
   1528         CHECK (substr(result_code, 1, 1) GLOB '[a-z]'),
   1529     UNIQUE (outbox_id, target_ordinal, attempt_number),
   1530     FOREIGN KEY (outbox_id, target_ordinal)
   1531         REFERENCES publication_targets (outbox_id, target_ordinal)
   1532 ) STRICT"#
   1533     };
   1534 }
   1535 
   1536 const CREATE_EVIDENCE_MANIFESTS_TABLE_SQL: &str = evidence_manifests_table_sql!();
   1537 const CREATE_EVIDENCE_MANIFESTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1538     "evidence_manifests_no_update",
   1539     "evidence_manifests",
   1540     "evidence manifests are immutable"
   1541 );
   1542 const CREATE_EVIDENCE_MANIFESTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1543     "evidence_manifests_no_delete",
   1544     "evidence_manifests",
   1545     "evidence manifests are retained"
   1546 );
   1547 const CREATE_TRADE_PROJECTIONS_TABLE_SQL: &str = trade_projections_table_sql!();
   1548 const CREATE_TRADE_PROJECTIONS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1549     "trade_projections_no_update",
   1550     "trade_projections",
   1551     "trade projections are immutable"
   1552 );
   1553 const CREATE_TRADE_PROJECTIONS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1554     "trade_projections_no_delete",
   1555     "trade_projections",
   1556     "trade projections are retained"
   1557 );
   1558 const CREATE_ATTESTATION_REPORTS_TABLE_SQL: &str = attestation_reports_table_sql!();
   1559 const CREATE_ATTESTATION_REPORTS_SUPERSESSION_SQL: &str = attestation_reports_supersession_sql!();
   1560 const CREATE_ATTESTATION_REPORTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1561     "attestation_reports_no_update",
   1562     "attestation_reports",
   1563     "attestation reports are immutable"
   1564 );
   1565 const CREATE_ATTESTATION_REPORTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1566     "attestation_reports_no_delete",
   1567     "attestation_reports",
   1568     "attestation reports are retained"
   1569 );
   1570 const CREATE_SIGNED_ATTESTATION_EVENTS_TABLE_SQL: &str = signed_attestation_events_table_sql!();
   1571 const CREATE_SIGNED_ATTESTATION_EVENTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1572     "signed_attestation_events_no_update",
   1573     "signed_attestation_events",
   1574     "signed attestation events are immutable"
   1575 );
   1576 const CREATE_SIGNED_ATTESTATION_EVENTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1577     "signed_attestation_events_no_delete",
   1578     "signed_attestation_events",
   1579     "signed attestation events are retained"
   1580 );
   1581 const CREATE_PUBLICATION_OUTBOX_TABLE_SQL: &str = publication_outbox_table_sql!();
   1582 const CREATE_PUBLICATION_OUTBOX_SCHEDULE_SQL: &str = publication_outbox_schedule_sql!();
   1583 const CREATE_PUBLICATION_OUTBOX_GUARD_UPDATE_SQL: &str = publication_outbox_guard_update_sql!();
   1584 const CREATE_PUBLICATION_OUTBOX_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1585     "publication_outbox_no_delete",
   1586     "publication_outbox",
   1587     "publication outbox rows are retained"
   1588 );
   1589 const CREATE_PUBLICATION_TARGETS_TABLE_SQL: &str = publication_targets_table_sql!();
   1590 const CREATE_PUBLICATION_TARGETS_SCHEDULE_SQL: &str = publication_targets_schedule_sql!();
   1591 const CREATE_PUBLICATION_TARGETS_GUARD_UPDATE_SQL: &str = publication_targets_guard_update_sql!();
   1592 const CREATE_PUBLICATION_TARGETS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1593     "publication_targets_no_delete",
   1594     "publication_targets",
   1595     "publication targets are retained"
   1596 );
   1597 const CREATE_PUBLICATION_ATTEMPTS_TABLE_SQL: &str = publication_attempts_table_sql!();
   1598 const CREATE_PUBLICATION_ATTEMPTS_NO_UPDATE_SQL: &str = immutable_no_update_sql!(
   1599     "publication_attempts_no_update",
   1600     "publication_attempts",
   1601     "publication attempts are immutable"
   1602 );
   1603 const CREATE_PUBLICATION_ATTEMPTS_NO_DELETE_SQL: &str = immutable_no_delete_sql!(
   1604     "publication_attempts_no_delete",
   1605     "publication_attempts",
   1606     "publication attempts are retained"
   1607 );
   1608 
   1609 const CREATE_REPORT_PUBLICATION_MIGRATION_SQL: &str = concat!(
   1610     evidence_manifests_table_sql!(),
   1611     ";\n",
   1612     immutable_no_update_sql!(
   1613         "evidence_manifests_no_update",
   1614         "evidence_manifests",
   1615         "evidence manifests are immutable"
   1616     ),
   1617     ";\n",
   1618     immutable_no_delete_sql!(
   1619         "evidence_manifests_no_delete",
   1620         "evidence_manifests",
   1621         "evidence manifests are retained"
   1622     ),
   1623     ";\n",
   1624     trade_projections_table_sql!(),
   1625     ";\n",
   1626     immutable_no_update_sql!(
   1627         "trade_projections_no_update",
   1628         "trade_projections",
   1629         "trade projections are immutable"
   1630     ),
   1631     ";\n",
   1632     immutable_no_delete_sql!(
   1633         "trade_projections_no_delete",
   1634         "trade_projections",
   1635         "trade projections are retained"
   1636     ),
   1637     ";\n",
   1638     attestation_reports_table_sql!(),
   1639     ";\n",
   1640     attestation_reports_supersession_sql!(),
   1641     ";\n",
   1642     immutable_no_update_sql!(
   1643         "attestation_reports_no_update",
   1644         "attestation_reports",
   1645         "attestation reports are immutable"
   1646     ),
   1647     ";\n",
   1648     immutable_no_delete_sql!(
   1649         "attestation_reports_no_delete",
   1650         "attestation_reports",
   1651         "attestation reports are retained"
   1652     ),
   1653     ";\n",
   1654     signed_attestation_events_table_sql!(),
   1655     ";\n",
   1656     immutable_no_update_sql!(
   1657         "signed_attestation_events_no_update",
   1658         "signed_attestation_events",
   1659         "signed attestation events are immutable"
   1660     ),
   1661     ";\n",
   1662     immutable_no_delete_sql!(
   1663         "signed_attestation_events_no_delete",
   1664         "signed_attestation_events",
   1665         "signed attestation events are retained"
   1666     ),
   1667     ";\n",
   1668     publication_outbox_table_sql!(),
   1669     ";\n",
   1670     publication_outbox_schedule_sql!(),
   1671     ";\n",
   1672     publication_outbox_guard_update_sql!(),
   1673     ";\n",
   1674     immutable_no_delete_sql!(
   1675         "publication_outbox_no_delete",
   1676         "publication_outbox",
   1677         "publication outbox rows are retained"
   1678     ),
   1679     ";\n",
   1680     publication_targets_table_sql!(),
   1681     ";\n",
   1682     publication_targets_schedule_sql!(),
   1683     ";\n",
   1684     publication_targets_guard_update_sql!(),
   1685     ";\n",
   1686     immutable_no_delete_sql!(
   1687         "publication_targets_no_delete",
   1688         "publication_targets",
   1689         "publication targets are retained"
   1690     ),
   1691     ";\n",
   1692     publication_attempts_table_sql!(),
   1693     ";\n",
   1694     immutable_no_update_sql!(
   1695         "publication_attempts_no_update",
   1696         "publication_attempts",
   1697         "publication attempts are immutable"
   1698     ),
   1699     ";\n",
   1700     immutable_no_delete_sql!(
   1701         "publication_attempts_no_delete",
   1702         "publication_attempts",
   1703         "publication attempts are retained"
   1704     ),
   1705     ";"
   1706 );
   1707 
   1708 const EVIDENCE_RECONCILIATIONS_TABLE_SHA256: [u8; 32] = [
   1709     0xaf, 0xed, 0xa3, 0xfb, 0xfb, 0x32, 0x6b, 0xd5, 0x27, 0x26, 0x42, 0x1d, 0x6c, 0x41, 0x5e, 0xff,
   1710     0xf9, 0x71, 0xf7, 0x47, 0x72, 0x5e, 0xbf, 0x8b, 0x34, 0x26, 0x8f, 0x89, 0x6e, 0xa1, 0x2d, 0x9b,
   1711 ];
   1712 const EVIDENCE_RECONCILIATIONS_NO_UPDATE_SHA256: [u8; 32] = [
   1713     0xf4, 0x8f, 0xe6, 0x07, 0x7f, 0x32, 0x9c, 0x96, 0xc7, 0x8a, 0xad, 0xd4, 0x41, 0x53, 0x1a, 0xa3,
   1714     0x24, 0x2b, 0x5d, 0x12, 0x63, 0x18, 0xdb, 0x39, 0xe7, 0x73, 0xbb, 0x0c, 0xa5, 0x40, 0xcd, 0xe9,
   1715 ];
   1716 const EVIDENCE_RECONCILIATIONS_NO_DELETE_SHA256: [u8; 32] = [
   1717     0x9a, 0x92, 0xf6, 0x89, 0x01, 0x75, 0xff, 0x89, 0x30, 0xee, 0x47, 0x8b, 0x8a, 0x6e, 0x10, 0x4f,
   1718     0xc3, 0x88, 0x4f, 0x83, 0xc5, 0x01, 0x95, 0x9b, 0x72, 0x3e, 0xbd, 0xed, 0x87, 0x2b, 0x13, 0xdf,
   1719 ];
   1720 const EVIDENCE_RECONCILIATION_SOURCES_TABLE_SHA256: [u8; 32] = [
   1721     0xd1, 0x56, 0x84, 0x76, 0xc7, 0x52, 0xf8, 0x22, 0x5c, 0xa0, 0xce, 0x77, 0xa0, 0x1f, 0xc4, 0xc6,
   1722     0x78, 0x22, 0x62, 0x61, 0x02, 0xaa, 0x92, 0x5c, 0xe5, 0x6d, 0x5c, 0x91, 0x4c, 0x8e, 0x1c, 0x5a,
   1723 ];
   1724 const EVIDENCE_RECONCILIATION_SOURCES_NO_UPDATE_SHA256: [u8; 32] = [
   1725     0x85, 0x8a, 0x6d, 0x3b, 0x97, 0x35, 0x91, 0x0b, 0x93, 0xe1, 0x9a, 0x73, 0x97, 0x6e, 0x47, 0x0e,
   1726     0xe6, 0xb6, 0x38, 0x68, 0x31, 0x35, 0xf2, 0x1d, 0x3a, 0x30, 0xe1, 0xa6, 0x3f, 0xae, 0x07, 0x6b,
   1727 ];
   1728 const EVIDENCE_RECONCILIATION_SOURCES_NO_DELETE_SHA256: [u8; 32] = [
   1729     0x55, 0x75, 0xfc, 0xaf, 0xab, 0x07, 0xaf, 0x83, 0x0b, 0x69, 0x8d, 0xfa, 0x86, 0x56, 0xe9, 0xc6,
   1730     0x98, 0x0b, 0x4c, 0xdc, 0xa2, 0xde, 0xce, 0xfc, 0x06, 0x41, 0x86, 0x69, 0x2e, 0xac, 0x00, 0x39,
   1731 ];
   1732 
   1733 const EVIDENCE_MANIFESTS_TABLE_SHA256: [u8; 32] = [
   1734     0x95, 0x41, 0x37, 0x66, 0x31, 0x3e, 0x96, 0x83, 0x81, 0xdf, 0x0d, 0x8b, 0xc5, 0xd5, 0x50, 0x8b,
   1735     0xde, 0x34, 0x3c, 0x68, 0xd6, 0x56, 0xea, 0xea, 0xab, 0x08, 0x87, 0x10, 0x9b, 0x23, 0xc6, 0xfb,
   1736 ];
   1737 const EVIDENCE_MANIFESTS_NO_UPDATE_SHA256: [u8; 32] = [
   1738     0x7f, 0xc1, 0x21, 0xaf, 0x5e, 0x9d, 0xc8, 0x32, 0xae, 0xc9, 0x98, 0x6d, 0x45, 0xc7, 0x68, 0xf3,
   1739     0xc1, 0x76, 0x14, 0xbb, 0xf6, 0xbe, 0x41, 0x11, 0x6a, 0x7e, 0xa9, 0x22, 0x90, 0x27, 0x0e, 0xe5,
   1740 ];
   1741 const EVIDENCE_MANIFESTS_NO_DELETE_SHA256: [u8; 32] = [
   1742     0xd9, 0x9e, 0x5f, 0x55, 0xf7, 0xf2, 0x48, 0x5e, 0xfc, 0xc3, 0xb9, 0x11, 0x88, 0xf5, 0x8d, 0x3b,
   1743     0xa0, 0x0c, 0x3e, 0xf7, 0x82, 0x3d, 0x88, 0xe0, 0x82, 0xc2, 0x60, 0xb8, 0x0f, 0xf4, 0xd6, 0xa4,
   1744 ];
   1745 const TRADE_PROJECTIONS_TABLE_SHA256: [u8; 32] = [
   1746     0xac, 0x04, 0x55, 0xd5, 0x1b, 0xed, 0xfb, 0x9b, 0x59, 0xfd, 0xc9, 0xea, 0x63, 0x1b, 0x85, 0x63,
   1747     0x7a, 0x16, 0xf1, 0xb1, 0xfe, 0xad, 0x4d, 0x4c, 0xdf, 0xba, 0xad, 0xa3, 0xef, 0x85, 0x65, 0x43,
   1748 ];
   1749 const TRADE_PROJECTIONS_NO_UPDATE_SHA256: [u8; 32] = [
   1750     0x8f, 0xba, 0x6b, 0x06, 0x8e, 0xb8, 0x69, 0x84, 0x14, 0x4b, 0x64, 0x14, 0xbf, 0x8c, 0x4e, 0x95,
   1751     0x47, 0x58, 0xaf, 0x09, 0x7d, 0xbb, 0x3a, 0xfe, 0x72, 0x06, 0x21, 0x00, 0x6a, 0x43, 0x32, 0xe0,
   1752 ];
   1753 const TRADE_PROJECTIONS_NO_DELETE_SHA256: [u8; 32] = [
   1754     0x94, 0x8a, 0x5c, 0xed, 0x5a, 0xaa, 0x0a, 0xb4, 0x90, 0x1c, 0xe4, 0x3a, 0xdb, 0x97, 0x69, 0xbf,
   1755     0x5a, 0x19, 0x5d, 0x35, 0x95, 0xc9, 0x39, 0x54, 0x73, 0xe9, 0x6e, 0xea, 0x9c, 0x08, 0x26, 0xb2,
   1756 ];
   1757 const ATTESTATION_REPORTS_TABLE_SHA256: [u8; 32] = [
   1758     0x97, 0xc4, 0x83, 0x37, 0x56, 0x92, 0x23, 0x67, 0xb2, 0xb8, 0xd2, 0x00, 0xeb, 0xc9, 0x31, 0x0d,
   1759     0xc8, 0xb9, 0x73, 0x38, 0xf6, 0xc5, 0x9c, 0xe5, 0xe5, 0x19, 0x87, 0x64, 0x19, 0x9d, 0x44, 0xd2,
   1760 ];
   1761 const ATTESTATION_REPORTS_SUPERSESSION_SHA256: [u8; 32] = [
   1762     0x57, 0xd5, 0x59, 0x2e, 0x2a, 0x7a, 0xd0, 0x03, 0x06, 0x42, 0x28, 0x16, 0x31, 0x8c, 0xe1, 0x25,
   1763     0x30, 0x1c, 0xd3, 0x73, 0xff, 0xc3, 0x47, 0xf5, 0xf8, 0x65, 0xc0, 0x63, 0x73, 0x76, 0xad, 0x8e,
   1764 ];
   1765 const ATTESTATION_REPORTS_NO_UPDATE_SHA256: [u8; 32] = [
   1766     0x5f, 0x27, 0x19, 0x68, 0xe4, 0xd8, 0x32, 0x84, 0xe1, 0x04, 0x09, 0x37, 0x0b, 0xdc, 0x55, 0x9d,
   1767     0xfa, 0x8f, 0xce, 0xa9, 0x0f, 0xd9, 0xd3, 0x47, 0xd4, 0xfa, 0xc8, 0x12, 0x53, 0x77, 0x17, 0x23,
   1768 ];
   1769 const ATTESTATION_REPORTS_NO_DELETE_SHA256: [u8; 32] = [
   1770     0xbe, 0xaf, 0xa1, 0x1a, 0xbe, 0x57, 0x27, 0xac, 0x3e, 0x43, 0x26, 0xd0, 0x8b, 0x0d, 0x39, 0x36,
   1771     0xb3, 0x04, 0x11, 0x37, 0x48, 0x13, 0xd3, 0x2a, 0xc8, 0x24, 0x1f, 0x56, 0xa9, 0x2c, 0x51, 0xfc,
   1772 ];
   1773 const SIGNED_ATTESTATION_EVENTS_TABLE_SHA256: [u8; 32] = [
   1774     0x9b, 0x83, 0x5b, 0x84, 0x97, 0x1f, 0x52, 0xba, 0xc2, 0x8f, 0xf2, 0xba, 0x04, 0x9a, 0x1b, 0x9b,
   1775     0xfc, 0xcc, 0x7c, 0xab, 0x39, 0xd0, 0x16, 0x53, 0x06, 0xa3, 0x9b, 0x93, 0x8c, 0x51, 0x72, 0xab,
   1776 ];
   1777 const SIGNED_ATTESTATION_EVENTS_NO_UPDATE_SHA256: [u8; 32] = [
   1778     0x36, 0x1d, 0xbe, 0xda, 0xae, 0xd4, 0xfc, 0x4c, 0xf3, 0xe8, 0xa8, 0x60, 0xeb, 0x63, 0xc8, 0xc7,
   1779     0x3a, 0x31, 0x79, 0x7c, 0x4f, 0x92, 0x79, 0x8f, 0x7d, 0x3a, 0x9f, 0xec, 0x7f, 0x95, 0xa8, 0x44,
   1780 ];
   1781 const SIGNED_ATTESTATION_EVENTS_NO_DELETE_SHA256: [u8; 32] = [
   1782     0x06, 0x4d, 0x71, 0x90, 0x60, 0x9e, 0x6a, 0x8e, 0xac, 0x6d, 0x80, 0x44, 0xe1, 0xef, 0x53, 0x76,
   1783     0x6a, 0xea, 0x6a, 0xb3, 0x68, 0xc9, 0x48, 0xb1, 0x64, 0x24, 0x9a, 0xf2, 0xc0, 0xc3, 0xeb, 0x9c,
   1784 ];
   1785 const PUBLICATION_OUTBOX_TABLE_SHA256: [u8; 32] = [
   1786     0x26, 0x2a, 0x56, 0x79, 0x77, 0x73, 0xcb, 0x84, 0xb6, 0x55, 0x1c, 0x19, 0x32, 0xe1, 0x0e, 0xb1,
   1787     0x98, 0xf2, 0x4b, 0xf2, 0xb3, 0x5f, 0x90, 0x15, 0xac, 0xc1, 0x8f, 0x27, 0xfd, 0x89, 0x4b, 0x2d,
   1788 ];
   1789 const PUBLICATION_OUTBOX_SCHEDULE_SHA256: [u8; 32] = [
   1790     0xc0, 0x70, 0xb5, 0xb0, 0xd0, 0x1f, 0x05, 0x34, 0xe9, 0x1e, 0xfa, 0xee, 0x6c, 0xba, 0xdd, 0xf8,
   1791     0x5c, 0xf1, 0x85, 0x33, 0xa7, 0x04, 0x5c, 0xfb, 0x65, 0x11, 0xdc, 0x80, 0x28, 0x7b, 0x4f, 0x6e,
   1792 ];
   1793 const PUBLICATION_OUTBOX_GUARD_UPDATE_SHA256: [u8; 32] = [
   1794     0x3e, 0xd0, 0x80, 0x98, 0x34, 0xb2, 0x24, 0x51, 0x5b, 0x7b, 0x06, 0x8e, 0x46, 0x8e, 0xbe, 0x8a,
   1795     0x52, 0x8b, 0xdb, 0xcf, 0xb4, 0x0e, 0x33, 0xe5, 0x19, 0xc6, 0xfd, 0xef, 0x19, 0x80, 0xcd, 0x62,
   1796 ];
   1797 const PUBLICATION_OUTBOX_NO_DELETE_SHA256: [u8; 32] = [
   1798     0xc5, 0x77, 0x63, 0xa0, 0x90, 0xde, 0xe0, 0x11, 0x62, 0x2a, 0xda, 0x9f, 0x32, 0x24, 0x47, 0x59,
   1799     0x54, 0xdf, 0x60, 0xd7, 0xe3, 0xf2, 0xf3, 0x42, 0x36, 0x14, 0x8e, 0xba, 0x52, 0x84, 0x3a, 0x6e,
   1800 ];
   1801 const PUBLICATION_TARGETS_TABLE_SHA256: [u8; 32] = [
   1802     0x23, 0xa0, 0x78, 0x7f, 0x7d, 0x90, 0x91, 0x8b, 0x41, 0x4a, 0x22, 0x37, 0xcc, 0x70, 0xa0, 0x83,
   1803     0x1a, 0xe0, 0xfa, 0x05, 0x2e, 0x1b, 0x9f, 0x25, 0x50, 0xe3, 0x6f, 0xda, 0xd1, 0x53, 0xab, 0x7b,
   1804 ];
   1805 const PUBLICATION_TARGETS_SCHEDULE_SHA256: [u8; 32] = [
   1806     0xf8, 0xc4, 0x46, 0x10, 0xcb, 0x2d, 0xe4, 0xa3, 0x54, 0xd7, 0x93, 0x64, 0x9f, 0x8b, 0xa9, 0xf1,
   1807     0x95, 0xfd, 0xba, 0x5d, 0xfc, 0xc1, 0xf9, 0x92, 0xe9, 0x08, 0x08, 0x7e, 0x56, 0x6a, 0x14, 0xde,
   1808 ];
   1809 const PUBLICATION_TARGETS_GUARD_UPDATE_SHA256: [u8; 32] = [
   1810     0x57, 0x10, 0x3b, 0xa2, 0xc3, 0xd7, 0x88, 0xd3, 0x83, 0x3a, 0xba, 0xed, 0xcd, 0xad, 0x49, 0x5e,
   1811     0xce, 0xfe, 0x6e, 0xbd, 0x63, 0x2a, 0x98, 0x14, 0x04, 0x10, 0x86, 0xb9, 0x84, 0x10, 0x72, 0x0c,
   1812 ];
   1813 const PUBLICATION_TARGETS_NO_DELETE_SHA256: [u8; 32] = [
   1814     0x53, 0x97, 0x8a, 0xa5, 0xca, 0x4d, 0xef, 0x0e, 0xc4, 0x75, 0xc4, 0x55, 0xf6, 0x10, 0x43, 0xf7,
   1815     0x1b, 0x10, 0x15, 0x6b, 0x2b, 0x56, 0xe0, 0x6c, 0x50, 0x4a, 0xc7, 0xee, 0x57, 0x3e, 0x74, 0x4e,
   1816 ];
   1817 const PUBLICATION_ATTEMPTS_TABLE_SHA256: [u8; 32] = [
   1818     0x7d, 0xa6, 0xea, 0xbe, 0xfc, 0x07, 0xeb, 0x16, 0xde, 0x5c, 0x47, 0xc9, 0x20, 0xfd, 0x64, 0x76,
   1819     0xa9, 0xe9, 0x8d, 0xce, 0xe9, 0x31, 0x84, 0x45, 0x8d, 0xd2, 0x98, 0xb8, 0x53, 0x52, 0x03, 0x28,
   1820 ];
   1821 const PUBLICATION_ATTEMPTS_NO_UPDATE_SHA256: [u8; 32] = [
   1822     0xc3, 0xe5, 0x51, 0x35, 0x06, 0xad, 0x45, 0xca, 0xea, 0xe5, 0xaa, 0x7e, 0xa2, 0x40, 0xe7, 0x0a,
   1823     0xde, 0x7c, 0xf7, 0x7f, 0x6d, 0x9a, 0x67, 0x76, 0x92, 0x5e, 0x12, 0x06, 0xc4, 0x55, 0xbf, 0x65,
   1824 ];
   1825 const PUBLICATION_ATTEMPTS_NO_DELETE_SHA256: [u8; 32] = [
   1826     0x6d, 0x8a, 0x4e, 0x03, 0x67, 0x52, 0x51, 0x1a, 0x4e, 0xe7, 0xaa, 0x41, 0x0c, 0x31, 0xaa, 0xc9,
   1827     0xd3, 0x5c, 0x42, 0x48, 0xe3, 0x78, 0xfa, 0x39, 0x7c, 0x9b, 0x90, 0xa0, 0xe3, 0x72, 0x19, 0x29,
   1828 ];
   1829 
   1830 const RECONCILIATION_JOBS_TABLE_SHA256: [u8; 32] = [
   1831     0xe7, 0x0b, 0x5c, 0xb7, 0x26, 0x91, 0x9d, 0x02, 0xef, 0xb3, 0xa6, 0x21, 0x58, 0x48, 0xce, 0x92,
   1832     0x30, 0x88, 0x17, 0x2b, 0x3f, 0xe0, 0xc1, 0x40, 0xee, 0x4a, 0xc7, 0x1b, 0xd0, 0x3c, 0x66, 0xa7,
   1833 ];
   1834 const RECONCILIATION_JOBS_ONE_ACTIVE_SHA256: [u8; 32] = [
   1835     0xf9, 0xbe, 0x78, 0xc6, 0x46, 0x7a, 0x76, 0x2d, 0x38, 0xf4, 0xe0, 0xb4, 0x80, 0xd4, 0x1b, 0x37,
   1836     0x6f, 0x66, 0x8c, 0x21, 0xd2, 0x96, 0xfd, 0x72, 0x12, 0x11, 0x9d, 0x2b, 0x9e, 0x3a, 0x14, 0x3f,
   1837 ];
   1838 const RECONCILIATION_JOBS_SCHEDULE_SHA256: [u8; 32] = [
   1839     0x31, 0xd9, 0xf7, 0x38, 0x3b, 0x87, 0x8d, 0xd8, 0x00, 0xda, 0xe6, 0x1f, 0x40, 0x54, 0xd8, 0xd2,
   1840     0x99, 0xca, 0x93, 0xef, 0x38, 0xbe, 0x5b, 0x63, 0x63, 0x0e, 0x1c, 0x3f, 0x57, 0x2a, 0x1e, 0x75,
   1841 ];
   1842 const RECONCILIATION_JOBS_GUARD_UPDATE_SHA256: [u8; 32] = [
   1843     0xe4, 0x6a, 0x3a, 0xf2, 0x7e, 0xe1, 0xce, 0xe2, 0x4e, 0x29, 0x13, 0x56, 0x51, 0x6c, 0x72, 0x6d,
   1844     0xf0, 0xd1, 0x11, 0x29, 0x01, 0x22, 0x97, 0x5e, 0xe1, 0x79, 0x76, 0xe3, 0x6a, 0x74, 0x13, 0x1b,
   1845 ];
   1846 const RECONCILIATION_JOBS_NO_DELETE_SHA256: [u8; 32] = [
   1847     0x1a, 0x86, 0xb1, 0x70, 0x05, 0x05, 0x4c, 0x27, 0x1b, 0xa4, 0x9a, 0xf2, 0x1a, 0x44, 0x9c, 0x9d,
   1848     0xdc, 0xfb, 0xbc, 0xd9, 0x13, 0xfa, 0x2a, 0x8e, 0x64, 0x6d, 0x5a, 0x6d, 0x22, 0x69, 0x59, 0xa2,
   1849 ];
   1850 const RECONCILIATION_JOBS_SHAPE_GUARD_INSERT_SHA256: [u8; 32] = [
   1851     0x77, 0xf6, 0x83, 0x23, 0x27, 0xce, 0xe0, 0x16, 0xc4, 0x0c, 0x22, 0x6a, 0x61, 0xbe, 0x82, 0xe7,
   1852     0x5b, 0xf0, 0x0b, 0xee, 0x07, 0xb7, 0x03, 0x6f, 0xf7, 0x0d, 0xd2, 0xc9, 0xe0, 0xdb, 0x26, 0xd5,
   1853 ];
   1854 const RECONCILIATION_JOBS_SHAPE_GUARD_UPDATE_SHA256: [u8; 32] = [
   1855     0xf7, 0xbb, 0x8e, 0xb8, 0x1a, 0x6a, 0x1c, 0x19, 0xa9, 0x84, 0x67, 0x51, 0x20, 0x30, 0xe3, 0x9c,
   1856     0xb8, 0x0d, 0x51, 0x6c, 0x1e, 0x33, 0xe7, 0x78, 0x8c, 0xfc, 0x37, 0x9e, 0x4e, 0x9e, 0xf4, 0x61,
   1857 ];
   1858 
   1859 const RHI_CONFIG_BINDINGS_TABLE_SHA256: [u8; 32] = [
   1860     0x4d, 0x6e, 0x8f, 0xff, 0xda, 0x43, 0xe6, 0xf5, 0x3e, 0x23, 0x77, 0xd2, 0x77, 0xa4, 0x52, 0x9e,
   1861     0x63, 0x3e, 0xaf, 0xb6, 0xea, 0xa2, 0xad, 0xd7, 0x56, 0xde, 0x0d, 0xc9, 0x24, 0xc5, 0x77, 0xeb,
   1862 ];
   1863 const RHI_CONFIG_BINDINGS_GUARD_INSERT_SHA256: [u8; 32] = [
   1864     0xe9, 0xc1, 0x7d, 0x5c, 0x2b, 0xbe, 0x59, 0x20, 0x06, 0xe3, 0x7c, 0x5d, 0x93, 0xdc, 0x33, 0x51,
   1865     0x42, 0x63, 0xb2, 0xd6, 0x1b, 0x67, 0x57, 0x81, 0x54, 0x63, 0x85, 0x6b, 0x3f, 0x9d, 0x9d, 0x25,
   1866 ];
   1867 const RHI_CONFIG_BINDINGS_NO_UPDATE_SHA256: [u8; 32] = [
   1868     0xca, 0xb4, 0xbf, 0x42, 0x05, 0x86, 0x03, 0x78, 0x27, 0x1a, 0xad, 0x5b, 0x57, 0x1f, 0x0e, 0x53,
   1869     0x61, 0xe6, 0xb6, 0x62, 0xc1, 0xa9, 0xc1, 0x38, 0x07, 0x5f, 0xab, 0x07, 0xcd, 0xc8, 0x92, 0xe0,
   1870 ];
   1871 const RHI_CONFIG_BINDINGS_NO_DELETE_SHA256: [u8; 32] = [
   1872     0x5d, 0x26, 0x82, 0xe9, 0xf2, 0xdc, 0x84, 0x97, 0x61, 0xd1, 0xd7, 0x10, 0xdc, 0xda, 0x75, 0xea,
   1873     0x40, 0x6d, 0x10, 0x95, 0xae, 0x1b, 0xc0, 0xad, 0xdf, 0x70, 0x64, 0xec, 0x8b, 0xed, 0x0b, 0x90,
   1874 ];
   1875 const TRADE_MUTATIONS_TABLE_SHA256: [u8; 32] = [
   1876     0x86, 0x4f, 0x45, 0xc0, 0x87, 0xe3, 0x87, 0x71, 0x53, 0xb8, 0x6a, 0xa1, 0x88, 0x6c, 0x73, 0x3e,
   1877     0x56, 0x9f, 0x1b, 0x8b, 0xad, 0x8e, 0x9c, 0xbf, 0xab, 0xc4, 0x84, 0x7d, 0x33, 0x33, 0xea, 0xb5,
   1878 ];
   1879 const TRADE_MUTATIONS_BY_TRADE_SHA256: [u8; 32] = [
   1880     0xcf, 0xd1, 0x79, 0x90, 0xf6, 0x0a, 0x18, 0x94, 0x0a, 0xf9, 0xe6, 0xa8, 0x93, 0xda, 0x9e, 0x9a,
   1881     0xc7, 0x5d, 0x2f, 0x69, 0x28, 0xd9, 0xb6, 0x7c, 0x25, 0x06, 0x64, 0x8d, 0x94, 0x9f, 0x97, 0x2e,
   1882 ];
   1883 const NOSTR_EVENTS_TABLE_SHA256: [u8; 32] = [
   1884     0xcd, 0x08, 0xad, 0x41, 0xb4, 0xd7, 0x88, 0xde, 0xc1, 0x23, 0xc9, 0x83, 0x27, 0x17, 0xb8, 0xab,
   1885     0x26, 0x0d, 0x58, 0x5c, 0x71, 0x56, 0x68, 0x6c, 0xaa, 0xf0, 0x5f, 0x07, 0xba, 0xfc, 0x72, 0x12,
   1886 ];
   1887 const NOSTR_EVENTS_BY_MUTATION_SHA256: [u8; 32] = [
   1888     0x57, 0xd2, 0x8a, 0x14, 0xed, 0x74, 0x84, 0xef, 0xa4, 0x1f, 0x78, 0xe8, 0xbf, 0x6e, 0x85, 0x49,
   1889     0xfa, 0x50, 0x76, 0x65, 0xc7, 0x95, 0x32, 0x34, 0xe0, 0xc5, 0xb4, 0xcb, 0x03, 0xb7, 0xa4, 0x18,
   1890 ];
   1891 const RELAY_OBSERVATIONS_TABLE_SHA256: [u8; 32] = [
   1892     0xb0, 0x4d, 0x44, 0x0b, 0xe0, 0x1b, 0x93, 0x2e, 0xea, 0x53, 0x0b, 0x6a, 0x2e, 0xb2, 0x13, 0xe5,
   1893     0x19, 0xab, 0xbf, 0xc2, 0xd2, 0xff, 0xa3, 0xb8, 0x86, 0x98, 0xb1, 0xc7, 0x28, 0x17, 0x86, 0xfc,
   1894 ];
   1895 const RELAY_OBSERVATIONS_BY_EVENT_SHA256: [u8; 32] = [
   1896     0xdd, 0x69, 0x9f, 0x49, 0x98, 0x67, 0x0f, 0x78, 0xb4, 0x62, 0xcb, 0x1c, 0xd5, 0x17, 0x2a, 0xdb,
   1897     0x8d, 0xa1, 0x68, 0x7c, 0x51, 0x74, 0xb3, 0x34, 0x43, 0xf1, 0xc6, 0x6f, 0x41, 0x03, 0xf7, 0x82,
   1898 ];
   1899 const TRADE_MUTATIONS_NO_UPDATE_SHA256: [u8; 32] = [
   1900     0xd7, 0xeb, 0x61, 0x74, 0x43, 0x6a, 0xe3, 0x46, 0xf8, 0x29, 0x31, 0x37, 0x33, 0x93, 0xc0, 0xe9,
   1901     0x0c, 0xe7, 0xf3, 0x06, 0xd6, 0xad, 0xc9, 0xe7, 0xc1, 0xe0, 0x19, 0x3e, 0xa2, 0x46, 0x7d, 0xbe,
   1902 ];
   1903 const TRADE_MUTATIONS_NO_DELETE_SHA256: [u8; 32] = [
   1904     0xde, 0x61, 0x5b, 0xe4, 0x8f, 0xac, 0xc6, 0xd9, 0xae, 0xb1, 0x11, 0xe7, 0xbb, 0xd3, 0xc7, 0x31,
   1905     0x17, 0x6e, 0xc6, 0xe4, 0x82, 0x61, 0x77, 0xba, 0x1c, 0xb7, 0x49, 0x44, 0x02, 0xb1, 0xba, 0xc4,
   1906 ];
   1907 const NOSTR_EVENTS_NO_UPDATE_SHA256: [u8; 32] = [
   1908     0x3e, 0x6e, 0xec, 0x38, 0x89, 0xd7, 0xfd, 0x25, 0xde, 0x26, 0xe2, 0x03, 0x6e, 0xa5, 0xa5, 0x2a,
   1909     0xd5, 0xa0, 0xeb, 0xd6, 0x04, 0x62, 0x61, 0x08, 0xaa, 0x80, 0x72, 0x56, 0xe9, 0xb6, 0x0a, 0x89,
   1910 ];
   1911 const NOSTR_EVENTS_NO_DELETE_SHA256: [u8; 32] = [
   1912     0x17, 0x6b, 0x15, 0x16, 0xce, 0xe2, 0xf1, 0xfc, 0x62, 0xa7, 0x40, 0x90, 0x01, 0x79, 0x51, 0xae,
   1913     0x15, 0x2c, 0xbe, 0x79, 0x53, 0xd0, 0x7c, 0x86, 0xa0, 0xae, 0xca, 0xd3, 0x19, 0x1e, 0xf5, 0xf6,
   1914 ];
   1915 const RELAY_OBSERVATIONS_NO_UPDATE_SHA256: [u8; 32] = [
   1916     0x6d, 0x20, 0xb3, 0xf0, 0xef, 0x1a, 0x26, 0x55, 0xff, 0xd7, 0x46, 0x5c, 0xce, 0xfa, 0x4c, 0x64,
   1917     0x25, 0x26, 0x64, 0xe2, 0x1b, 0xdc, 0xd8, 0x59, 0xdc, 0xb2, 0xde, 0x15, 0xf0, 0x55, 0xf6, 0xaa,
   1918 ];
   1919 const RELAY_OBSERVATIONS_NO_DELETE_SHA256: [u8; 32] = [
   1920     0xe9, 0xaa, 0x66, 0xff, 0x29, 0xa0, 0x62, 0xc9, 0xf9, 0x97, 0x27, 0x0f, 0x59, 0xad, 0x63, 0x65,
   1921     0xdc, 0x4d, 0x88, 0xc6, 0x59, 0x4b, 0xe5, 0xe5, 0xfe, 0x44, 0xf4, 0x44, 0x6d, 0x00, 0xb7, 0xe0,
   1922 ];
   1923 const RELAY_CHECKPOINTS_TABLE_SHA256: [u8; 32] = [
   1924     0x5f, 0xf7, 0xc3, 0x41, 0xa3, 0x48, 0x37, 0x3e, 0x92, 0xf5, 0x46, 0xe1, 0xff, 0xfd, 0x45, 0x4a,
   1925     0x86, 0x6e, 0x23, 0x2c, 0xff, 0x60, 0x83, 0xbf, 0x3f, 0xfe, 0xc3, 0xfc, 0x65, 0x53, 0x2c, 0xb6,
   1926 ];
   1927 const RELAY_CHECKPOINTS_GUARD_UPDATE_SHA256: [u8; 32] = [
   1928     0x5c, 0xd7, 0x2a, 0xaf, 0x31, 0x2c, 0x17, 0xcf, 0xfa, 0xe4, 0xa8, 0x37, 0x91, 0x3c, 0x5e, 0x92,
   1929     0xf2, 0xaa, 0x31, 0xea, 0x71, 0x3e, 0x86, 0x0e, 0x3a, 0xaa, 0x9f, 0xf7, 0x05, 0xd0, 0xc4, 0x92,
   1930 ];
   1931 const RELAY_CHECKPOINTS_NO_DELETE_SHA256: [u8; 32] = [
   1932     0x8d, 0xb0, 0x54, 0xf7, 0x75, 0x97, 0xd5, 0xe5, 0x42, 0xd0, 0x0c, 0x2e, 0xdc, 0xf2, 0xd9, 0x26,
   1933     0xa9, 0x2b, 0x8e, 0xf5, 0x5a, 0x69, 0x54, 0xb2, 0x01, 0x6b, 0x93, 0x36, 0x48, 0x84, 0xfb, 0x1f,
   1934 ];
   1935 const TRADE_DIRTY_GENERATIONS_TABLE_SHA256: [u8; 32] = [
   1936     0xe9, 0x93, 0x53, 0x2c, 0x08, 0x36, 0xa2, 0x99, 0x40, 0xd2, 0xe3, 0x51, 0x5b, 0x11, 0x34, 0xea,
   1937     0x68, 0xf7, 0xd3, 0x50, 0xe5, 0xbe, 0xdb, 0x3b, 0xc1, 0xb1, 0xa5, 0x6f, 0x7f, 0xa6, 0xe4, 0xd1,
   1938 ];
   1939 const TRADE_DIRTY_GENERATIONS_GUARD_UPDATE_SHA256: [u8; 32] = [
   1940     0x50, 0x31, 0xbc, 0x10, 0x4d, 0x51, 0x66, 0xae, 0xf2, 0xdc, 0x9a, 0x1b, 0xaf, 0x42, 0x0e, 0x47,
   1941     0xc1, 0x6b, 0xa9, 0x70, 0x91, 0x6f, 0x5d, 0xc5, 0x6d, 0xb3, 0xc1, 0x70, 0x4e, 0x76, 0x16, 0xcb,
   1942 ];
   1943 const TRADE_DIRTY_GENERATIONS_NO_DELETE_SHA256: [u8; 32] = [
   1944     0x36, 0x66, 0x3a, 0x1a, 0xd4, 0x65, 0x41, 0x9f, 0x23, 0x1e, 0xe6, 0xcd, 0x1e, 0xd1, 0x6d, 0xa4,
   1945     0x26, 0xac, 0x7d, 0x70, 0xde, 0xc3, 0x67, 0x75, 0x55, 0x62, 0xa8, 0x45, 0x52, 0x86, 0x54, 0x23,
   1946 ];
   1947 const PRESENCE_DESIRED_STATE_TABLE_SHA256: [u8; 32] = [
   1948     0x78, 0x4d, 0xfc, 0x23, 0xd5, 0x05, 0xba, 0x09, 0xb3, 0x73, 0x76, 0xf0, 0x18, 0xaa, 0x03, 0xc6,
   1949     0x3d, 0x98, 0x77, 0x1e, 0xba, 0xd6, 0x73, 0x25, 0x4a, 0x38, 0x46, 0xe3, 0x72, 0xc0, 0x80, 0x40,
   1950 ];
   1951 const PRESENCE_DESIRED_STATE_GUARD_INSERT_SHA256: [u8; 32] = [
   1952     0xe5, 0x55, 0xa5, 0x87, 0xa9, 0x73, 0x2f, 0xae, 0x7c, 0x2d, 0x4e, 0xde, 0xb1, 0x88, 0x93, 0x33,
   1953     0x4a, 0xa4, 0x23, 0x12, 0x22, 0x7a, 0x71, 0xca, 0x6c, 0x2b, 0x38, 0x1f, 0x0b, 0x56, 0xad, 0x8b,
   1954 ];
   1955 const PRESENCE_DESIRED_STATE_GUARD_UPDATE_SHA256: [u8; 32] = [
   1956     0xb3, 0x2a, 0xc0, 0x44, 0xd6, 0x8c, 0x40, 0xfa, 0x3e, 0xbc, 0x57, 0x8a, 0x2d, 0x59, 0xcb, 0x1b,
   1957     0xd6, 0x87, 0xd5, 0x3d, 0xa0, 0xc7, 0xec, 0x99, 0xb5, 0x1e, 0x63, 0xc9, 0x72, 0xeb, 0x27, 0x14,
   1958 ];
   1959 const PRESENCE_DESIRED_STATE_NO_DELETE_SHA256: [u8; 32] = [
   1960     0xca, 0xcd, 0xcf, 0x6f, 0x3b, 0x34, 0xc0, 0x7d, 0x6c, 0xf1, 0x1a, 0xab, 0x03, 0xd5, 0x19, 0x7c,
   1961     0xca, 0x44, 0xab, 0x2e, 0x4f, 0x77, 0x65, 0x29, 0x75, 0x02, 0x4b, 0xbf, 0x1f, 0x04, 0xdc, 0x3f,
   1962 ];
   1963 
   1964 const PRESENCE_OUTBOX_TABLE_SHA256: [u8; 32] = [
   1965     0x7e, 0x59, 0xa4, 0xb4, 0x54, 0x09, 0x9e, 0x47, 0xf8, 0xad, 0x0d, 0xb8, 0x7f, 0xd2, 0xa0, 0xc5,
   1966     0xf6, 0x69, 0x8d, 0x70, 0xda, 0x96, 0x8d, 0xb0, 0x57, 0x6a, 0xa8, 0x54, 0x28, 0xd1, 0x40, 0xdd,
   1967 ];
   1968 const PRESENCE_OUTBOX_SCHEDULE_SHA256: [u8; 32] = [
   1969     0xed, 0x0e, 0x52, 0xba, 0xc1, 0xa8, 0xc8, 0xe3, 0x25, 0xf0, 0x28, 0xe4, 0x2c, 0x8d, 0x88, 0x8f,
   1970     0x0e, 0x8b, 0x42, 0x63, 0x7c, 0x95, 0x25, 0xf1, 0x02, 0x0c, 0x18, 0x41, 0x3b, 0xf0, 0xf0, 0x41,
   1971 ];
   1972 const PRESENCE_OUTBOX_GUARD_UPDATE_SHA256: [u8; 32] = [
   1973     0x1d, 0x80, 0x93, 0xa8, 0xe7, 0x70, 0x82, 0xc4, 0x2f, 0xb3, 0xe4, 0x79, 0xc6, 0x22, 0x6f, 0x39,
   1974     0x92, 0x88, 0x80, 0xd4, 0x92, 0xa9, 0x6c, 0x04, 0x29, 0x6b, 0xf2, 0xcc, 0x56, 0x69, 0x6e, 0xce,
   1975 ];
   1976 const PRESENCE_OUTBOX_NO_DELETE_SHA256: [u8; 32] = [
   1977     0xc4, 0xe9, 0xb5, 0x5a, 0x02, 0x0b, 0x67, 0x1d, 0x7d, 0x6c, 0x81, 0xf6, 0x99, 0x90, 0x65, 0x52,
   1978     0xd9, 0x5e, 0x97, 0xfd, 0xba, 0xac, 0xad, 0x7b, 0x01, 0xb5, 0x02, 0x3f, 0x6b, 0x5f, 0x79, 0xeb,
   1979 ];
   1980 const PRESENCE_TARGETS_TABLE_SHA256: [u8; 32] = [
   1981     0x1e, 0xfa, 0xc9, 0xe2, 0x8d, 0x55, 0xcf, 0x90, 0xa5, 0x5d, 0xc4, 0x13, 0x1a, 0x8e, 0xcb, 0xc3,
   1982     0x86, 0x2e, 0xff, 0xa9, 0x3d, 0xb3, 0x63, 0xff, 0xed, 0xd4, 0xa1, 0xd6, 0xcd, 0xa4, 0xb7, 0x8c,
   1983 ];
   1984 const PRESENCE_TARGETS_SCHEDULE_SHA256: [u8; 32] = [
   1985     0x6d, 0xbc, 0xf6, 0x25, 0x20, 0x1e, 0x11, 0x2e, 0x1a, 0x54, 0xa7, 0xc8, 0x87, 0xaf, 0xbb, 0xb8,
   1986     0x21, 0x0a, 0xdc, 0xf6, 0xfa, 0xc1, 0xc5, 0x99, 0xe1, 0xaa, 0x6c, 0xa5, 0xc4, 0x56, 0x74, 0x6a,
   1987 ];
   1988 const PRESENCE_TARGETS_GUARD_UPDATE_SHA256: [u8; 32] = [
   1989     0xa0, 0x8f, 0x28, 0x9e, 0x60, 0x32, 0x27, 0xfa, 0x74, 0x34, 0xea, 0x8d, 0x4a, 0xb5, 0x2a, 0x07,
   1990     0x60, 0xdc, 0xd2, 0x8f, 0xe1, 0x35, 0x33, 0x51, 0xa3, 0x5c, 0x3e, 0x6c, 0x73, 0x5d, 0x12, 0x44,
   1991 ];
   1992 const PRESENCE_TARGETS_NO_DELETE_SHA256: [u8; 32] = [
   1993     0x8f, 0x0a, 0x46, 0x61, 0x55, 0x96, 0xa8, 0x33, 0x6f, 0x5f, 0x56, 0xa0, 0x3e, 0xa9, 0xd3, 0x5c,
   1994     0x7d, 0xc3, 0x69, 0xb3, 0xa3, 0x1d, 0x91, 0x0c, 0x23, 0x05, 0xeb, 0xeb, 0xcb, 0x50, 0x71, 0x25,
   1995 ];
   1996 const PRESENCE_ATTEMPTS_TABLE_SHA256: [u8; 32] = [
   1997     0xed, 0x26, 0x46, 0x45, 0x6f, 0x96, 0x45, 0xde, 0x57, 0xcb, 0xef, 0x79, 0x62, 0xd6, 0xfe, 0x43,
   1998     0x9d, 0xae, 0x10, 0xfd, 0x5e, 0x4c, 0x25, 0x90, 0x91, 0x62, 0x58, 0x8f, 0x58, 0x0d, 0x94, 0x9c,
   1999 ];
   2000 const PRESENCE_ATTEMPTS_NO_UPDATE_SHA256: [u8; 32] = [
   2001     0x8b, 0xe2, 0xd1, 0xa5, 0xe6, 0x5d, 0xb9, 0x96, 0xe3, 0x27, 0xb8, 0xee, 0x27, 0x29, 0xa3, 0xe9,
   2002     0x1d, 0xa0, 0x68, 0x0e, 0x16, 0x05, 0x90, 0x77, 0x3a, 0x78, 0x1e, 0x80, 0x00, 0x35, 0xac, 0x44,
   2003 ];
   2004 const PRESENCE_ATTEMPTS_NO_DELETE_SHA256: [u8; 32] = [
   2005     0x8c, 0x59, 0xe5, 0x11, 0x0e, 0xe5, 0xa7, 0x45, 0x3d, 0xde, 0xca, 0x36, 0xc2, 0x87, 0xc3, 0x6e,
   2006     0xbd, 0xf7, 0x74, 0xbb, 0x8d, 0x84, 0xc9, 0xab, 0xd9, 0x76, 0xe2, 0xae, 0x9c, 0xd2, 0x4a, 0x71,
   2007 ];
   2008 
   2009 macro_rules! rhi_admin_operations_table_sql {
   2010     () => {
   2011         r#"CREATE TABLE rhi_admin_operations (
   2012     operation_id TEXT NOT NULL PRIMARY KEY
   2013         CHECK (length(CAST(operation_id AS BLOB)) BETWEEN 1 AND 128)
   2014         CHECK (substr(operation_id, 1, 1) GLOB '[A-Za-z0-9]')
   2015         CHECK (operation_id NOT GLOB '*[^A-Za-z0-9._:-]*'),
   2016     route TEXT NOT NULL CHECK (length(CAST(route AS BLOB)) BETWEEN 1 AND 128),
   2017     request_sha256 BLOB NOT NULL CHECK (length(request_sha256) = 32),
   2018     state TEXT NOT NULL CHECK (state IN ('prepared', 'completed')),
   2019     response_model BLOB CHECK (response_model IS NULL OR
   2020         length(response_model) BETWEEN 1 AND 8192),
   2021     response_sha256 BLOB CHECK (response_sha256 IS NULL OR
   2022         length(response_sha256) = 32),
   2023     prepared_at_unix_ms INTEGER NOT NULL
   2024         CHECK (prepared_at_unix_ms BETWEEN 0 AND 9223372036854775807),
   2025     completed_at_unix_ms INTEGER
   2026         CHECK (completed_at_unix_ms IS NULL OR
   2027             completed_at_unix_ms BETWEEN prepared_at_unix_ms AND 9223372036854775807),
   2028     expires_at_unix_ms INTEGER
   2029         CHECK (expires_at_unix_ms IS NULL OR
   2030             expires_at_unix_ms BETWEEN completed_at_unix_ms AND 9223372036854775807),
   2031     CHECK ((state = 'prepared' AND response_model IS NULL
   2032             AND response_sha256 IS NULL AND completed_at_unix_ms IS NULL
   2033             AND expires_at_unix_ms IS NULL)
   2034         OR (state = 'completed' AND response_model IS NOT NULL
   2035             AND response_sha256 IS NOT NULL AND completed_at_unix_ms IS NOT NULL
   2036             AND expires_at_unix_ms IS NOT NULL))
   2037 ) STRICT"#
   2038     };
   2039 }
   2040 
   2041 macro_rules! rhi_admin_operations_guard_update_sql {
   2042     () => {
   2043         r#"CREATE TRIGGER rhi_admin_operations_guard_update
   2044 BEFORE UPDATE ON rhi_admin_operations
   2045 WHEN OLD.state != 'prepared' OR NEW.state != 'completed'
   2046     OR NEW.operation_id != OLD.operation_id OR NEW.route != OLD.route
   2047     OR NEW.request_sha256 != OLD.request_sha256
   2048     OR NEW.prepared_at_unix_ms != OLD.prepared_at_unix_ms
   2049     OR NEW.response_model IS NULL OR NEW.response_sha256 IS NULL
   2050     OR NEW.completed_at_unix_ms IS NULL OR NEW.expires_at_unix_ms IS NULL
   2051 BEGIN
   2052     SELECT RAISE(ABORT, 'admin operation transition is invalid');
   2053 END"#
   2054     };
   2055 }
   2056 
   2057 const CREATE_RHI_ADMIN_OPERATIONS_TABLE_SQL: &str = rhi_admin_operations_table_sql!();
   2058 const CREATE_RHI_ADMIN_OPERATIONS_GUARD_UPDATE_SQL: &str = rhi_admin_operations_guard_update_sql!();
   2059 const CREATE_RHI_ADMIN_OPERATIONS_MIGRATION_SQL: &str = concat!(
   2060     rhi_admin_operations_table_sql!(),
   2061     ";\n",
   2062     rhi_admin_operations_guard_update_sql!(),
   2063     ";",
   2064 );
   2065 
   2066 const RHI_ADMIN_OPERATIONS_TABLE_SHA256: [u8; 32] = [
   2067     0xf7, 0xa6, 0x22, 0x21, 0xc8, 0xec, 0x66, 0x2c, 0x17, 0x14, 0x43, 0x82, 0x2b, 0x11, 0xa9, 0x9b,
   2068     0xc4, 0xde, 0x02, 0x13, 0xa1, 0x9e, 0x12, 0xaa, 0x70, 0x54, 0x7b, 0x7f, 0x9d, 0x50, 0x99, 0x21,
   2069 ];
   2070 const RHI_ADMIN_OPERATIONS_GUARD_UPDATE_SHA256: [u8; 32] = [
   2071     0xac, 0xe5, 0x7c, 0x97, 0xbc, 0xd5, 0xe9, 0xda, 0x0d, 0xfc, 0xe0, 0x23, 0x65, 0x6d, 0xae, 0xda,
   2072     0x96, 0xe5, 0xbf, 0xb6, 0x89, 0x70, 0xa6, 0x06, 0x1b, 0x70, 0x7d, 0x21, 0xec, 0x1f, 0x6b, 0x39,
   2073 ];
   2074 
   2075 /// Stable classes for invalid embedded RHI catalog definitions.
   2076 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
   2077 pub enum RhiStateCatalogErrorKind {
   2078     MigrationCatalog,
   2079     SchemaCatalog,
   2080     CatalogMismatch,
   2081 }
   2082 
   2083 impl RhiStateCatalogErrorKind {
   2084     /// Returns the stable machine-readable classification.
   2085     #[must_use]
   2086     pub const fn code(self) -> &'static str {
   2087         match self {
   2088             Self::MigrationCatalog => "migration_catalog_invalid",
   2089             Self::SchemaCatalog => "schema_catalog_invalid",
   2090             Self::CatalogMismatch => "state_catalog_mismatch",
   2091         }
   2092     }
   2093 }
   2094 
   2095 /// Source-free failure to construct or validate the embedded RHI catalogs.
   2096 #[derive(Clone, Copy, PartialEq, Eq)]
   2097 pub struct RhiStateCatalogError {
   2098     kind: RhiStateCatalogErrorKind,
   2099 }
   2100 
   2101 impl RhiStateCatalogError {
   2102     const fn new(kind: RhiStateCatalogErrorKind) -> Self {
   2103         Self { kind }
   2104     }
   2105 
   2106     /// Returns the stable failure class.
   2107     #[must_use]
   2108     pub const fn kind(self) -> RhiStateCatalogErrorKind {
   2109         self.kind
   2110     }
   2111 
   2112     /// Returns the stable machine-readable code.
   2113     #[must_use]
   2114     pub const fn code(self) -> &'static str {
   2115         self.kind.code()
   2116     }
   2117 }
   2118 
   2119 impl fmt::Display for RhiStateCatalogError {
   2120     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
   2121         formatter.write_str(match self.kind {
   2122             RhiStateCatalogErrorKind::MigrationCatalog => {
   2123                 "RHI migration catalog definition is invalid"
   2124             }
   2125             RhiStateCatalogErrorKind::SchemaCatalog => "RHI schema catalog definition is invalid",
   2126             RhiStateCatalogErrorKind::CatalogMismatch => {
   2127                 "RHI state catalogs do not match the governed identity"
   2128             }
   2129         })
   2130     }
   2131 }
   2132 
   2133 impl fmt::Debug for RhiStateCatalogError {
   2134     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
   2135         formatter
   2136             .debug_struct("RhiStateCatalogError")
   2137             .field("kind", &self.kind)
   2138             .finish()
   2139     }
   2140 }
   2141 
   2142 impl Error for RhiStateCatalogError {}
   2143 
   2144 fn build_rhi_migration_catalog() -> Result<MigrationCatalog, RhiStateCatalogError> {
   2145     let configuration = MigrationDescriptor::sql(
   2146         2,
   2147         "create_configuration_binding_history",
   2148         CREATE_RHI_CONFIG_BINDINGS_MIGRATION_SQL,
   2149         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_2_MIGRATION_SHA256),
   2150     )
   2151     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2152     let trade_evidence = MigrationDescriptor::sql(
   2153         3,
   2154         "create_immutable_trade_evidence",
   2155         CREATE_TRADE_EVIDENCE_MIGRATION_SQL,
   2156         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_3_MIGRATION_SHA256),
   2157     )
   2158     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2159     let source_checkpoints = MigrationDescriptor::sql(
   2160         4,
   2161         "create_source_checkpoints_and_dirty_generations",
   2162         CREATE_SOURCE_CHECKPOINT_MIGRATION_SQL,
   2163         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_4_MIGRATION_SHA256),
   2164     )
   2165     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2166     let reconciliation_jobs = MigrationDescriptor::sql(
   2167         5,
   2168         "create_reconciliation_jobs",
   2169         CREATE_RECONCILIATION_JOBS_MIGRATION_SQL,
   2170         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_5_MIGRATION_SHA256),
   2171     )
   2172     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2173     let reconciliation_results = MigrationDescriptor::sql(
   2174         6,
   2175         "create_reconciliation_source_results",
   2176         CREATE_RECONCILIATION_RESULTS_MIGRATION_SQL,
   2177         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_6_MIGRATION_SHA256),
   2178     )
   2179     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2180     let report_publication = MigrationDescriptor::sql(
   2181         7,
   2182         "create_reports_and_publication_outbox",
   2183         CREATE_REPORT_PUBLICATION_MIGRATION_SQL,
   2184         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_7_MIGRATION_SHA256),
   2185     )
   2186     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2187     let reconciliation_job_shape_guards = MigrationDescriptor::sql(
   2188         8,
   2189         "guard_reconciliation_job_state_shape",
   2190         CREATE_RECONCILIATION_JOB_SHAPE_GUARDS_MIGRATION_SQL,
   2191         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_8_MIGRATION_SHA256),
   2192     )
   2193     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2194     let presence_desired_state = MigrationDescriptor::sql(
   2195         9,
   2196         "create_presence_desired_state",
   2197         CREATE_PRESENCE_DESIRED_STATE_MIGRATION_SQL,
   2198         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_9_MIGRATION_SHA256),
   2199     )
   2200     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2201     let presence_publication = MigrationDescriptor::sql(
   2202         10,
   2203         "create_presence_publication_workflow",
   2204         CREATE_PRESENCE_PUBLICATION_MIGRATION_SQL,
   2205         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_10_MIGRATION_SHA256),
   2206     )
   2207     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2208     let admin_operations = MigrationDescriptor::sql(
   2209         11,
   2210         "create_admin_operation_journal",
   2211         CREATE_RHI_ADMIN_OPERATIONS_MIGRATION_SQL,
   2212         MigrationChecksum::from_bytes(RHI_STATE_SCHEMA_VERSION_11_MIGRATION_SHA256),
   2213     )
   2214     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2215     let catalog = MigrationCatalog::new([
   2216         configuration,
   2217         trade_evidence,
   2218         source_checkpoints,
   2219         reconciliation_jobs,
   2220         reconciliation_results,
   2221         report_publication,
   2222         reconciliation_job_shape_guards,
   2223         presence_desired_state,
   2224         presence_publication,
   2225         admin_operations,
   2226     ])
   2227     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::MigrationCatalog))?;
   2228     Ok(catalog)
   2229 }
   2230 
   2231 /// Constructs the exact ordered RHI migration catalog.
   2232 pub fn rhi_migration_catalog() -> Result<MigrationCatalog, RhiStateCatalogError> {
   2233     let catalog = build_rhi_migration_catalog()?;
   2234     if catalog.current_version() != RHI_STATE_SCHEMA_VERSION
   2235         || catalog.descriptors().len() != 10
   2236         || catalog.digest().as_bytes() != &RHI_MIGRATION_CATALOG_SHA256
   2237     {
   2238         return Err(RhiStateCatalogError::new(
   2239             RhiStateCatalogErrorKind::CatalogMismatch,
   2240         ));
   2241     }
   2242     Ok(catalog)
   2243 }
   2244 
   2245 /// Constructs the exact RHI schema catalog bound to the migration catalog.
   2246 pub fn rhi_schema_catalog() -> Result<SchemaCatalog, RhiStateCatalogError> {
   2247     let migrations = rhi_migration_catalog()?;
   2248     let catalog = build_rhi_schema_catalog(&migrations)?;
   2249     validate_rhi_state_catalogs(&migrations, &catalog)?;
   2250     Ok(catalog)
   2251 }
   2252 
   2253 fn build_rhi_schema_catalog(
   2254     migrations: &MigrationCatalog,
   2255 ) -> Result<SchemaCatalog, RhiStateCatalogError> {
   2256     let version_one = SchemaVersionCatalog::new(
   2257         RHI_STATE_BASE_SCHEMA_VERSION,
   2258         [],
   2259         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_1_SHA256),
   2260     )
   2261     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2262     let version_two = SchemaVersionCatalog::new(
   2263         2,
   2264         rhi_config_binding_objects()?,
   2265         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_2_SHA256),
   2266     )
   2267     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2268     let version_three = SchemaVersionCatalog::new(
   2269         3,
   2270         rhi_schema_version_three_objects()?,
   2271         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_3_SHA256),
   2272     )
   2273     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2274     let version_four = SchemaVersionCatalog::new(
   2275         4,
   2276         rhi_schema_version_four_objects()?,
   2277         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_4_SHA256),
   2278     )
   2279     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2280     let version_five = SchemaVersionCatalog::new(
   2281         5,
   2282         rhi_schema_version_five_objects()?,
   2283         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_5_SHA256),
   2284     )
   2285     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2286     let version_six = SchemaVersionCatalog::new(
   2287         6,
   2288         rhi_schema_version_six_objects()?,
   2289         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_6_SHA256),
   2290     )
   2291     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2292     let version_seven = SchemaVersionCatalog::new(
   2293         7,
   2294         rhi_schema_version_seven_objects()?,
   2295         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_7_SHA256),
   2296     )
   2297     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2298     let version_eight = SchemaVersionCatalog::new(
   2299         8,
   2300         rhi_schema_version_eight_objects()?,
   2301         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_8_SHA256),
   2302     )
   2303     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2304     let version_nine = SchemaVersionCatalog::new(
   2305         9,
   2306         rhi_schema_version_nine_objects()?,
   2307         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_9_SHA256),
   2308     )
   2309     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2310     let version_ten = SchemaVersionCatalog::new(
   2311         10,
   2312         rhi_schema_version_ten_objects()?,
   2313         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_10_SHA256),
   2314     )
   2315     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2316     let version_eleven = SchemaVersionCatalog::new(
   2317         11,
   2318         rhi_schema_version_eleven_objects()?,
   2319         SchemaDigest::from_bytes(RHI_STATE_SCHEMA_VERSION_11_SHA256),
   2320     )
   2321     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2322     let catalog = SchemaCatalog::new(
   2323         migrations,
   2324         [
   2325             version_one,
   2326             version_two,
   2327             version_three,
   2328             version_four,
   2329             version_five,
   2330             version_six,
   2331             version_seven,
   2332             version_eight,
   2333             version_nine,
   2334             version_ten,
   2335             version_eleven,
   2336         ],
   2337     )
   2338     .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?;
   2339     Ok(catalog)
   2340 }
   2341 
   2342 /// Independently validates exact catalog versions, counts, and digests.
   2343 pub fn validate_rhi_state_catalogs(
   2344     migrations: &MigrationCatalog,
   2345     schema: &SchemaCatalog,
   2346 ) -> Result<(), RhiStateCatalogError> {
   2347     let versions = schema.versions();
   2348     let valid = migrations.current_version() == RHI_STATE_SCHEMA_VERSION
   2349         && migrations.descriptors().len() == 10
   2350         && migrations.digest().as_bytes() == &RHI_MIGRATION_CATALOG_SHA256
   2351         && schema.migration_catalog_digest() == migrations.digest()
   2352         && versions.len() == 11
   2353         && versions[0].version() == RHI_STATE_BASE_SCHEMA_VERSION
   2354         && versions[0].object_count() == RHI_STATE_SCHEMA_VERSION_1_OBJECT_COUNT
   2355         && versions[0].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_1_SHA256
   2356         && versions[1].version() == 2
   2357         && versions[1].object_count() == RHI_STATE_SCHEMA_VERSION_2_OBJECT_COUNT
   2358         && versions[1].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_2_SHA256
   2359         && versions[2].version() == 3
   2360         && versions[2].object_count() == RHI_STATE_SCHEMA_VERSION_3_OBJECT_COUNT
   2361         && versions[2].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_3_SHA256
   2362         && versions[3].version() == 4
   2363         && versions[3].object_count() == RHI_STATE_SCHEMA_VERSION_4_OBJECT_COUNT
   2364         && versions[3].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_4_SHA256
   2365         && versions[4].version() == 5
   2366         && versions[4].object_count() == RHI_STATE_SCHEMA_VERSION_5_OBJECT_COUNT
   2367         && versions[4].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_5_SHA256
   2368         && versions[5].version() == 6
   2369         && versions[5].object_count() == RHI_STATE_SCHEMA_VERSION_6_OBJECT_COUNT
   2370         && versions[5].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_6_SHA256
   2371         && versions[6].version() == 7
   2372         && versions[6].object_count() == RHI_STATE_SCHEMA_VERSION_7_OBJECT_COUNT
   2373         && versions[6].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_7_SHA256
   2374         && versions[7].version() == 8
   2375         && versions[7].object_count() == RHI_STATE_SCHEMA_VERSION_8_OBJECT_COUNT
   2376         && versions[7].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_8_SHA256
   2377         && versions[8].version() == 9
   2378         && versions[8].object_count() == RHI_STATE_SCHEMA_VERSION_9_OBJECT_COUNT
   2379         && versions[8].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_9_SHA256
   2380         && versions[9].version() == 10
   2381         && versions[9].object_count() == RHI_STATE_SCHEMA_VERSION_10_OBJECT_COUNT
   2382         && versions[9].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_10_SHA256
   2383         && versions[10].version() == RHI_STATE_SCHEMA_VERSION
   2384         && versions[10].object_count() == RHI_STATE_SCHEMA_VERSION_11_OBJECT_COUNT
   2385         && versions[10].digest().as_bytes() == &RHI_STATE_SCHEMA_VERSION_11_SHA256
   2386         && schema.digest().as_bytes() == &RHI_STATE_SCHEMA_CATALOG_SHA256;
   2387     if valid {
   2388         Ok(())
   2389     } else {
   2390         Err(RhiStateCatalogError::new(
   2391             RhiStateCatalogErrorKind::CatalogMismatch,
   2392         ))
   2393     }
   2394 }
   2395 
   2396 fn rhi_config_binding_objects() -> Result<[SchemaObject; 4], RhiStateCatalogError> {
   2397     Ok([
   2398         SchemaObject::new(
   2399             SchemaObjectKind::Table,
   2400             "rhi_config_bindings",
   2401             "rhi_config_bindings",
   2402             CREATE_RHI_CONFIG_BINDINGS_TABLE_SQL,
   2403             SchemaDigest::from_bytes(RHI_CONFIG_BINDINGS_TABLE_SHA256),
   2404         )
   2405         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?,
   2406         SchemaObject::new(
   2407             SchemaObjectKind::Trigger,
   2408             "rhi_config_bindings_guard_insert",
   2409             "rhi_config_bindings",
   2410             CREATE_RHI_CONFIG_BINDINGS_GUARD_INSERT_SQL,
   2411             SchemaDigest::from_bytes(RHI_CONFIG_BINDINGS_GUARD_INSERT_SHA256),
   2412         )
   2413         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?,
   2414         SchemaObject::new(
   2415             SchemaObjectKind::Trigger,
   2416             "rhi_config_bindings_no_update",
   2417             "rhi_config_bindings",
   2418             CREATE_RHI_CONFIG_BINDINGS_NO_UPDATE_SQL,
   2419             SchemaDigest::from_bytes(RHI_CONFIG_BINDINGS_NO_UPDATE_SHA256),
   2420         )
   2421         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?,
   2422         SchemaObject::new(
   2423             SchemaObjectKind::Trigger,
   2424             "rhi_config_bindings_no_delete",
   2425             "rhi_config_bindings",
   2426             CREATE_RHI_CONFIG_BINDINGS_NO_DELETE_SQL,
   2427             SchemaDigest::from_bytes(RHI_CONFIG_BINDINGS_NO_DELETE_SHA256),
   2428         )
   2429         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))?,
   2430     ])
   2431 }
   2432 
   2433 fn rhi_schema_version_three_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2434     let mut objects = rhi_config_binding_objects()?.to_vec();
   2435     objects.extend(rhi_trade_evidence_objects()?);
   2436     Ok(objects)
   2437 }
   2438 
   2439 fn rhi_schema_version_four_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2440     let mut objects = rhi_schema_version_three_objects()?;
   2441     objects.extend(rhi_source_checkpoint_objects()?);
   2442     Ok(objects)
   2443 }
   2444 
   2445 fn rhi_schema_version_five_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2446     let mut objects = rhi_schema_version_four_objects()?;
   2447     objects.extend(rhi_reconciliation_job_objects()?);
   2448     Ok(objects)
   2449 }
   2450 
   2451 fn rhi_schema_version_six_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2452     let mut objects = rhi_schema_version_five_objects()?;
   2453     objects.extend(rhi_reconciliation_result_objects()?);
   2454     Ok(objects)
   2455 }
   2456 
   2457 fn rhi_schema_version_seven_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2458     let mut objects = rhi_schema_version_six_objects()?;
   2459     objects.extend(rhi_report_publication_objects()?);
   2460     Ok(objects)
   2461 }
   2462 
   2463 fn rhi_schema_version_eight_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2464     let mut objects = rhi_schema_version_seven_objects()?;
   2465     objects.extend(rhi_reconciliation_job_shape_guard_objects()?);
   2466     Ok(objects)
   2467 }
   2468 
   2469 fn rhi_schema_version_nine_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2470     let mut objects = rhi_schema_version_eight_objects()?;
   2471     objects.extend(rhi_presence_desired_state_objects()?);
   2472     Ok(objects)
   2473 }
   2474 
   2475 fn rhi_schema_version_ten_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2476     let mut objects = rhi_schema_version_nine_objects()?;
   2477     objects.extend(rhi_presence_publication_objects()?);
   2478     Ok(objects)
   2479 }
   2480 
   2481 fn rhi_schema_version_eleven_objects() -> Result<Vec<SchemaObject>, RhiStateCatalogError> {
   2482     let mut objects = rhi_schema_version_ten_objects()?;
   2483     objects.extend(rhi_admin_operation_objects()?);
   2484     Ok(objects)
   2485 }
   2486 
   2487 fn rhi_admin_operation_objects() -> Result<[SchemaObject; 2], RhiStateCatalogError> {
   2488     let object = |kind, name, sql, digest| {
   2489         SchemaObject::new(
   2490             kind,
   2491             name,
   2492             "rhi_admin_operations",
   2493             sql,
   2494             SchemaDigest::from_bytes(digest),
   2495         )
   2496         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2497     };
   2498     Ok([
   2499         object(
   2500             SchemaObjectKind::Table,
   2501             "rhi_admin_operations",
   2502             CREATE_RHI_ADMIN_OPERATIONS_TABLE_SQL,
   2503             RHI_ADMIN_OPERATIONS_TABLE_SHA256,
   2504         )?,
   2505         object(
   2506             SchemaObjectKind::Trigger,
   2507             "rhi_admin_operations_guard_update",
   2508             CREATE_RHI_ADMIN_OPERATIONS_GUARD_UPDATE_SQL,
   2509             RHI_ADMIN_OPERATIONS_GUARD_UPDATE_SHA256,
   2510         )?,
   2511     ])
   2512 }
   2513 
   2514 fn rhi_presence_publication_objects() -> Result<[SchemaObject; 11], RhiStateCatalogError> {
   2515     let object = |kind, name, table_name, sql, digest| {
   2516         SchemaObject::new(
   2517             kind,
   2518             name,
   2519             table_name,
   2520             sql,
   2521             SchemaDigest::from_bytes(digest),
   2522         )
   2523         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2524     };
   2525     Ok([
   2526         object(
   2527             SchemaObjectKind::Table,
   2528             "presence_outbox",
   2529             "presence_outbox",
   2530             CREATE_PRESENCE_OUTBOX_TABLE_SQL,
   2531             PRESENCE_OUTBOX_TABLE_SHA256,
   2532         )?,
   2533         object(
   2534             SchemaObjectKind::Index,
   2535             "presence_outbox_by_schedule",
   2536             "presence_outbox",
   2537             CREATE_PRESENCE_OUTBOX_SCHEDULE_SQL,
   2538             PRESENCE_OUTBOX_SCHEDULE_SHA256,
   2539         )?,
   2540         object(
   2541             SchemaObjectKind::Trigger,
   2542             "presence_outbox_guard_update",
   2543             "presence_outbox",
   2544             CREATE_PRESENCE_OUTBOX_GUARD_UPDATE_SQL,
   2545             PRESENCE_OUTBOX_GUARD_UPDATE_SHA256,
   2546         )?,
   2547         object(
   2548             SchemaObjectKind::Trigger,
   2549             "presence_outbox_no_delete",
   2550             "presence_outbox",
   2551             CREATE_PRESENCE_OUTBOX_NO_DELETE_SQL,
   2552             PRESENCE_OUTBOX_NO_DELETE_SHA256,
   2553         )?,
   2554         object(
   2555             SchemaObjectKind::Table,
   2556             "presence_targets",
   2557             "presence_targets",
   2558             CREATE_PRESENCE_TARGETS_TABLE_SQL,
   2559             PRESENCE_TARGETS_TABLE_SHA256,
   2560         )?,
   2561         object(
   2562             SchemaObjectKind::Index,
   2563             "presence_targets_by_schedule",
   2564             "presence_targets",
   2565             CREATE_PRESENCE_TARGETS_SCHEDULE_SQL,
   2566             PRESENCE_TARGETS_SCHEDULE_SHA256,
   2567         )?,
   2568         object(
   2569             SchemaObjectKind::Trigger,
   2570             "presence_targets_guard_update",
   2571             "presence_targets",
   2572             CREATE_PRESENCE_TARGETS_GUARD_UPDATE_SQL,
   2573             PRESENCE_TARGETS_GUARD_UPDATE_SHA256,
   2574         )?,
   2575         object(
   2576             SchemaObjectKind::Trigger,
   2577             "presence_targets_no_delete",
   2578             "presence_targets",
   2579             CREATE_PRESENCE_TARGETS_NO_DELETE_SQL,
   2580             PRESENCE_TARGETS_NO_DELETE_SHA256,
   2581         )?,
   2582         object(
   2583             SchemaObjectKind::Table,
   2584             "presence_attempts",
   2585             "presence_attempts",
   2586             CREATE_PRESENCE_ATTEMPTS_TABLE_SQL,
   2587             PRESENCE_ATTEMPTS_TABLE_SHA256,
   2588         )?,
   2589         object(
   2590             SchemaObjectKind::Trigger,
   2591             "presence_attempts_no_update",
   2592             "presence_attempts",
   2593             CREATE_PRESENCE_ATTEMPTS_NO_UPDATE_SQL,
   2594             PRESENCE_ATTEMPTS_NO_UPDATE_SHA256,
   2595         )?,
   2596         object(
   2597             SchemaObjectKind::Trigger,
   2598             "presence_attempts_no_delete",
   2599             "presence_attempts",
   2600             CREATE_PRESENCE_ATTEMPTS_NO_DELETE_SQL,
   2601             PRESENCE_ATTEMPTS_NO_DELETE_SHA256,
   2602         )?,
   2603     ])
   2604 }
   2605 
   2606 fn rhi_presence_desired_state_objects() -> Result<[SchemaObject; 4], RhiStateCatalogError> {
   2607     let object = |kind, name, sql, digest| {
   2608         SchemaObject::new(
   2609             kind,
   2610             name,
   2611             "presence_desired_state",
   2612             sql,
   2613             SchemaDigest::from_bytes(digest),
   2614         )
   2615         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2616     };
   2617     Ok([
   2618         object(
   2619             SchemaObjectKind::Table,
   2620             "presence_desired_state",
   2621             CREATE_PRESENCE_DESIRED_STATE_TABLE_SQL,
   2622             PRESENCE_DESIRED_STATE_TABLE_SHA256,
   2623         )?,
   2624         object(
   2625             SchemaObjectKind::Trigger,
   2626             "presence_desired_state_guard_insert",
   2627             CREATE_PRESENCE_DESIRED_STATE_GUARD_INSERT_SQL,
   2628             PRESENCE_DESIRED_STATE_GUARD_INSERT_SHA256,
   2629         )?,
   2630         object(
   2631             SchemaObjectKind::Trigger,
   2632             "presence_desired_state_guard_update",
   2633             CREATE_PRESENCE_DESIRED_STATE_GUARD_UPDATE_SQL,
   2634             PRESENCE_DESIRED_STATE_GUARD_UPDATE_SHA256,
   2635         )?,
   2636         object(
   2637             SchemaObjectKind::Trigger,
   2638             "presence_desired_state_no_delete",
   2639             CREATE_PRESENCE_DESIRED_STATE_NO_DELETE_SQL,
   2640             PRESENCE_DESIRED_STATE_NO_DELETE_SHA256,
   2641         )?,
   2642     ])
   2643 }
   2644 
   2645 fn rhi_reconciliation_job_shape_guard_objects() -> Result<[SchemaObject; 2], RhiStateCatalogError> {
   2646     let object = |name, sql, digest| {
   2647         SchemaObject::new(
   2648             SchemaObjectKind::Trigger,
   2649             name,
   2650             "reconciliation_jobs",
   2651             sql,
   2652             SchemaDigest::from_bytes(digest),
   2653         )
   2654         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2655     };
   2656     Ok([
   2657         object(
   2658             "reconciliation_jobs_shape_guard_insert",
   2659             CREATE_RECONCILIATION_JOBS_SHAPE_GUARD_INSERT_SQL,
   2660             RECONCILIATION_JOBS_SHAPE_GUARD_INSERT_SHA256,
   2661         )?,
   2662         object(
   2663             "reconciliation_jobs_shape_guard_update",
   2664             CREATE_RECONCILIATION_JOBS_SHAPE_GUARD_UPDATE_SQL,
   2665             RECONCILIATION_JOBS_SHAPE_GUARD_UPDATE_SHA256,
   2666         )?,
   2667     ])
   2668 }
   2669 
   2670 fn rhi_report_publication_objects() -> Result<[SchemaObject; 24], RhiStateCatalogError> {
   2671     let object = |kind, name, table_name, sql, digest| {
   2672         SchemaObject::new(
   2673             kind,
   2674             name,
   2675             table_name,
   2676             sql,
   2677             SchemaDigest::from_bytes(digest),
   2678         )
   2679         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2680     };
   2681     Ok([
   2682         object(
   2683             SchemaObjectKind::Table,
   2684             "evidence_manifests",
   2685             "evidence_manifests",
   2686             CREATE_EVIDENCE_MANIFESTS_TABLE_SQL,
   2687             EVIDENCE_MANIFESTS_TABLE_SHA256,
   2688         )?,
   2689         object(
   2690             SchemaObjectKind::Trigger,
   2691             "evidence_manifests_no_update",
   2692             "evidence_manifests",
   2693             CREATE_EVIDENCE_MANIFESTS_NO_UPDATE_SQL,
   2694             EVIDENCE_MANIFESTS_NO_UPDATE_SHA256,
   2695         )?,
   2696         object(
   2697             SchemaObjectKind::Trigger,
   2698             "evidence_manifests_no_delete",
   2699             "evidence_manifests",
   2700             CREATE_EVIDENCE_MANIFESTS_NO_DELETE_SQL,
   2701             EVIDENCE_MANIFESTS_NO_DELETE_SHA256,
   2702         )?,
   2703         object(
   2704             SchemaObjectKind::Table,
   2705             "trade_projections",
   2706             "trade_projections",
   2707             CREATE_TRADE_PROJECTIONS_TABLE_SQL,
   2708             TRADE_PROJECTIONS_TABLE_SHA256,
   2709         )?,
   2710         object(
   2711             SchemaObjectKind::Trigger,
   2712             "trade_projections_no_update",
   2713             "trade_projections",
   2714             CREATE_TRADE_PROJECTIONS_NO_UPDATE_SQL,
   2715             TRADE_PROJECTIONS_NO_UPDATE_SHA256,
   2716         )?,
   2717         object(
   2718             SchemaObjectKind::Trigger,
   2719             "trade_projections_no_delete",
   2720             "trade_projections",
   2721             CREATE_TRADE_PROJECTIONS_NO_DELETE_SQL,
   2722             TRADE_PROJECTIONS_NO_DELETE_SHA256,
   2723         )?,
   2724         object(
   2725             SchemaObjectKind::Table,
   2726             "attestation_reports",
   2727             "attestation_reports",
   2728             CREATE_ATTESTATION_REPORTS_TABLE_SQL,
   2729             ATTESTATION_REPORTS_TABLE_SHA256,
   2730         )?,
   2731         object(
   2732             SchemaObjectKind::Index,
   2733             "attestation_reports_one_successor",
   2734             "attestation_reports",
   2735             CREATE_ATTESTATION_REPORTS_SUPERSESSION_SQL,
   2736             ATTESTATION_REPORTS_SUPERSESSION_SHA256,
   2737         )?,
   2738         object(
   2739             SchemaObjectKind::Trigger,
   2740             "attestation_reports_no_update",
   2741             "attestation_reports",
   2742             CREATE_ATTESTATION_REPORTS_NO_UPDATE_SQL,
   2743             ATTESTATION_REPORTS_NO_UPDATE_SHA256,
   2744         )?,
   2745         object(
   2746             SchemaObjectKind::Trigger,
   2747             "attestation_reports_no_delete",
   2748             "attestation_reports",
   2749             CREATE_ATTESTATION_REPORTS_NO_DELETE_SQL,
   2750             ATTESTATION_REPORTS_NO_DELETE_SHA256,
   2751         )?,
   2752         object(
   2753             SchemaObjectKind::Table,
   2754             "signed_attestation_events",
   2755             "signed_attestation_events",
   2756             CREATE_SIGNED_ATTESTATION_EVENTS_TABLE_SQL,
   2757             SIGNED_ATTESTATION_EVENTS_TABLE_SHA256,
   2758         )?,
   2759         object(
   2760             SchemaObjectKind::Trigger,
   2761             "signed_attestation_events_no_update",
   2762             "signed_attestation_events",
   2763             CREATE_SIGNED_ATTESTATION_EVENTS_NO_UPDATE_SQL,
   2764             SIGNED_ATTESTATION_EVENTS_NO_UPDATE_SHA256,
   2765         )?,
   2766         object(
   2767             SchemaObjectKind::Trigger,
   2768             "signed_attestation_events_no_delete",
   2769             "signed_attestation_events",
   2770             CREATE_SIGNED_ATTESTATION_EVENTS_NO_DELETE_SQL,
   2771             SIGNED_ATTESTATION_EVENTS_NO_DELETE_SHA256,
   2772         )?,
   2773         object(
   2774             SchemaObjectKind::Table,
   2775             "publication_outbox",
   2776             "publication_outbox",
   2777             CREATE_PUBLICATION_OUTBOX_TABLE_SQL,
   2778             PUBLICATION_OUTBOX_TABLE_SHA256,
   2779         )?,
   2780         object(
   2781             SchemaObjectKind::Index,
   2782             "publication_outbox_by_schedule",
   2783             "publication_outbox",
   2784             CREATE_PUBLICATION_OUTBOX_SCHEDULE_SQL,
   2785             PUBLICATION_OUTBOX_SCHEDULE_SHA256,
   2786         )?,
   2787         object(
   2788             SchemaObjectKind::Trigger,
   2789             "publication_outbox_guard_update",
   2790             "publication_outbox",
   2791             CREATE_PUBLICATION_OUTBOX_GUARD_UPDATE_SQL,
   2792             PUBLICATION_OUTBOX_GUARD_UPDATE_SHA256,
   2793         )?,
   2794         object(
   2795             SchemaObjectKind::Trigger,
   2796             "publication_outbox_no_delete",
   2797             "publication_outbox",
   2798             CREATE_PUBLICATION_OUTBOX_NO_DELETE_SQL,
   2799             PUBLICATION_OUTBOX_NO_DELETE_SHA256,
   2800         )?,
   2801         object(
   2802             SchemaObjectKind::Table,
   2803             "publication_targets",
   2804             "publication_targets",
   2805             CREATE_PUBLICATION_TARGETS_TABLE_SQL,
   2806             PUBLICATION_TARGETS_TABLE_SHA256,
   2807         )?,
   2808         object(
   2809             SchemaObjectKind::Index,
   2810             "publication_targets_by_schedule",
   2811             "publication_targets",
   2812             CREATE_PUBLICATION_TARGETS_SCHEDULE_SQL,
   2813             PUBLICATION_TARGETS_SCHEDULE_SHA256,
   2814         )?,
   2815         object(
   2816             SchemaObjectKind::Trigger,
   2817             "publication_targets_guard_update",
   2818             "publication_targets",
   2819             CREATE_PUBLICATION_TARGETS_GUARD_UPDATE_SQL,
   2820             PUBLICATION_TARGETS_GUARD_UPDATE_SHA256,
   2821         )?,
   2822         object(
   2823             SchemaObjectKind::Trigger,
   2824             "publication_targets_no_delete",
   2825             "publication_targets",
   2826             CREATE_PUBLICATION_TARGETS_NO_DELETE_SQL,
   2827             PUBLICATION_TARGETS_NO_DELETE_SHA256,
   2828         )?,
   2829         object(
   2830             SchemaObjectKind::Table,
   2831             "publication_attempts",
   2832             "publication_attempts",
   2833             CREATE_PUBLICATION_ATTEMPTS_TABLE_SQL,
   2834             PUBLICATION_ATTEMPTS_TABLE_SHA256,
   2835         )?,
   2836         object(
   2837             SchemaObjectKind::Trigger,
   2838             "publication_attempts_no_update",
   2839             "publication_attempts",
   2840             CREATE_PUBLICATION_ATTEMPTS_NO_UPDATE_SQL,
   2841             PUBLICATION_ATTEMPTS_NO_UPDATE_SHA256,
   2842         )?,
   2843         object(
   2844             SchemaObjectKind::Trigger,
   2845             "publication_attempts_no_delete",
   2846             "publication_attempts",
   2847             CREATE_PUBLICATION_ATTEMPTS_NO_DELETE_SQL,
   2848             PUBLICATION_ATTEMPTS_NO_DELETE_SHA256,
   2849         )?,
   2850     ])
   2851 }
   2852 
   2853 fn rhi_reconciliation_result_objects() -> Result<[SchemaObject; 6], RhiStateCatalogError> {
   2854     let object = |kind, name, table_name, sql, digest| {
   2855         SchemaObject::new(
   2856             kind,
   2857             name,
   2858             table_name,
   2859             sql,
   2860             SchemaDigest::from_bytes(digest),
   2861         )
   2862         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2863     };
   2864     Ok([
   2865         object(
   2866             SchemaObjectKind::Table,
   2867             "evidence_reconciliations",
   2868             "evidence_reconciliations",
   2869             CREATE_EVIDENCE_RECONCILIATIONS_TABLE_SQL,
   2870             EVIDENCE_RECONCILIATIONS_TABLE_SHA256,
   2871         )?,
   2872         object(
   2873             SchemaObjectKind::Trigger,
   2874             "evidence_reconciliations_no_update",
   2875             "evidence_reconciliations",
   2876             CREATE_EVIDENCE_RECONCILIATIONS_NO_UPDATE_SQL,
   2877             EVIDENCE_RECONCILIATIONS_NO_UPDATE_SHA256,
   2878         )?,
   2879         object(
   2880             SchemaObjectKind::Trigger,
   2881             "evidence_reconciliations_no_delete",
   2882             "evidence_reconciliations",
   2883             CREATE_EVIDENCE_RECONCILIATIONS_NO_DELETE_SQL,
   2884             EVIDENCE_RECONCILIATIONS_NO_DELETE_SHA256,
   2885         )?,
   2886         object(
   2887             SchemaObjectKind::Table,
   2888             "evidence_reconciliation_sources",
   2889             "evidence_reconciliation_sources",
   2890             CREATE_EVIDENCE_RECONCILIATION_SOURCES_TABLE_SQL,
   2891             EVIDENCE_RECONCILIATION_SOURCES_TABLE_SHA256,
   2892         )?,
   2893         object(
   2894             SchemaObjectKind::Trigger,
   2895             "evidence_reconciliation_sources_no_update",
   2896             "evidence_reconciliation_sources",
   2897             CREATE_EVIDENCE_RECONCILIATION_SOURCES_NO_UPDATE_SQL,
   2898             EVIDENCE_RECONCILIATION_SOURCES_NO_UPDATE_SHA256,
   2899         )?,
   2900         object(
   2901             SchemaObjectKind::Trigger,
   2902             "evidence_reconciliation_sources_no_delete",
   2903             "evidence_reconciliation_sources",
   2904             CREATE_EVIDENCE_RECONCILIATION_SOURCES_NO_DELETE_SQL,
   2905             EVIDENCE_RECONCILIATION_SOURCES_NO_DELETE_SHA256,
   2906         )?,
   2907     ])
   2908 }
   2909 
   2910 fn rhi_reconciliation_job_objects() -> Result<[SchemaObject; 5], RhiStateCatalogError> {
   2911     let object = |kind, name, table_name, sql, digest| {
   2912         SchemaObject::new(
   2913             kind,
   2914             name,
   2915             table_name,
   2916             sql,
   2917             SchemaDigest::from_bytes(digest),
   2918         )
   2919         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2920     };
   2921     Ok([
   2922         object(
   2923             SchemaObjectKind::Table,
   2924             "reconciliation_jobs",
   2925             "reconciliation_jobs",
   2926             CREATE_RECONCILIATION_JOBS_TABLE_SQL,
   2927             RECONCILIATION_JOBS_TABLE_SHA256,
   2928         )?,
   2929         object(
   2930             SchemaObjectKind::Index,
   2931             "reconciliation_jobs_one_active_per_trade",
   2932             "reconciliation_jobs",
   2933             CREATE_RECONCILIATION_JOBS_ONE_ACTIVE_SQL,
   2934             RECONCILIATION_JOBS_ONE_ACTIVE_SHA256,
   2935         )?,
   2936         object(
   2937             SchemaObjectKind::Index,
   2938             "reconciliation_jobs_by_schedule",
   2939             "reconciliation_jobs",
   2940             CREATE_RECONCILIATION_JOBS_SCHEDULE_SQL,
   2941             RECONCILIATION_JOBS_SCHEDULE_SHA256,
   2942         )?,
   2943         object(
   2944             SchemaObjectKind::Trigger,
   2945             "reconciliation_jobs_guard_update",
   2946             "reconciliation_jobs",
   2947             CREATE_RECONCILIATION_JOBS_GUARD_UPDATE_SQL,
   2948             RECONCILIATION_JOBS_GUARD_UPDATE_SHA256,
   2949         )?,
   2950         object(
   2951             SchemaObjectKind::Trigger,
   2952             "reconciliation_jobs_no_delete",
   2953             "reconciliation_jobs",
   2954             CREATE_RECONCILIATION_JOBS_NO_DELETE_SQL,
   2955             RECONCILIATION_JOBS_NO_DELETE_SHA256,
   2956         )?,
   2957     ])
   2958 }
   2959 
   2960 fn rhi_source_checkpoint_objects() -> Result<[SchemaObject; 6], RhiStateCatalogError> {
   2961     let object = |kind, name, table_name, sql, digest| {
   2962         SchemaObject::new(
   2963             kind,
   2964             name,
   2965             table_name,
   2966             sql,
   2967             SchemaDigest::from_bytes(digest),
   2968         )
   2969         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   2970     };
   2971     Ok([
   2972         object(
   2973             SchemaObjectKind::Table,
   2974             "relay_checkpoints",
   2975             "relay_checkpoints",
   2976             CREATE_RELAY_CHECKPOINTS_TABLE_SQL,
   2977             RELAY_CHECKPOINTS_TABLE_SHA256,
   2978         )?,
   2979         object(
   2980             SchemaObjectKind::Trigger,
   2981             "relay_checkpoints_guard_update",
   2982             "relay_checkpoints",
   2983             CREATE_RELAY_CHECKPOINTS_GUARD_UPDATE_SQL,
   2984             RELAY_CHECKPOINTS_GUARD_UPDATE_SHA256,
   2985         )?,
   2986         object(
   2987             SchemaObjectKind::Trigger,
   2988             "relay_checkpoints_no_delete",
   2989             "relay_checkpoints",
   2990             CREATE_RELAY_CHECKPOINTS_NO_DELETE_SQL,
   2991             RELAY_CHECKPOINTS_NO_DELETE_SHA256,
   2992         )?,
   2993         object(
   2994             SchemaObjectKind::Table,
   2995             "trade_dirty_generations",
   2996             "trade_dirty_generations",
   2997             CREATE_TRADE_DIRTY_GENERATIONS_TABLE_SQL,
   2998             TRADE_DIRTY_GENERATIONS_TABLE_SHA256,
   2999         )?,
   3000         object(
   3001             SchemaObjectKind::Trigger,
   3002             "trade_dirty_generations_guard_update",
   3003             "trade_dirty_generations",
   3004             CREATE_TRADE_DIRTY_GENERATIONS_GUARD_UPDATE_SQL,
   3005             TRADE_DIRTY_GENERATIONS_GUARD_UPDATE_SHA256,
   3006         )?,
   3007         object(
   3008             SchemaObjectKind::Trigger,
   3009             "trade_dirty_generations_no_delete",
   3010             "trade_dirty_generations",
   3011             CREATE_TRADE_DIRTY_GENERATIONS_NO_DELETE_SQL,
   3012             TRADE_DIRTY_GENERATIONS_NO_DELETE_SHA256,
   3013         )?,
   3014     ])
   3015 }
   3016 
   3017 fn rhi_trade_evidence_objects() -> Result<[SchemaObject; 12], RhiStateCatalogError> {
   3018     let object = |kind, name, table_name, sql, digest| {
   3019         SchemaObject::new(
   3020             kind,
   3021             name,
   3022             table_name,
   3023             sql,
   3024             SchemaDigest::from_bytes(digest),
   3025         )
   3026         .map_err(|_| RhiStateCatalogError::new(RhiStateCatalogErrorKind::SchemaCatalog))
   3027     };
   3028     Ok([
   3029         object(
   3030             SchemaObjectKind::Table,
   3031             "trade_mutations",
   3032             "trade_mutations",
   3033             CREATE_TRADE_MUTATIONS_TABLE_SQL,
   3034             TRADE_MUTATIONS_TABLE_SHA256,
   3035         )?,
   3036         object(
   3037             SchemaObjectKind::Index,
   3038             "trade_mutations_by_trade",
   3039             "trade_mutations",
   3040             CREATE_TRADE_MUTATIONS_BY_TRADE_SQL,
   3041             TRADE_MUTATIONS_BY_TRADE_SHA256,
   3042         )?,
   3043         object(
   3044             SchemaObjectKind::Table,
   3045             "nostr_events",
   3046             "nostr_events",
   3047             CREATE_NOSTR_EVENTS_TABLE_SQL,
   3048             NOSTR_EVENTS_TABLE_SHA256,
   3049         )?,
   3050         object(
   3051             SchemaObjectKind::Index,
   3052             "nostr_events_by_mutation",
   3053             "nostr_events",
   3054             CREATE_NOSTR_EVENTS_BY_MUTATION_SQL,
   3055             NOSTR_EVENTS_BY_MUTATION_SHA256,
   3056         )?,
   3057         object(
   3058             SchemaObjectKind::Table,
   3059             "relay_observations",
   3060             "relay_observations",
   3061             CREATE_RELAY_OBSERVATIONS_TABLE_SQL,
   3062             RELAY_OBSERVATIONS_TABLE_SHA256,
   3063         )?,
   3064         object(
   3065             SchemaObjectKind::Index,
   3066             "relay_observations_by_event",
   3067             "relay_observations",
   3068             CREATE_RELAY_OBSERVATIONS_BY_EVENT_SQL,
   3069             RELAY_OBSERVATIONS_BY_EVENT_SHA256,
   3070         )?,
   3071         object(
   3072             SchemaObjectKind::Trigger,
   3073             "trade_mutations_no_update",
   3074             "trade_mutations",
   3075             CREATE_TRADE_MUTATIONS_NO_UPDATE_SQL,
   3076             TRADE_MUTATIONS_NO_UPDATE_SHA256,
   3077         )?,
   3078         object(
   3079             SchemaObjectKind::Trigger,
   3080             "trade_mutations_no_delete",
   3081             "trade_mutations",
   3082             CREATE_TRADE_MUTATIONS_NO_DELETE_SQL,
   3083             TRADE_MUTATIONS_NO_DELETE_SHA256,
   3084         )?,
   3085         object(
   3086             SchemaObjectKind::Trigger,
   3087             "nostr_events_no_update",
   3088             "nostr_events",
   3089             CREATE_NOSTR_EVENTS_NO_UPDATE_SQL,
   3090             NOSTR_EVENTS_NO_UPDATE_SHA256,
   3091         )?,
   3092         object(
   3093             SchemaObjectKind::Trigger,
   3094             "nostr_events_no_delete",
   3095             "nostr_events",
   3096             CREATE_NOSTR_EVENTS_NO_DELETE_SQL,
   3097             NOSTR_EVENTS_NO_DELETE_SHA256,
   3098         )?,
   3099         object(
   3100             SchemaObjectKind::Trigger,
   3101             "relay_observations_no_update",
   3102             "relay_observations",
   3103             CREATE_RELAY_OBSERVATIONS_NO_UPDATE_SQL,
   3104             RELAY_OBSERVATIONS_NO_UPDATE_SHA256,
   3105         )?,
   3106         object(
   3107             SchemaObjectKind::Trigger,
   3108             "relay_observations_no_delete",
   3109             "relay_observations",
   3110             CREATE_RELAY_OBSERVATIONS_NO_DELETE_SQL,
   3111             RELAY_OBSERVATIONS_NO_DELETE_SHA256,
   3112         )?,
   3113     ])
   3114 }