@feltdb/core 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/dist/cli/commands.js +4 -1
  2. package/dist/cli/provisioning-neutrality.js +79 -0
  3. package/dist/collection.d.ts +43 -1
  4. package/dist/collection.d.ts.map +1 -1
  5. package/dist/collection.js +192 -22
  6. package/dist/create/create.js +25 -21
  7. package/dist/create/managed-account.js +11 -0
  8. package/dist/create/package-versions.js +1 -1
  9. package/dist/create/server-source/Cargo.lock +165 -0
  10. package/dist/create/server-source/Cargo.toml +9 -0
  11. package/dist/create/server-source/crates/feltdb/Cargo.toml +3 -0
  12. package/dist/create/server-source/crates/feltdb/benches/gate13_baseline.rs +44 -44
  13. package/dist/create/server-source/crates/feltdb/benches/gate13_phase_7_1_release_economics.rs +12 -24
  14. package/dist/create/server-source/crates/feltdb/benches/gate_13_redux.rs +7 -13
  15. package/dist/create/server-source/crates/feltdb/benches/gate_13_regression_runner.rs +13 -10
  16. package/dist/create/server-source/crates/feltdb/benches/gate_14a_concurrent_writer_scaling.rs +12 -9
  17. package/dist/create/server-source/crates/feltdb/benches/gate_14a_production_admission_revalidation.rs +78 -25
  18. package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc2_admission_contract.rs +16 -13
  19. package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc_root_cause.rs +13 -5
  20. package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync1_queued_prototype.rs +41 -22
  21. package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync_economics.rs +33 -15
  22. package/dist/create/server-source/crates/feltdb/benches/gate_14b_causal_backlog_scaling.rs +100 -33
  23. package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_contract_test.rs +56 -20
  24. package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_scaling.rs +116 -41
  25. package/dist/create/server-source/crates/feltdb/benches/gate_14d_combined_dimension_scaling.rs +186 -55
  26. package/dist/create/server-source/crates/feltdb/benches/phase_7_1_2_optimization_benchmark.rs +64 -26
  27. package/dist/create/server-source/crates/feltdb/benches/phase_7_1_3_crossover_analysis.rs +46 -15
  28. package/dist/create/server-source/crates/feltdb/src/admission.rs +8 -15
  29. package/dist/create/server-source/crates/feltdb/src/admission_contract_tests.rs +43 -13
  30. package/dist/create/server-source/crates/feltdb/src/adversarial_transport.rs +15 -42
  31. package/dist/create/server-source/crates/feltdb/src/analytics.rs +65 -19
  32. package/dist/create/server-source/crates/feltdb/src/application.rs +113 -30
  33. package/dist/create/server-source/crates/feltdb/src/authorization_security_tests.rs +475 -140
  34. package/dist/create/server-source/crates/feltdb/src/cardinality_diagnostics.rs +17 -15
  35. package/dist/create/server-source/crates/feltdb/src/cardinality_endpoint.rs +0 -1
  36. package/dist/create/server-source/crates/feltdb/src/causal_backlog_bound.rs +59 -15
  37. package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier.rs +266 -114
  38. package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier_phase_7_1.rs +25 -7
  39. package/dist/create/server-source/crates/feltdb/src/concurrency_fuzzing.rs +10 -15
  40. package/dist/create/server-source/crates/feltdb/src/consistency_contract.rs +3 -11
  41. package/dist/create/server-source/crates/feltdb/src/crash_atomic_boundary.rs +14 -5
  42. package/dist/create/server-source/crates/feltdb/src/crash_injection.rs +21 -25
  43. package/dist/create/server-source/crates/feltdb/src/crash_recovery_tests.rs +14 -11
  44. package/dist/create/server-source/crates/feltdb/src/dedup_bound_investigation.rs +103 -22
  45. package/dist/create/server-source/crates/feltdb/src/distributed_indexing.rs +18 -15
  46. package/dist/create/server-source/crates/feltdb/src/durability_guarantees.rs +12 -8
  47. package/dist/create/server-source/crates/feltdb/src/durable_dedup_set.rs +1 -5
  48. package/dist/create/server-source/crates/feltdb/src/durable_operation_identity.rs +87 -23
  49. package/dist/create/server-source/crates/feltdb/src/durable_operation_log.rs +3 -7
  50. package/dist/create/server-source/crates/feltdb/src/durable_sync.rs +10 -9
  51. package/dist/create/server-source/crates/feltdb/src/equality_index.rs +595 -0
  52. package/dist/create/server-source/crates/feltdb/src/in_process_transport.rs +1 -6
  53. package/dist/create/server-source/crates/feltdb/src/indexing.rs +35 -38
  54. package/dist/create/server-source/crates/feltdb/src/lib.rs +1050 -117
  55. package/dist/create/server-source/crates/feltdb/src/managed_cas_tests.rs +4 -1
  56. package/dist/create/server-source/crates/feltdb/src/metrics.rs +0 -1
  57. package/dist/create/server-source/crates/feltdb/src/multi_node_convergence.rs +1 -2
  58. package/dist/create/server-source/crates/feltdb/src/multi_operation_transaction.rs +107 -30
  59. package/dist/create/server-source/crates/feltdb/src/observability.rs +19 -6
  60. package/dist/create/server-source/crates/feltdb/src/operation_algebra.rs +12 -11
  61. package/dist/create/server-source/crates/feltdb/src/operation_log.rs +9 -4
  62. package/dist/create/server-source/crates/feltdb/src/p1_application_atomicity.rs +65 -18
  63. package/dist/create/server-source/crates/feltdb/src/p1_atomicity_acceptance.rs +193 -57
  64. package/dist/create/server-source/crates/feltdb/src/partition_reconciliation.rs +37 -27
  65. package/dist/create/server-source/crates/feltdb/src/permutation_scheduler.rs +38 -10
  66. package/dist/create/server-source/crates/feltdb/src/persistence_reality.rs +20 -14
  67. package/dist/create/server-source/crates/feltdb/src/phase1b_acceptance.rs +394 -229
  68. package/dist/create/server-source/crates/feltdb/src/phase1c1_acceptance.rs +8 -6
  69. package/dist/create/server-source/crates/feltdb/src/phase1c2_acceptance.rs +11 -13
  70. package/dist/create/server-source/crates/feltdb/src/phase1c3_acceptance.rs +90 -72
  71. package/dist/create/server-source/crates/feltdb/src/phase1c_atomicity_proof.rs +3 -3
  72. package/dist/create/server-source/crates/feltdb/src/phase5_integration.rs +33 -11
  73. package/dist/create/server-source/crates/feltdb/src/phase5_scenarios.rs +6 -6
  74. package/dist/create/server-source/crates/feltdb/src/phase6_adversarial_scenarios.rs +14 -56
  75. package/dist/create/server-source/crates/feltdb/src/phase6_convergence_validator.rs +29 -27
  76. package/dist/create/server-source/crates/feltdb/src/phase6_persistence.rs +35 -17
  77. package/dist/create/server-source/crates/feltdb/src/phase_1c_real_tcp.rs +8 -2
  78. package/dist/create/server-source/crates/feltdb/src/phase_2a_failures.rs +59 -15
  79. package/dist/create/server-source/crates/feltdb/src/phase_2b_network.rs +70 -17
  80. package/dist/create/server-source/crates/feltdb/src/phase_2c_cascading.rs +23 -6
  81. package/dist/create/server-source/crates/feltdb/src/phase_3_durability.rs +12 -3
  82. package/dist/create/server-source/crates/feltdb/src/phase_4_baseline.rs +41 -11
  83. package/dist/create/server-source/crates/feltdb/src/phase_5_soak.rs +56 -25
  84. package/dist/create/server-source/crates/feltdb/src/policy_evaluation.rs +701 -245
  85. package/dist/create/server-source/crates/feltdb/src/production_api.rs +31 -13
  86. package/dist/create/server-source/crates/feltdb/src/query_execution_diagnostics.rs +126 -0
  87. package/dist/create/server-source/crates/feltdb/src/query_performance.rs +6 -8
  88. package/dist/create/server-source/crates/feltdb/src/replay_fuzzing.rs +5 -5
  89. package/dist/create/server-source/crates/feltdb/src/replica_acknowledgements.rs +48 -18
  90. package/dist/create/server-source/crates/feltdb/src/replica_membership.rs +30 -11
  91. package/dist/create/server-source/crates/feltdb/src/replication_manager.rs +6 -3
  92. package/dist/create/server-source/crates/feltdb/src/replication_protocol.rs +4 -3
  93. package/dist/create/server-source/crates/feltdb/src/sharding.rs +36 -10
  94. package/dist/create/server-source/crates/feltdb/src/state_conflict_contract.rs +516 -0
  95. package/dist/create/server-source/crates/feltdb/src/state_contract.rs +305 -6
  96. package/dist/create/server-source/crates/feltdb/src/state_diff_contract.rs +222 -0
  97. package/dist/create/server-source/crates/feltdb/src/state_facade.rs +82 -54
  98. package/dist/create/server-source/crates/feltdb/src/state_hash.rs +2 -2
  99. package/dist/create/server-source/crates/feltdb/src/state_model.rs +1514 -537
  100. package/dist/create/server-source/crates/feltdb/src/state_transition_store.rs +6 -3
  101. package/dist/create/server-source/crates/feltdb/src/state_trigger.rs +672 -0
  102. package/dist/create/server-source/crates/feltdb/src/submission.rs +5 -11
  103. package/dist/create/server-source/crates/feltdb/src/sync.rs +12 -0
  104. package/dist/create/server-source/crates/feltdb/src/tcp_transport.rs +6 -8
  105. package/dist/create/server-source/crates/feltdb/src/transaction_api.rs +24 -35
  106. package/dist/create/server-source/crates/feltdb/src/transaction_invariants.rs +24 -8
  107. package/dist/create/server-source/crates/feltdb/src/transaction_preconditions.rs +248 -59
  108. package/dist/create/server-source/crates/feltdb/src/transactions.rs +17 -20
  109. package/dist/create/server-source/crates/feltdb/src/trigger_contract.rs +749 -0
  110. package/dist/create/server-source/crates/feltdb/src/worker_mesh.rs +1 -0
  111. package/dist/create/server-source/crates/feltdb/src/workload.rs +512 -4
  112. package/dist/create/server-source/crates/feltdb/src/workload_diagnostics.rs +442 -0
  113. package/dist/create/server-source/crates/feltdb/tests/branching_evidence.rs +299 -0
  114. package/dist/create/server-source/crates/feltdb/tests/current_revision_authority_evidence.rs +288 -0
  115. package/dist/create/server-source/crates/feltdb/tests/durable_format_compatibility.rs +392 -0
  116. package/dist/create/server-source/crates/feltdb/tests/feltdb_state_boundary_tests.rs +436 -220
  117. package/dist/create/server-source/crates/feltdb/tests/fixtures/state_conflict_contract_corpus.json +1916 -0
  118. package/dist/create/server-source/crates/feltdb/tests/fixtures/state_diff_contract_corpus.json +1878 -0
  119. package/dist/create/server-source/crates/feltdb/tests/fixtures/trigger_contract_corpus.json +1862 -0
  120. package/dist/create/server-source/crates/feltdb/tests/pr34_query_collection.rs +234 -0
  121. package/dist/create/server-source/crates/feltdb/tests/pr35_equality_index.rs +947 -0
  122. package/dist/create/server-source/crates/feltdb/tests/pr7_self_authorization_proof.rs +5 -8
  123. package/dist/create/server-source/crates/feltdb/tests/pr8_vocabulary_assessment.rs +52 -44
  124. package/dist/create/server-source/crates/feltdb/tests/pr9_phase2_boundary_tests.rs +33 -16
  125. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3a_path_a_tests.rs +22 -7
  126. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_authorized_mutations.rs +41 -22
  127. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_role_based_authorization.rs +25 -8
  128. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_simple_auth_delete.rs +9 -6
  129. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_team_delete_role_authorization.rs +120 -69
  130. package/dist/create/server-source/crates/feltdb/tests/pr9_teams_role_based_access.rs +21 -10
  131. package/dist/create/server-source/crates/feltdb/tests/production_readiness_contract.rs +1032 -0
  132. package/dist/create/server-source/crates/feltdb/tests/reconciliation_application.rs +868 -0
  133. package/dist/create/server-source/crates/feltdb/tests/reconciliation_wire_format_evidence.rs +221 -0
  134. package/dist/create/server-source/crates/feltdb/tests/resource_scoped_revisions.rs +338 -0
  135. package/dist/create/server-source/crates/feltdb/tests/revision_identity_contract.rs +1039 -0
  136. package/dist/create/server-source/crates/feltdb/tests/revision_model_decision.rs +739 -0
  137. package/dist/create/server-source/crates/feltdb/tests/revision_retention_boundary_evidence.rs +427 -0
  138. package/dist/create/server-source/crates/feltdb/tests/saas_authorization_integration.rs +3 -3
  139. package/dist/create/server-source/crates/feltdb/tests/saas_invitation_lifecycle.rs +25 -22
  140. package/dist/create/server-source/crates/feltdb/tests/state_conflict_contract_conformance.rs +1799 -0
  141. package/dist/create/server-source/crates/feltdb/tests/state_diff_contract_conformance.rs +1316 -0
  142. package/dist/create/server-source/crates/feltdb/tests/state_model_integration.rs +53 -61
  143. package/dist/create/server-source/crates/feltdb/tests/state_persistence_integration.rs +156 -61
  144. package/dist/create/server-source/crates/feltdb/tests/state_store_boundary_evidence.rs +299 -0
  145. package/dist/create/server-source/crates/feltdb/tests/sync_divergence_evidence.rs +255 -0
  146. package/dist/create/server-source/crates/feltdb/tests/three_way_input_boundary_evidence.rs +249 -0
  147. package/dist/create/server-source/crates/feltdb/tests/trigger_contract_conformance.rs +994 -0
  148. package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +2 -1
  149. package/dist/create/server-source/crates/feltdb-server/src/audit.rs +1137 -29
  150. package/dist/create/server-source/crates/feltdb-server/src/auth.rs +164 -13
  151. package/dist/create/server-source/crates/feltdb-server/src/main.rs +800 -34
  152. package/dist/db.d.ts +33 -34
  153. package/dist/db.d.ts.map +1 -1
  154. package/dist/db.js +74 -20
  155. package/dist/deployment.d.ts +30 -0
  156. package/dist/deployment.d.ts.map +1 -0
  157. package/dist/deployment.js +130 -0
  158. package/dist/embedded-transaction.d.ts +22 -4
  159. package/dist/embedded-transaction.d.ts.map +1 -1
  160. package/dist/embedded-transaction.js +51 -5
  161. package/dist/feltdb.d.ts +14 -2
  162. package/dist/feltdb.d.ts.map +1 -1
  163. package/dist/file-db.js +1 -1
  164. package/dist/http-client.d.ts +14 -0
  165. package/dist/http-client.d.ts.map +1 -1
  166. package/dist/http-client.js +23 -5
  167. package/dist/http-db.d.ts +119 -1
  168. package/dist/http-db.d.ts.map +1 -1
  169. package/dist/http-db.js +346 -31
  170. package/dist/index-core.d.ts +2 -0
  171. package/dist/index-core.d.ts.map +1 -1
  172. package/dist/index-core.js +2 -0
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.js +9 -0
  175. package/dist/indexeddb-db.d.ts.map +1 -1
  176. package/dist/indexeddb-db.js +35 -21
  177. package/dist/managed-recovery.d.ts +192 -0
  178. package/dist/managed-recovery.d.ts.map +1 -0
  179. package/dist/managed-recovery.js +242 -0
  180. package/dist/memory-db.js +1 -1
  181. package/dist/studio-app/assets/{feltdb_wasm-DB8cX151.js → feltdb_wasm-DaNwCLRX.js} +1 -1
  182. package/dist/studio-app/assets/feltdb_wasm_bg-DnsHNv6g.wasm +0 -0
  183. package/dist/studio-app/assets/index-j8IlhNqJ.js +29 -0
  184. package/dist/studio-app/index.html +1 -1
  185. package/dist/transaction.d.ts +30 -0
  186. package/dist/transaction.d.ts.map +1 -1
  187. package/dist/transaction.js +41 -0
  188. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  189. package/dist/workload.d.ts +2 -1
  190. package/dist/workload.d.ts.map +1 -1
  191. package/package.json +1 -1
  192. package/dist/studio-app/assets/feltdb_wasm_bg-ClhDHp0S.wasm +0 -0
  193. package/dist/studio-app/assets/index-B0k4UAlI.js +0 -29
