@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
@@ -14,9 +14,8 @@
14
14
  //! - Explicit reconciliation (no automatic merge)
15
15
 
16
16
  use crate::state_model::{
17
- StateId, StateRevision, StateStore, StateTopology, Relationship,
18
- SemanticDiff, ConflictClassification, ReconciliationPlan,
19
- StateReconciliationResult, STATE_MODEL_VERSION,
17
+ ConflictClassification, ReconciliationPlan, Relationship, SemanticDiff, StateId,
18
+ StateReconciliationResult, StateRevision, StateStore, StateTopology, STATE_MODEL_VERSION,
20
19
  };
21
20
  use crate::FeltDb;
22
21
  use std::sync::Arc;
@@ -47,8 +46,8 @@ impl FeltDBStateSystem {
47
46
  /// ```ignore
48
47
  /// let db = FeltDb::open("./data")?;
49
48
  /// let store = FeltDBStateSystem::create_store(&Arc::new(db))?;
50
- /// let initial = store.create(json_string, "app-authority")?;
51
- /// let current = store.current()?;
49
+ /// let initial = store.create("docs:1", json_string, "app-authority")?;
50
+ /// let same = store.get(&initial.id).expect("retrieved by identity");
52
51
  /// ```
53
52
  pub fn create_store(db: &Arc<FeltDb>) -> Result<StateStore, String> {
54
53
  StateStore::with_feltdb(db.clone())
@@ -81,7 +80,9 @@ impl FeltDBStateSystem {
81
80
  2. Use FeltDBStateSystem::create_store(&Arc::new(db)) to initialize state
82
81
  3. Call store.create() for initial state
83
82
  4. Call store.commit() for transitions
84
- 5. Call store.current() to retrieve the working state
83
+ 5. Call store.get(&id) to retrieve a revision by identity
84
+ (the store does not track which revision is "current" — see
85
+ StateStore's own documentation for why that is a separate concern)
85
86
  6. Use StateTopology to inspect causal relationships
86
87
  7. Use SemanticDiff to compute changes between states
87
88
  8. Use ConflictClassification to analyze divergence
@@ -104,7 +105,10 @@ impl FeltDBStateSystem {
104
105
  #[cfg(test)]
105
106
  mod facade_tests {
106
107
  use super::*;
107
- use crate::{ConflictClass, SemanticDiff, StateTopology, Relationship, ConflictClassification, state_model::StateStore};
108
+ use crate::{
109
+ state_model::StateStore, ConflictClass, ConflictClassification, Relationship, SemanticDiff,
110
+ StateTopology,
111
+ };
108
112
  use serde_json::json;
109
113
 
110
114
  #[test]
@@ -112,11 +116,17 @@ mod facade_tests {
112
116
  // For testing, use new_volatile() - production must use create_store(&db)
113
117
  let store = StateStore::new_volatile();
114
118
  let initial = store
115
- .create(r#"{"data":"test"}"#.to_string(), "test-auth".to_string())
119
+ .create(
120
+ "docs:1",
121
+ r#"{"data":"test"}"#.to_string(),
122
+ "test-auth".to_string(),
123
+ )
116
124
  .expect("Failed to create initial state");
117
-
118
- let current = store.current().expect("Failed to get current state");
119
- assert_eq!(current.id, initial.id);
125
+
126
+ let stored = store
127
+ .get(&initial.id)
128
+ .expect("the revision is retrievable by identity");
129
+ assert_eq!(stored.id, initial.id);
120
130
  }
121
131
 
122
132
  #[test]
@@ -128,19 +138,21 @@ mod facade_tests {
128
138
  fn test_facade_comprehensive_workflow() {
129
139
  // Initialize - for testing, use new_volatile()
130
140
  let store = StateStore::new_volatile();
131
-
141
+
132
142
  // Create initial state
133
143
  let initial = store
134
144
  .create(
145
+ "docs:1",
135
146
  r#"{"users":{"alice":100}}"#.to_string(),
136
147
  "app-auth".to_string(),
137
148
  )
138
149
  .expect("Failed to create");
139
150
 
140
- // Verify current
141
- assert_eq!(store.current().unwrap().id, initial.id);
151
+ // Verify the revision is retrievable by identity. The store tracks no
152
+ // "current" pointer; the caller holds the ids it cares about.
153
+ assert_eq!(store.get(&initial.id).unwrap().id, initial.id);
142
154
 
143
- // Branch 1: alice updates
155
+ // Divergence 1: alice updates
144
156
  let branch1 = store
145
157
  .commit(
146
158
  r#"{"users":{"alice":150}}"#.to_string(),
@@ -149,11 +161,7 @@ mod facade_tests {
149
161
  )
150
162
  .expect("Failed branch 1");
151
163
 
152
- store
153
- .create_branch("alice-branch".to_string(), branch1.id.clone())
154
- .expect("Failed to create alice-branch");
155
-
156
- // Branch 2: create from initial
164
+ // Divergence 2: from the same parent
157
165
  let branch2 = store
158
166
  .commit(
159
167
  r#"{"users":{"alice":100,"bob":50}}"#.to_string(),
@@ -162,10 +170,6 @@ mod facade_tests {
162
170
  )
163
171
  .expect("Failed branch 2");
164
172
 
165
- store
166
- .create_branch("bob-branch".to_string(), branch2.id.clone())
167
- .expect("Failed to create bob-branch");
168
-
169
173
  // Inspect topology
170
174
  let mut topology = StateTopology::new();
171
175
  topology.add_revision(initial.clone());
@@ -181,12 +185,10 @@ mod facade_tests {
181
185
  }
182
186
 
183
187
  // Compute diff using JSON values
184
- let initial_json: serde_json::Value = serde_json::from_str(
185
- r#"{"users":{"alice":100}}"#,
186
- ).unwrap();
187
- let branch1_json: serde_json::Value = serde_json::from_str(
188
- r#"{"users":{"alice":150}}"#,
189
- ).unwrap();
188
+ let initial_json: serde_json::Value =
189
+ serde_json::from_str(r#"{"users":{"alice":100}}"#).unwrap();
190
+ let branch1_json: serde_json::Value =
191
+ serde_json::from_str(r#"{"users":{"alice":150}}"#).unwrap();
190
192
  let diff = SemanticDiff::compute(&initial_json, &branch1_json);
191
193
  assert!(!diff.changes.is_empty());
192
194
 
@@ -199,16 +201,16 @@ mod facade_tests {
199
201
  fn test_facade_immutability() {
200
202
  let store = StateStore::new_volatile();
201
203
  let initial = store
202
- .create(r#"{"v":1}"#.to_string(), "auth".to_string())
204
+ .create("docs:1", r#"{"v":1}"#.to_string(), "auth".to_string())
203
205
  .unwrap();
204
-
206
+
205
207
  let initial_id = initial.id.clone();
206
-
208
+
207
209
  // Create another state
208
210
  let second = store
209
211
  .commit(r#"{"v":2}"#.to_string(), &initial, "auth".to_string())
210
212
  .unwrap();
211
-
213
+
212
214
  // Verify first state is unchanged
213
215
  assert_eq!(store.get(&initial_id).unwrap().content, r#"{"v":1}"#);
214
216
  assert_eq!(initial_id, initial.id);
@@ -218,12 +220,16 @@ mod facade_tests {
218
220
  fn test_facade_restart_recovery() {
219
221
  let store1 = StateStore::new_volatile();
220
222
  let initial = store1
221
- .create(r#"{"data":"test"}"#.to_string(), "auth".to_string())
223
+ .create(
224
+ "docs:1",
225
+ r#"{"data":"test"}"#.to_string(),
226
+ "auth".to_string(),
227
+ )
222
228
  .unwrap();
223
-
229
+
224
230
  // Simulate restart: new store instance
225
231
  let _store2 = StateStore::new_volatile();
226
-
232
+
227
233
  // Note: In real scenario, store would load from persistent storage
228
234
  // Here we demonstrate the API contract: states retrieved by id are valid
229
235
  assert!(store1.exists(&initial.id));
@@ -233,44 +239,62 @@ mod facade_tests {
233
239
  fn test_facade_authority_neutrality() {
234
240
  let store = StateStore::new_volatile();
235
241
  let initial = store
236
- .create(r#"{"balance":100}"#.to_string(), "alice".to_string())
242
+ .create(
243
+ "docs:1",
244
+ r#"{"balance":100}"#.to_string(),
245
+ "alice".to_string(),
246
+ )
237
247
  .unwrap();
238
-
248
+
239
249
  let update1 = store
240
- .commit(r#"{"balance":150}"#.to_string(), &initial, "alice".to_string())
250
+ .commit(
251
+ r#"{"balance":150}"#.to_string(),
252
+ &initial,
253
+ "alice".to_string(),
254
+ )
241
255
  .unwrap();
242
-
256
+
243
257
  let update2 = store
244
- .commit(r#"{"balance":150}"#.to_string(), &initial, "bob".to_string())
258
+ .commit(
259
+ r#"{"balance":150}"#.to_string(),
260
+ &initial,
261
+ "bob".to_string(),
262
+ )
245
263
  .unwrap();
246
-
247
- // Same content, different authorities produce same id
264
+
265
+ // The same state, from the same parent, is the same historical fact —
266
+ // so it is one revision, whoever committed it. Authority is recorded
267
+ // but takes no part in identity.
248
268
  assert_eq!(update1.id, update2.id);
249
-
250
- // But authorities are recorded for audit
269
+ assert_eq!(update1.content_id, update2.content_id);
270
+
271
+ // And because authority takes no part in identity, the second commit
272
+ // is a no-op that returns what was already recorded. The authority on a
273
+ // revision is whoever first committed that historical fact, not
274
+ // whoever last asked for it.
251
275
  assert_eq!(update1.authority, "alice");
252
- assert_eq!(update2.authority, "bob");
276
+ assert_eq!(update2.authority, "alice");
253
277
  }
254
278
 
255
279
  #[test]
256
280
  fn test_facade_read_only_operations() {
257
281
  let store = StateStore::new_volatile();
258
282
  let initial = store
259
- .create(r#"{"v":1}"#.to_string(), "auth".to_string())
283
+ .create("docs:1", r#"{"v":1}"#.to_string(), "auth".to_string())
260
284
  .unwrap();
261
-
285
+
262
286
  let update = store
263
287
  .commit(r#"{"v":2}"#.to_string(), &initial, "auth".to_string())
264
288
  .unwrap();
265
-
289
+
266
290
  // Topology operations should not mutate
267
291
  let mut topology = StateTopology::new();
268
292
  topology.add_revision(initial.clone());
269
293
  topology.add_revision(update.clone());
270
-
294
+
271
295
  let rel = topology.relationship(&initial.id, &update.id);
272
296
  assert!(matches!(rel, Relationship::Ancestor));
273
-
297
+
274
298
  // Verify both states still exist unchanged
275
299
  assert_eq!(store.get(&initial.id).unwrap().id, initial.id);
276
300
  assert_eq!(store.get(&update.id).unwrap().id, update.id);
@@ -281,9 +305,13 @@ mod facade_tests {
281
305
  // This test verifies we can use the state system without any .git access
282
306
  let store = StateStore::new_volatile();
283
307
  let state = store
284
- .create(r#"{"test":"no-git"}"#.to_string(), "auth".to_string())
308
+ .create(
309
+ "docs:1",
310
+ r#"{"test":"no-git"}"#.to_string(),
311
+ "auth".to_string(),
312
+ )
285
313
  .expect("State creation should work without .git");
286
-
314
+
287
315
  // Topology and diff operations should work without git
288
316
  let mut topology = StateTopology::new();
289
317
  topology.add_revision(state.clone());
@@ -2,7 +2,6 @@
2
2
  ///
3
3
  /// Produces SHA-256 hashes of canonical state serializations.
4
4
  /// Invariant: same state → same hash, different state → different hash (except negligible crypto collision)
5
-
6
5
  use serde_json::{json, Value};
7
6
  use std::collections::BTreeMap;
8
7
 
@@ -27,7 +26,8 @@ impl CanonicalState {
27
26
 
28
27
  /// Get a record
29
28
  pub fn get_record(&self, collection: &str, record_id: &str) -> Option<&Value> {
30
- self.records.get(&(collection.to_string(), record_id.to_string()))
29
+ self.records
30
+ .get(&(collection.to_string(), record_id.to_string()))
31
31
  }
32
32
 
33
33
  /// Canonical serialization for hashing (deterministic ordering)