@@ -13,7 +13,7 @@ mod tests {
13
13
  use crate::distributed_transactions::TransactionEnvelope;
14
14
  use crate::durable_operation_log::OperationLog;
15
15
  use crate::state_hash::StateHash;
16
- use crate::transactions::{ConsistencyLevel, ConsistencyContract};
16
+ use crate::transactions::{ConsistencyContract, ConsistencyLevel};
17
17
  use tempfile::TempDir;
18
18
 
19
19
  fn create_test_envelope(node: &str, sequence: u64) -> TransactionEnvelope {
@@ -68,8 +68,7 @@ mod tests {
68
68
  /// 2. Recover log from disk
69
69
  /// 3. Verify all 3 recovered in order
70
70
  #[test]
71
- fn test_durable_log_multiple_envelopes_in_order(
72
- ) -> Result<(), Box<dyn std::error::Error>> {
71
+ fn test_durable_log_multiple_envelopes_in_order() -> Result<(), Box<dyn std::error::Error>> {
73
72
  let temp_dir = TempDir::new()?;
74
73
  let log_path = temp_dir.path().join("operations.log");
75
74
 
@@ -89,8 +88,11 @@ mod tests {
89
88
 
90
89
  assert_eq!(loaded.len(), 3, "Should have recovered 3 envelopes");
91
90
  for (i, envelope) in loaded.iter().enumerate() {
92
- assert_eq!(envelope.envelope_id.sequence, (i + 1) as u64,
93
- "Envelopes should be in order");
91
+ assert_eq!(
92
+ envelope.envelope_id.sequence,
93
+ (i + 1) as u64,
94
+ "Envelopes should be in order"
95
+ );
94
96
  }
95
97
  }
96
98
 
@@ -110,7 +112,7 @@ mod tests {
110
112
 
111
113
  for seq in 1..=100 {
112
114
  let envelope = create_test_envelope("nodeA", seq);
113
- log.append(&envelope)?; // Each append must fsync
115
+ log.append(&envelope)?; // Each append must fsync
114
116
  }
115
117
 
116
118
  // Verify all 100 can be loaded (fsync guarantee)
@@ -13,7 +13,7 @@ mod tests {
13
13
  use crate::distributed_transactions::{DistributedTransactionExecutor, TransactionEnvelope};
14
14
  use crate::durable_dedup_set::DeduplicationSet;
15
15
  use crate::state_hash::StateHash;
16
- use crate::transactions::{ConsistencyLevel, ConsistencyContract};
16
+ use crate::transactions::{ConsistencyContract, ConsistencyLevel};
17
17
  use tempfile::TempDir;
18
18
 
19
19
  fn create_test_envelope(node: &str, sequence: u64) -> TransactionEnvelope {
@@ -79,12 +79,11 @@ mod tests {
79
79
 
80
80
  // Step 1 & 2: Create executor with log and simulate loading persisted state
81
81
  {
82
- let executor =
83
- DistributedTransactionExecutor::with_log(
84
- "nodeA".to_string(),
85
- StateHash::from_hex("state_v0".to_string()),
86
- Some(log_path.clone()),
87
- )?;
82
+ let executor = DistributedTransactionExecutor::with_log(
83
+ "nodeA".to_string(),
84
+ StateHash::from_hex("state_v0".to_string()),
85
+ Some(log_path.clone()),
86
+ )?;
88
87
 
89
88
  // Verify executor has dedup set configured
90
89
  let node_id = executor.get_local_node_id();
@@ -93,12 +92,11 @@ mod tests {
93
92
 
94
93
  // Step 3: Create another executor and load from disk
95
94
  {
96
- let mut executor =
97
- DistributedTransactionExecutor::with_log(
98
- "nodeA".to_string(),
99
- StateHash::from_hex("state_v0".to_string()),
100
- Some(log_path.clone()),
101
- )?;
95
+ let mut executor = DistributedTransactionExecutor::with_log(
96
+ "nodeA".to_string(),
97
+ StateHash::from_hex("state_v0".to_string()),
98
+ Some(log_path.clone()),
99
+ )?;
102
100
 
103
101
  // This should set up both operation log and dedup set
104
102
  let recovered = executor.load_from_disk(log_path)?;
@@ -144,12 +144,11 @@ mod tests {
144
144
  let log_path = temp_dir.path().join("operations.log");
145
145
 
146
146
  // Setup: Node A and B both have operations 1-3
147
- let mut node_a =
148
- DistributedTransactionExecutor::with_log(
149
- "nodeA".to_string(),
150
- StateHash::from_hex("hash0".to_string()),
151
- Some(log_path.clone()),
152
- )?;
147
+ let mut node_a = DistributedTransactionExecutor::with_log(
148
+ "nodeA".to_string(),
149
+ StateHash::from_hex("hash0".to_string()),
150
+ Some(log_path.clone()),
151
+ )?;
153
152
 
154
153
  let node_b = DistributedTransactionExecutor::new(
155
154
  "nodeB".to_string(),
@@ -157,7 +156,10 @@ mod tests {
157
156
  );
158
157
 
159
158
  // Simulate: Both nodes have same state
160
- node_a.register_replica("nodeB".to_string(), StateHash::from_hex("hash0".to_string()));
159
+ node_a.register_replica(
160
+ "nodeB".to_string(),
161
+ StateHash::from_hex("hash0".to_string()),
162
+ );
161
163
 
162
164
  // Verify convergence
163
165
  assert!(node_a.check_convergence());
@@ -183,12 +185,11 @@ mod tests {
183
185
  let log_path = temp_dir.path().join("operations.log");
184
186
 
185
187
  // Setup: Node A (restarted, missing op), Node B (authoritative)
186
- let mut node_a =
187
- DistributedTransactionExecutor::with_log(
188
- "nodeA".to_string(),
189
- StateHash::from_hex("hash0".to_string()),
190
- Some(log_path.clone()),
191
- )?;
188
+ let mut node_a = DistributedTransactionExecutor::with_log(
189
+ "nodeA".to_string(),
190
+ StateHash::from_hex("hash0".to_string()),
191
+ Some(log_path.clone()),
192
+ )?;
192
193
 
193
194
  let mut node_b = DistributedTransactionExecutor::new(
194
195
  "nodeB".to_string(),
@@ -196,8 +197,14 @@ mod tests {
196
197
  );
197
198
 
198
199
  // Register each other
199
- node_a.register_replica("nodeB".to_string(), StateHash::from_hex("hash0".to_string()));
200
- node_b.register_replica("nodeA".to_string(), StateHash::from_hex("hash0".to_string()));
200
+ node_a.register_replica(
201
+ "nodeB".to_string(),
202
+ StateHash::from_hex("hash0".to_string()),
203
+ );
204
+ node_b.register_replica(
205
+ "nodeA".to_string(),
206
+ StateHash::from_hex("hash0".to_string()),
207
+ );
201
208
 
202
209
  // Peer (B) has operation 1
203
210
  let missing_op = create_test_envelope("nodeB", 1);
@@ -222,20 +229,25 @@ mod tests {
222
229
  let temp_dir = TempDir::new()?;
223
230
  let log_path = temp_dir.path().join("operations.log");
224
231
 
225
- let mut node_a =
226
- DistributedTransactionExecutor::with_log(
227
- "nodeA".to_string(),
228
- StateHash::from_hex("hash0".to_string()),
229
- Some(log_path.clone()),
230
- )?;
232
+ let mut node_a = DistributedTransactionExecutor::with_log(
233
+ "nodeA".to_string(),
234
+ StateHash::from_hex("hash0".to_string()),
235
+ Some(log_path.clone()),
236
+ )?;
231
237
 
232
238
  let mut node_b = DistributedTransactionExecutor::new(
233
239
  "nodeB".to_string(),
234
240
  StateHash::from_hex("hash0".to_string()),
235
241
  );
236
242
 
237
- node_a.register_replica("nodeB".to_string(), StateHash::from_hex("hash0".to_string()));
238
- node_b.register_replica("nodeA".to_string(), StateHash::from_hex("hash0".to_string()));
243
+ node_a.register_replica(
244
+ "nodeB".to_string(),
245
+ StateHash::from_hex("hash0".to_string()),
246
+ );
247
+ node_b.register_replica(
248
+ "nodeA".to_string(),
249
+ StateHash::from_hex("hash0".to_string()),
250
+ );
239
251
 
240
252
  // Peer has operations 1-5
241
253
  let missing_ops: Vec<_> = (1..=5)
@@ -261,12 +273,11 @@ mod tests {
261
273
  let temp_dir = TempDir::new()?;
262
274
  let log_path = temp_dir.path().join("operations.log");
263
275
 
264
- let mut node_a =
265
- DistributedTransactionExecutor::with_log(
266
- "nodeA".to_string(),
267
- StateHash::from_hex("hash0".to_string()),
268
- Some(log_path.clone()),
269
- )?;
276
+ let mut node_a = DistributedTransactionExecutor::with_log(
277
+ "nodeA".to_string(),
278
+ StateHash::from_hex("hash0".to_string()),
279
+ Some(log_path.clone()),
280
+ )?;
270
281
 
271
282
  let node_b = DistributedTransactionExecutor::new(
272
283
  "nodeB".to_string(),
@@ -275,9 +286,7 @@ mod tests {
275
286
 
276
287
  // Pre-populate node_a's seen set to simulate prior durability
277
288
  let envelope = create_test_envelope("nodeB", 1);
278
- node_a
279
- .envelopes_seen
280
- .insert(envelope.envelope_id.clone());
289
+ node_a.envelopes_seen.insert(envelope.envelope_id.clone());
281
290
 
282
291
  // Recovery tries to apply same envelope (duplicate)
283
292
  let mut recovery = RecoveryOrchestrator::new(node_a, "nodeB".to_string());
@@ -285,7 +294,10 @@ mod tests {
285
294
  recovery.apply_missing_operations(vec![envelope.clone()])?;
286
295
 
287
296
  // Should not error on duplicate—dedup handles it
288
- assert!(recovery.executor.envelopes_seen.contains(&envelope.envelope_id));
297
+ assert!(recovery
298
+ .executor
299
+ .envelopes_seen
300
+ .contains(&envelope.envelope_id));
289
301
  recovery.finalize_recovery()?;
290
302
 
291
303
  assert_eq!(recovery.get_state(), RecoveryState::Ready);
@@ -303,12 +315,11 @@ mod tests {
303
315
  let log_path = temp_dir.path().join("operations.log");
304
316
 
305
317
  // First recovery attempt (simulated interruption)
306
- let node_a_attempt1 =
307
- DistributedTransactionExecutor::with_log(
308
- "nodeA".to_string(),
309
- StateHash::from_hex("hash0".to_string()),
310
- Some(log_path.clone()),
311
- )?;
318
+ let node_a_attempt1 = DistributedTransactionExecutor::with_log(
319
+ "nodeA".to_string(),
320
+ StateHash::from_hex("hash0".to_string()),
321
+ Some(log_path.clone()),
322
+ )?;
312
323
 
313
324
  let node_b = DistributedTransactionExecutor::new(
314
325
  "nodeB".to_string(),
@@ -325,12 +336,11 @@ mod tests {
325
336
  recovery1.apply_missing_operations(ops[0..2].to_vec())?;
326
337
 
327
338
  // Second recovery attempt (after restart)
328
- let mut node_a_attempt2 =
329
- DistributedTransactionExecutor::with_log(
330
- "nodeA".to_string(),
331
- StateHash::from_hex("hash0".to_string()),
332
- Some(log_path.clone()),
333
- )?;
339
+ let mut node_a_attempt2 = DistributedTransactionExecutor::with_log(
340
+ "nodeA".to_string(),
341
+ StateHash::from_hex("hash0".to_string()),
342
+ Some(log_path.clone()),
343
+ )?;
334
344
  node_a_attempt2
335
345
  .envelopes_seen
336
346
  .extend(recovery1.executor.envelopes_seen.clone());
@@ -355,12 +365,11 @@ mod tests {
355
365
  let temp_dir = TempDir::new()?;
356
366
  let log_path = temp_dir.path().join("operations.log");
357
367
 
358
- let node_a =
359
- DistributedTransactionExecutor::with_log(
360
- "nodeA".to_string(),
361
- StateHash::from_hex("hash0".to_string()),
362
- Some(log_path.clone()),
363
- )?;
368
+ let node_a = DistributedTransactionExecutor::with_log(
369
+ "nodeA".to_string(),
370
+ StateHash::from_hex("hash0".to_string()),
371
+ Some(log_path.clone()),
372
+ )?;
364
373
 
365
374
  // No peer available - simulate peer_state being unavailable
366
375
  let mut recovery = RecoveryOrchestrator::new(node_a, "unavailable_peer".to_string());
@@ -398,16 +407,18 @@ mod tests {
398
407
  );
399
408
 
400
409
  // Create restarted node with same initial hash
401
- let mut local =
402
- DistributedTransactionExecutor::with_log(
403
- "local".to_string(),
404
- StateHash::from_hex("hash0".to_string()),
405
- Some(log_path.clone()),
406
- )?;
410
+ let mut local = DistributedTransactionExecutor::with_log(
411
+ "local".to_string(),
412
+ StateHash::from_hex("hash0".to_string()),
413
+ Some(log_path.clone()),
414
+ )?;
407
415
 
408
416
  // Register each other with same state
409
417
  local.register_replica("peer".to_string(), StateHash::from_hex("hash0".to_string()));
410
- peer.register_replica("local".to_string(), StateHash::from_hex("hash0".to_string()));
418
+ peer.register_replica(
419
+ "local".to_string(),
420
+ StateHash::from_hex("hash0".to_string()),
421
+ );
411
422
 
412
423
  // Reconcile: Both have same state
413
424
  let mut recovery = RecoveryOrchestrator::new(local, "peer".to_string());
@@ -439,24 +450,22 @@ mod tests {
439
450
 
440
451
  // Phase 1: Initial execution and persistence
441
452
  {
442
- let executor =
443
- DistributedTransactionExecutor::with_log(
444
- "nodeA".to_string(),
445
- StateHash::from_hex("hash0".to_string()),
446
- Some(log_path.clone()),
447
- )?;
453
+ let executor = DistributedTransactionExecutor::with_log(
454
+ "nodeA".to_string(),
455
+ StateHash::from_hex("hash0".to_string()),
456
+ Some(log_path.clone()),
457
+ )?;
448
458
 
449
459
  let _node_id = executor.get_local_node_id();
450
460
  assert_eq!(_node_id, "nodeA");
451
461
  }
452
462
 
453
463
  // Phase 2: "Crash" and restart
454
- let mut recovered_executor =
455
- DistributedTransactionExecutor::with_log(
456
- "nodeA".to_string(),
457
- StateHash::from_hex("hash0".to_string()),
458
- Some(log_path.clone()),
459
- )?;
464
+ let mut recovered_executor = DistributedTransactionExecutor::with_log(
465
+ "nodeA".to_string(),
466
+ StateHash::from_hex("hash0".to_string()),
467
+ Some(log_path.clone()),
468
+ )?;
460
469
 
461
470
  // Phase 3: Load from disk (reconstruct dedup from operation log)
462
471
  let count = recovered_executor.load_from_disk(log_path)?;
@@ -468,8 +477,17 @@ mod tests {
468
477
  StateHash::from_hex("hash0".to_string()),
469
478
  );
470
479
 
471
- recovered_executor
472
- .register_replica("nodeB".to_string(), StateHash::from_hex("hash0".to_string()));
480
+ // The peer is registered at the state the recovered node actually
481
+ // holds, read back rather than restated. `load_from_disk` recomputes
482
+ // the local replica's hash from the replayed log, so a fabricated
483
+ // literal here would describe a peer that has diverged and the
484
+ // convergence check below would be asserting the opposite of what this
485
+ // test is about.
486
+ let recovered_hash = recovered_executor
487
+ .get_replica_state("nodeA")
488
+ .expect("the recovered node has a local replica")
489
+ .state_hash;
490
+ recovered_executor.register_replica("nodeB".to_string(), recovered_hash);
473
491
 
474
492
  let mut recovery = RecoveryOrchestrator::new(recovered_executor, "nodeB".to_string());
475
493
  recovery.reconcile_with_peer(&peer)?;
@@ -9,10 +9,10 @@
9
9
 
10
10
  #[cfg(test)]
11
11
  mod tests {
12
- use crate::durable_operation_log::OperationLog;
13
12
  use crate::distributed_transactions::TransactionEnvelope;
13
+ use crate::durable_operation_log::OperationLog;
14
14
  use crate::state_hash::StateHash;
15
- use crate::transactions::{ConsistencyLevel, ConsistencyContract};
15
+ use crate::transactions::{ConsistencyContract, ConsistencyLevel};
16
16
  use tempfile::TempDir;
17
17
 
18
18
  fn create_test_envelope(node: &str, sequence: u64) -> TransactionEnvelope {
@@ -95,7 +95,7 @@ mod tests {
95
95
  let mut log = OperationLog::new(&log_path)?;
96
96
  let envelope = create_test_envelope("nodeA", 1);
97
97
  log.append(&envelope)?; // fsync ensures this is durable
98
- // ... hypothetical crash here ...
98
+ // ... hypothetical crash here ...
99
99
  }
100
100
 
101
101
  // Scenario B: Restart and recover
@@ -66,8 +66,15 @@ mod tests {
66
66
 
67
67
  // Verify all standard operations are registered
68
68
  let standard_ops = vec![
69
- "SetField", "Increment", "AddToSet", "RemoveFromSet", "Create", "Delete", "Transfer",
70
- "Append", "Noop",
69
+ "SetField",
70
+ "Increment",
71
+ "AddToSet",
72
+ "RemoveFromSet",
73
+ "Create",
74
+ "Delete",
75
+ "Transfer",
76
+ "Append",
77
+ "Noop",
71
78
  ];
72
79
 
73
80
  for op_type in &standard_ops {
@@ -125,7 +132,10 @@ mod tests {
125
132
  create_test_operation(3, "records", "rec3", 30),
126
133
  ];
127
134
  let schedules = PermutationScheduler::minimal_schedules(&ops);
128
- println!("Gate 1: Generated {} permutation schedules", schedules.len());
135
+ println!(
136
+ "Gate 1: Generated {} permutation schedules",
137
+ schedules.len()
138
+ );
129
139
 
130
140
  // Integration insight:
131
141
  // - Gate 1 creates permutations
@@ -148,11 +158,14 @@ mod tests {
148
158
  "Increment should be commutative"
149
159
  );
150
160
  assert_eq!(
151
- increment_algebra.merge_function_description, "Counter CRDT: sum(all_increments)"
161
+ increment_algebra.merge_function_description,
162
+ "Counter CRDT: sum(all_increments)"
152
163
  );
153
164
 
154
- println!("✓ Increment declared as commutative (algebra: {})",
155
- increment_algebra.merge_function_description);
165
+ println!(
166
+ "✓ Increment declared as commutative (algebra: {})",
167
+ increment_algebra.merge_function_description
168
+ );
156
169
  }
157
170
 
158
171
  #[test]
@@ -165,7 +178,8 @@ mod tests {
165
178
  // SetField uses LWW (Last-Write-Wins) for determinism
166
179
  assert!(setfield_algebra.is_deterministic());
167
180
  assert_eq!(
168
- setfield_algebra.merge_function_description, "LWW: max(timestamp, value)"
181
+ setfield_algebra.merge_function_description,
182
+ "LWW: max(timestamp, value)"
169
183
  );
170
184
 
171
185
  println!(
@@ -209,7 +223,9 @@ mod tests {
209
223
  // Test that convergence holds as operation count increases
210
224
  for op_count in [1, 3, 5, 10].iter() {
211
225
  let ops: Vec<_> = (1..=*op_count)
212
- .map(|seq| create_test_operation(seq, "records", &format!("rec{}", seq), seq as i32 * 10))
226
+ .map(|seq| {
227
+ create_test_operation(seq, "records", &format!("rec{}", seq), seq as i32 * 10)
228
+ })
213
229
  .collect();
214
230
 
215
231
  let simulator = MultiNodeConvergenceSimulator::new(3);
@@ -263,8 +279,11 @@ mod tests {
263
279
  ];
264
280
  let simulator = MultiNodeConvergenceSimulator::new(3);
265
281
  let result = simulator.test_minimal_convergence(&ops);
266
- println!(" ✓ {} nodes executed {} operations",
267
- result.node_results.len(), ops.len());
282
+ println!(
283
+ " ✓ {} nodes executed {} operations",
284
+ result.node_results.len(),
285
+ ops.len()
286
+ );
268
287
  println!(" ✓ All converged to: {}", result.canonical_hash);
269
288
 
270
289
  println!("\nGate 2: Operation Algebra Declaration");
@@ -272,7 +291,10 @@ mod tests {
272
291
  let algebras = registry.all_algebras();
273
292
  println!(" ✓ {} operation types declared", algebras.len());
274
293
  for alg in algebras.iter().take(5) {
275
- println!(" - {}: {:?}", alg.operation_type, alg.convergence_semantic);
294
+ println!(
295
+ " - {}: {:?}",
296
+ alg.operation_type, alg.convergence_semantic
297
+ );
276
298
  }
277
299
 
278
300
  println!("\n✅ Phase 5 Foundation Established");
@@ -60,7 +60,10 @@ mod tests {
60
60
  // Gate 2: Increment is commutative
61
61
  let registry = OperationAlgebraRegistry::new();
62
62
  let increment_algebra = registry.get("Increment").unwrap();
63
- assert!(increment_algebra.is_commutative(), "Gate 2: Increment not commutative");
63
+ assert!(
64
+ increment_algebra.is_commutative(),
65
+ "Gate 2: Increment not commutative"
66
+ );
64
67
 
65
68
  println!(
66
69
  "✅ Scenario 1: Basic Convergence (Gates 1,2,4,6) - {} nodes converged to {}",
@@ -128,9 +131,7 @@ mod tests {
128
131
  crate::crash_atomic_boundary::InvariantCheckResult::Satisfied
129
132
  ));
130
133
 
131
- println!(
132
- "✅ Scenario 3: Exactly-Once with Crash (Gates 3,4) - invariant satisfied"
133
- );
134
+ println!("✅ Scenario 3: Exactly-Once with Crash (Gates 3,4) - invariant satisfied");
134
135
  }
135
136
 
136
137
  #[test]
@@ -267,8 +268,7 @@ mod tests {
267
268
 
268
269
  let mut barrier = CausalDependencyBarrier::new();
269
270
  let op_empty = VectorClock::new();
270
- let recv_result =
271
- barrier.receive_operation("op1".to_string(), op_empty);
271
+ let recv_result = barrier.receive_operation("op1".to_string(), op_empty);
272
272
  assert!(matches!(
273
273
  recv_result,
274
274
  crate::causal_dependency_barrier::ReceiveResult::ReadyToApply { .. }
@@ -57,18 +57,9 @@ mod tests {
57
57
  assert_eq!(transport.receive(n4).len(), 1);
58
58
 
59
59
  // Gate 9: Partition n1 from {n2, n3, n4}
60
- transport.apply_fault(NetworkEvent::Partition {
61
- from: n1,
62
- to: n2,
63
- });
64
- transport.apply_fault(NetworkEvent::Partition {
65
- from: n1,
66
- to: n3,
67
- });
68
- transport.apply_fault(NetworkEvent::Partition {
69
- from: n1,
70
- to: n4,
71
- });
60
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n2 });
61
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n3 });
62
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n4 });
72
63
 
73
64
  // n1 tries to send but gets dropped by partition
74
65
  transport.send(n1, n2, b"during_partition".to_vec());
@@ -83,18 +74,9 @@ mod tests {
83
74
  assert_eq!(transport.receive(n4).len(), 1);
84
75
 
85
76
  // Gate 9: Heal partition
86
- transport.apply_fault(NetworkEvent::Heal {
87
- from: n1,
88
- to: n2,
89
- });
90
- transport.apply_fault(NetworkEvent::Heal {
91
- from: n1,
92
- to: n3,
93
- });
94
- transport.apply_fault(NetworkEvent::Heal {
95
- from: n1,
96
- to: n4,
97
- });
77
+ transport.apply_fault(NetworkEvent::Heal { from: n1, to: n2 });
78
+ transport.apply_fault(NetworkEvent::Heal { from: n1, to: n3 });
79
+ transport.apply_fault(NetworkEvent::Heal { from: n1, to: n4 });
98
80
 
99
81
  // Now all nodes can communicate again
100
82
  transport.send(n1, n2, b"after_heal".to_vec());
@@ -121,10 +103,7 @@ mod tests {
121
103
  assert_eq!(transport.receive(n3).len(), 1);
122
104
 
123
105
  // Gate 9: Create asymmetric partition (n1→n2 broken but n2→n1 ok)
124
- transport.apply_fault(NetworkEvent::Partition {
125
- from: n1,
126
- to: n2,
127
- });
106
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n2 });
128
107
 
129
108
  // n1 can't reach n2
130
109
  transport.send(n1, n2, b"blocked".to_vec());
@@ -429,10 +408,7 @@ mod tests {
429
408
  });
430
409
 
431
410
  // And partition n1 from n3
432
- transport.apply_fault(NetworkEvent::Partition {
433
- from: n1,
434
- to: n3,
435
- });
411
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n3 });
436
412
 
437
413
  // Byzantine messages from n2 still deliver
438
414
  transport.tick();
@@ -466,20 +442,11 @@ mod tests {
466
442
  assert_eq!(transport.receive(n3).len(), 1);
467
443
 
468
444
  // Round 2-4: Cascade of partitions
469
- transport.apply_fault(NetworkEvent::Partition {
470
- from: n1,
471
- to: n2,
472
- });
445
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n2 });
473
446
  transport.tick();
474
- transport.apply_fault(NetworkEvent::Partition {
475
- from: n1,
476
- to: n3,
477
- });
447
+ transport.apply_fault(NetworkEvent::Partition { from: n1, to: n3 });
478
448
  transport.tick();
479
- transport.apply_fault(NetworkEvent::Partition {
480
- from: n2,
481
- to: n3,
482
- });
449
+ transport.apply_fault(NetworkEvent::Partition { from: n2, to: n3 });
483
450
  transport.tick();
484
451
 
485
452
  // All nodes isolated
@@ -488,10 +455,7 @@ mod tests {
488
455
  assert_eq!(transport.receive(n2).len(), 0);
489
456
 
490
457
  // Round 5-7: Heal partitions one by one
491
- transport.apply_fault(NetworkEvent::Heal {
492
- from: n1,
493
- to: n2,
494
- });
458
+ transport.apply_fault(NetworkEvent::Heal { from: n1, to: n2 });
495
459
  transport.tick();
496
460
 
497
461
  // n1 ↔ n2 now connected
@@ -499,10 +463,7 @@ mod tests {
499
463
  transport.tick();
500
464
  assert_eq!(transport.receive(n2).len(), 1);
501
465
 
502
- transport.apply_fault(NetworkEvent::Heal {
503
- from: n2,
504
- to: n3,
505
- });
466
+ transport.apply_fault(NetworkEvent::Heal { from: n2, to: n3 });
506
467
  transport.tick();
507
468
 
508
469
  // n2 ↔ n3 now connected
@@ -510,10 +471,7 @@ mod tests {
510
471
  transport.tick();
511
472
  assert_eq!(transport.receive(n3).len(), 1);
512
473
 
513
- transport.apply_fault(NetworkEvent::Heal {
514
- from: n1,
515
- to: n3,
516
- });
474
+ transport.apply_fault(NetworkEvent::Heal { from: n1, to: n3 });
517
475
  transport.tick();
518
476
 
519
477
  // All fully connected again