@feltdb/core 0.15.0 → 0.16.0

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 (247) hide show
  1. package/dist/agent-state.d.ts +20 -0
  2. package/dist/agent-state.d.ts.map +1 -1
  3. package/dist/agent-state.js +36 -0
  4. package/dist/build-identity.json +12 -4
  5. package/dist/cli/commands.js +187 -4
  6. package/dist/cli/publish-engine.js +116 -16
  7. package/dist/collection.d.ts.map +1 -1
  8. package/dist/collection.js +3 -0
  9. package/dist/create/build-identity.json +12 -4
  10. package/dist/create/managed-account.js +93 -35
  11. package/dist/create/package-versions.js +1 -1
  12. package/dist/create/server-source/Cargo.lock +6 -509
  13. package/dist/create/server-source/Cargo.toml +2 -13
  14. package/dist/create/server-source/crates/feltdb-client/Cargo.toml +1 -1
  15. package/dist/create/server-source/crates/feltdb-server/Cargo.toml +1 -1
  16. package/dist/create/server-source/crates/feltdb-server/src/main.rs +255 -12
  17. package/dist/create/server-source/crates/feltdb-wasm/Cargo.toml +1 -1
  18. package/dist/db.d.ts +11 -1
  19. package/dist/db.d.ts.map +1 -1
  20. package/dist/db.js +15 -2
  21. package/dist/error-codes.d.ts +5 -0
  22. package/dist/error-codes.d.ts.map +1 -1
  23. package/dist/error-codes.js +9 -1
  24. package/dist/http-db.d.ts +16 -0
  25. package/dist/http-db.d.ts.map +1 -1
  26. package/dist/http-db.js +36 -6
  27. package/dist/managed-recovery.d.ts +6 -0
  28. package/dist/managed-recovery.d.ts.map +1 -1
  29. package/dist/managed-recovery.js +9 -0
  30. package/dist/studio-app/assets/{feltdb_wasm-BjM1ylL3.js → feltdb_wasm-DtybUY0q.js} +1 -1
  31. package/dist/studio-app/assets/feltdb_wasm_bg-DsgIUwaB.wasm +0 -0
  32. package/dist/studio-app/assets/index-C4OffsZl.js +37 -0
  33. package/dist/studio-app/index.html +1 -1
  34. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  35. package/dist/wasm/package.json +1 -1
  36. package/dist/workload.d.ts +55 -3
  37. package/dist/workload.d.ts.map +1 -1
  38. package/dist/workload.js +23 -0
  39. package/dist/workspace/workspace-connection.d.ts.map +1 -1
  40. package/dist/workspace/workspace-connection.js +14 -3
  41. package/package.json +1 -1
  42. package/dist/create/server-source/crates/feltdb/Cargo.lock +0 -175
  43. package/dist/create/server-source/crates/feltdb/Cargo.toml +0 -102
  44. package/dist/create/server-source/crates/feltdb/LICENSE +0 -21
  45. package/dist/create/server-source/crates/feltdb/README.md +0 -75
  46. package/dist/create/server-source/crates/feltdb/benches/baselines/gate-13-redux.json +0 -370
  47. package/dist/create/server-source/crates/feltdb/benches/gate13_baseline.rs +0 -589
  48. package/dist/create/server-source/crates/feltdb/benches/gate13_phase_7_1_release_economics.rs +0 -247
  49. package/dist/create/server-source/crates/feltdb/benches/gate_13_redux.rs +0 -440
  50. package/dist/create/server-source/crates/feltdb/benches/gate_13_regression_runner.rs +0 -275
  51. package/dist/create/server-source/crates/feltdb/benches/gate_14a_concurrent_writer_scaling.rs +0 -381
  52. package/dist/create/server-source/crates/feltdb/benches/gate_14a_production_admission_revalidation.rs +0 -467
  53. package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc2_admission_contract.rs +0 -489
  54. package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc_root_cause.rs +0 -281
  55. package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync1_queued_prototype.rs +0 -606
  56. package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync_economics.rs +0 -531
  57. package/dist/create/server-source/crates/feltdb/benches/gate_14b_causal_backlog_scaling.rs +0 -462
  58. package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_contract_test.rs +0 -505
  59. package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_scaling.rs +0 -484
  60. package/dist/create/server-source/crates/feltdb/benches/gate_14d_combined_dimension_scaling.rs +0 -758
  61. package/dist/create/server-source/crates/feltdb/benches/phase_7_1_2_optimization_benchmark.rs +0 -421
  62. package/dist/create/server-source/crates/feltdb/benches/phase_7_1_3_crossover_analysis.rs +0 -329
  63. package/dist/create/server-source/crates/feltdb/src/acceptance_tests.rs +0 -1705
  64. package/dist/create/server-source/crates/feltdb/src/acquisition.rs +0 -286
  65. package/dist/create/server-source/crates/feltdb/src/admission.rs +0 -185
  66. package/dist/create/server-source/crates/feltdb/src/admission_contract_tests.rs +0 -507
  67. package/dist/create/server-source/crates/feltdb/src/adversarial_transport.rs +0 -539
  68. package/dist/create/server-source/crates/feltdb/src/agent_state.rs +0 -320
  69. package/dist/create/server-source/crates/feltdb/src/agent_transition_contract.rs +0 -1545
  70. package/dist/create/server-source/crates/feltdb/src/analytics.rs +0 -521
  71. package/dist/create/server-source/crates/feltdb/src/application.rs +0 -2674
  72. package/dist/create/server-source/crates/feltdb/src/application_runtime.rs +0 -1070
  73. package/dist/create/server-source/crates/feltdb/src/authority.rs +0 -479
  74. package/dist/create/server-source/crates/feltdb/src/authority_failover.rs +0 -847
  75. package/dist/create/server-source/crates/feltdb/src/authorization.rs +0 -1030
  76. package/dist/create/server-source/crates/feltdb/src/authorization_security_tests.rs +0 -1122
  77. package/dist/create/server-source/crates/feltdb/src/bin/feltdb-authority-client.rs +0 -32
  78. package/dist/create/server-source/crates/feltdb/src/bin/feltdb-authority.rs +0 -19
  79. package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +0 -1474
  80. package/dist/create/server-source/crates/feltdb/src/capabilities/mod.rs +0 -8
  81. package/dist/create/server-source/crates/feltdb/src/capabilities/search.rs +0 -418
  82. package/dist/create/server-source/crates/feltdb/src/capabilities/vector.rs +0 -482
  83. package/dist/create/server-source/crates/feltdb/src/capability.rs +0 -903
  84. package/dist/create/server-source/crates/feltdb/src/cardinality_diagnostics.rs +0 -263
  85. package/dist/create/server-source/crates/feltdb/src/cardinality_endpoint.rs +0 -77
  86. package/dist/create/server-source/crates/feltdb/src/causal_backlog_bound.rs +0 -496
  87. package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier.rs +0 -2574
  88. package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier_phase_7_1.rs +0 -212
  89. package/dist/create/server-source/crates/feltdb/src/concurrency_fuzzing.rs +0 -422
  90. package/dist/create/server-source/crates/feltdb/src/consistency_contract.rs +0 -445
  91. package/dist/create/server-source/crates/feltdb/src/content_distribution.rs +0 -465
  92. package/dist/create/server-source/crates/feltdb/src/convergence.rs +0 -634
  93. package/dist/create/server-source/crates/feltdb/src/crash_atomic_boundary.rs +0 -427
  94. package/dist/create/server-source/crates/feltdb/src/crash_injection.rs +0 -376
  95. package/dist/create/server-source/crates/feltdb/src/crash_recovery_tests.rs +0 -365
  96. package/dist/create/server-source/crates/feltdb/src/cron.rs +0 -294
  97. package/dist/create/server-source/crates/feltdb/src/dedup_bound_investigation.rs +0 -483
  98. package/dist/create/server-source/crates/feltdb/src/distributed_indexing.rs +0 -477
  99. package/dist/create/server-source/crates/feltdb/src/distributed_tests.rs +0 -1003
  100. package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +0 -1334
  101. package/dist/create/server-source/crates/feltdb/src/durability_guarantees.rs +0 -368
  102. package/dist/create/server-source/crates/feltdb/src/durable_dedup_set.rs +0 -231
  103. package/dist/create/server-source/crates/feltdb/src/durable_operation_identity.rs +0 -482
  104. package/dist/create/server-source/crates/feltdb/src/durable_operation_log.rs +0 -203
  105. package/dist/create/server-source/crates/feltdb/src/durable_sync.rs +0 -317
  106. package/dist/create/server-source/crates/feltdb/src/equality_index.rs +0 -595
  107. package/dist/create/server-source/crates/feltdb/src/execution.rs +0 -426
  108. package/dist/create/server-source/crates/feltdb/src/in_process_transport.rs +0 -214
  109. package/dist/create/server-source/crates/feltdb/src/indexing.rs +0 -776
  110. package/dist/create/server-source/crates/feltdb/src/lib.rs +0 -7365
  111. package/dist/create/server-source/crates/feltdb/src/managed_cas_tests.rs +0 -234
  112. package/dist/create/server-source/crates/feltdb/src/materialization.rs +0 -184
  113. package/dist/create/server-source/crates/feltdb/src/metrics.rs +0 -266
  114. package/dist/create/server-source/crates/feltdb/src/multi_node_convergence.rs +0 -310
  115. package/dist/create/server-source/crates/feltdb/src/multi_operation_transaction.rs +0 -736
  116. package/dist/create/server-source/crates/feltdb/src/observability.rs +0 -379
  117. package/dist/create/server-source/crates/feltdb/src/operation.rs +0 -290
  118. package/dist/create/server-source/crates/feltdb/src/operation_algebra.rs +0 -439
  119. package/dist/create/server-source/crates/feltdb/src/operation_log.rs +0 -349
  120. package/dist/create/server-source/crates/feltdb/src/p1_application_atomicity.rs +0 -332
  121. package/dist/create/server-source/crates/feltdb/src/p1_atomicity_acceptance.rs +0 -718
  122. package/dist/create/server-source/crates/feltdb/src/partition_reconciliation.rs +0 -487
  123. package/dist/create/server-source/crates/feltdb/src/peer_registry.rs +0 -166
  124. package/dist/create/server-source/crates/feltdb/src/permutation_scheduler.rs +0 -289
  125. package/dist/create/server-source/crates/feltdb/src/persistence_reality.rs +0 -566
  126. package/dist/create/server-source/crates/feltdb/src/phase1b_acceptance.rs +0 -3391
  127. package/dist/create/server-source/crates/feltdb/src/phase1c1_acceptance.rs +0 -203
  128. package/dist/create/server-source/crates/feltdb/src/phase1c2_acceptance.rs +0 -261
  129. package/dist/create/server-source/crates/feltdb/src/phase1c3_acceptance.rs +0 -502
  130. package/dist/create/server-source/crates/feltdb/src/phase1c_atomicity_proof.rs +0 -216
  131. package/dist/create/server-source/crates/feltdb/src/phase5_integration.rs +0 -303
  132. package/dist/create/server-source/crates/feltdb/src/phase5_scenarios.rs +0 -323
  133. package/dist/create/server-source/crates/feltdb/src/phase6_adversarial_scenarios.rs +0 -531
  134. package/dist/create/server-source/crates/feltdb/src/phase6_convergence_validator.rs +0 -406
  135. package/dist/create/server-source/crates/feltdb/src/phase6_persistence.rs +0 -436
  136. package/dist/create/server-source/crates/feltdb/src/phase_1c_real_tcp.rs +0 -387
  137. package/dist/create/server-source/crates/feltdb/src/phase_2a_failures.rs +0 -378
  138. package/dist/create/server-source/crates/feltdb/src/phase_2b_network.rs +0 -359
  139. package/dist/create/server-source/crates/feltdb/src/phase_2c_cascading.rs +0 -372
  140. package/dist/create/server-source/crates/feltdb/src/phase_3_durability.rs +0 -404
  141. package/dist/create/server-source/crates/feltdb/src/phase_4_baseline.rs +0 -376
  142. package/dist/create/server-source/crates/feltdb/src/phase_5_soak.rs +0 -461
  143. package/dist/create/server-source/crates/feltdb/src/policy_evaluation.rs +0 -2125
  144. package/dist/create/server-source/crates/feltdb/src/production_api.rs +0 -418
  145. package/dist/create/server-source/crates/feltdb/src/provenance.rs +0 -207
  146. package/dist/create/server-source/crates/feltdb/src/query_execution_diagnostics.rs +0 -126
  147. package/dist/create/server-source/crates/feltdb/src/query_performance.rs +0 -218
  148. package/dist/create/server-source/crates/feltdb/src/read_basis.rs +0 -257
  149. package/dist/create/server-source/crates/feltdb/src/references.rs +0 -404
  150. package/dist/create/server-source/crates/feltdb/src/replay_fuzzing.rs +0 -401
  151. package/dist/create/server-source/crates/feltdb/src/replica_acknowledgements.rs +0 -501
  152. package/dist/create/server-source/crates/feltdb/src/replica_membership.rs +0 -680
  153. package/dist/create/server-source/crates/feltdb/src/replication_manager.rs +0 -163
  154. package/dist/create/server-source/crates/feltdb/src/replication_protocol.rs +0 -133
  155. package/dist/create/server-source/crates/feltdb/src/routing.rs +0 -409
  156. package/dist/create/server-source/crates/feltdb/src/semantic_decision.rs +0 -2029
  157. package/dist/create/server-source/crates/feltdb/src/semantic_query.rs +0 -599
  158. package/dist/create/server-source/crates/feltdb/src/sharding.rs +0 -549
  159. package/dist/create/server-source/crates/feltdb/src/state_conflict_contract.rs +0 -516
  160. package/dist/create/server-source/crates/feltdb/src/state_contract.rs +0 -6003
  161. package/dist/create/server-source/crates/feltdb/src/state_diff_contract.rs +0 -222
  162. package/dist/create/server-source/crates/feltdb/src/state_facade.rs +0 -320
  163. package/dist/create/server-source/crates/feltdb/src/state_hash.rs +0 -291
  164. package/dist/create/server-source/crates/feltdb/src/state_model.rs +0 -4158
  165. package/dist/create/server-source/crates/feltdb/src/state_transition_store.rs +0 -379
  166. package/dist/create/server-source/crates/feltdb/src/state_trigger.rs +0 -673
  167. package/dist/create/server-source/crates/feltdb/src/storage.rs +0 -273
  168. package/dist/create/server-source/crates/feltdb/src/submission.rs +0 -471
  169. package/dist/create/server-source/crates/feltdb/src/sync.rs +0 -495
  170. package/dist/create/server-source/crates/feltdb/src/sync_contract.rs +0 -822
  171. package/dist/create/server-source/crates/feltdb/src/tcp_transport.rs +0 -433
  172. package/dist/create/server-source/crates/feltdb/src/transaction_api.rs +0 -462
  173. package/dist/create/server-source/crates/feltdb/src/transaction_invariants.rs +0 -965
  174. package/dist/create/server-source/crates/feltdb/src/transaction_preconditions.rs +0 -1120
  175. package/dist/create/server-source/crates/feltdb/src/transactions.rs +0 -643
  176. package/dist/create/server-source/crates/feltdb/src/trigger.rs +0 -390
  177. package/dist/create/server-source/crates/feltdb/src/trigger_contract.rs +0 -749
  178. package/dist/create/server-source/crates/feltdb/src/versioned_object_substrate.rs +0 -708
  179. package/dist/create/server-source/crates/feltdb/src/worker_mesh.rs +0 -1269
  180. package/dist/create/server-source/crates/feltdb/src/workflow.rs +0 -713
  181. package/dist/create/server-source/crates/feltdb/src/workflow_acceptance_tests.rs +0 -510
  182. package/dist/create/server-source/crates/feltdb/src/workflow_integration.rs +0 -354
  183. package/dist/create/server-source/crates/feltdb/src/workflow_runtime.rs +0 -594
  184. package/dist/create/server-source/crates/feltdb/src/workload.rs +0 -4222
  185. package/dist/create/server-source/crates/feltdb/src/workload_diagnostics.rs +0 -456
  186. package/dist/create/server-source/crates/feltdb/tests/agent_state_native.rs +0 -1188
  187. package/dist/create/server-source/crates/feltdb/tests/agent_transition_contract_conformance.rs +0 -2884
  188. package/dist/create/server-source/crates/feltdb/tests/authority_process.rs +0 -297
  189. package/dist/create/server-source/crates/feltdb/tests/authority_transaction_identity.rs +0 -534
  190. package/dist/create/server-source/crates/feltdb/tests/bounded_read_contract.rs +0 -132
  191. package/dist/create/server-source/crates/feltdb/tests/branching_evidence.rs +0 -299
  192. package/dist/create/server-source/crates/feltdb/tests/common/mod.rs +0 -96
  193. package/dist/create/server-source/crates/feltdb/tests/compaction_stall_contract.rs +0 -272
  194. package/dist/create/server-source/crates/feltdb/tests/crash_durability_contract.rs +0 -467
  195. package/dist/create/server-source/crates/feltdb/tests/current_revision_authority_evidence.rs +0 -309
  196. package/dist/create/server-source/crates/feltdb/tests/durable_backup_contract.rs +0 -445
  197. package/dist/create/server-source/crates/feltdb/tests/durable_corruption_contract.rs +0 -518
  198. package/dist/create/server-source/crates/feltdb/tests/durable_format_compatibility.rs +0 -392
  199. package/dist/create/server-source/crates/feltdb/tests/feltdb_state_boundary_tests.rs +0 -850
  200. package/dist/create/server-source/crates/feltdb/tests/fixtures/agent_transition_corpus.json +0 -23340
  201. package/dist/create/server-source/crates/feltdb/tests/fixtures/state_conflict_contract_corpus.json +0 -1916
  202. package/dist/create/server-source/crates/feltdb/tests/fixtures/state_diff_contract_corpus.json +0 -1878
  203. package/dist/create/server-source/crates/feltdb/tests/fixtures/trigger_contract_corpus.json +0 -1862
  204. package/dist/create/server-source/crates/feltdb/tests/generalized_version_control_evidence.rs +0 -123
  205. package/dist/create/server-source/crates/feltdb/tests/generalized_version_control_substrate_completion.rs +0 -299
  206. package/dist/create/server-source/crates/feltdb/tests/local_process_ownership.rs +0 -69
  207. package/dist/create/server-source/crates/feltdb/tests/managed_incident_regression.rs +0 -191
  208. package/dist/create/server-source/crates/feltdb/tests/operational_health_contract.rs +0 -278
  209. package/dist/create/server-source/crates/feltdb/tests/pr34_query_collection.rs +0 -234
  210. package/dist/create/server-source/crates/feltdb/tests/pr35_equality_index.rs +0 -947
  211. package/dist/create/server-source/crates/feltdb/tests/pr7_self_authorization_proof.rs +0 -404
  212. package/dist/create/server-source/crates/feltdb/tests/pr8_vocabulary_assessment.rs +0 -916
  213. package/dist/create/server-source/crates/feltdb/tests/pr9_phase2_boundary_tests.rs +0 -1045
  214. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3a_path_a_tests.rs +0 -347
  215. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_authorized_mutations.rs +0 -361
  216. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_role_based_authorization.rs +0 -330
  217. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_simple_auth_delete.rs +0 -93
  218. package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_team_delete_role_authorization.rs +0 -622
  219. package/dist/create/server-source/crates/feltdb/tests/pr9_teams_role_based_access.rs +0 -517
  220. package/dist/create/server-source/crates/feltdb/tests/production_certification.rs +0 -1153
  221. package/dist/create/server-source/crates/feltdb/tests/production_contract.rs +0 -771
  222. package/dist/create/server-source/crates/feltdb/tests/production_readiness_contract.rs +0 -1383
  223. package/dist/create/server-source/crates/feltdb/tests/reconciliation_application.rs +0 -868
  224. package/dist/create/server-source/crates/feltdb/tests/reconciliation_wire_format_evidence.rs +0 -221
  225. package/dist/create/server-source/crates/feltdb/tests/replicated_history_contract.rs +0 -417
  226. package/dist/create/server-source/crates/feltdb/tests/resource_scoped_revisions.rs +0 -338
  227. package/dist/create/server-source/crates/feltdb/tests/revision_identity_contract.rs +0 -1039
  228. package/dist/create/server-source/crates/feltdb/tests/revision_model_decision.rs +0 -739
  229. package/dist/create/server-source/crates/feltdb/tests/revision_retention_boundary_evidence.rs +0 -452
  230. package/dist/create/server-source/crates/feltdb/tests/saas_authorization_integration.rs +0 -81
  231. package/dist/create/server-source/crates/feltdb/tests/saas_invitation_lifecycle.rs +0 -438
  232. package/dist/create/server-source/crates/feltdb/tests/semantic_decision.rs +0 -1165
  233. package/dist/create/server-source/crates/feltdb/tests/semantic_query.rs +0 -767
  234. package/dist/create/server-source/crates/feltdb/tests/semantic_query_contract.rs +0 -363
  235. package/dist/create/server-source/crates/feltdb/tests/state_conflict_contract_conformance.rs +0 -1799
  236. package/dist/create/server-source/crates/feltdb/tests/state_diff_contract_conformance.rs +0 -1316
  237. package/dist/create/server-source/crates/feltdb/tests/state_model_integration.rs +0 -358
  238. package/dist/create/server-source/crates/feltdb/tests/state_persistence_integration.rs +0 -365
  239. package/dist/create/server-source/crates/feltdb/tests/state_ref_authority.rs +0 -918
  240. package/dist/create/server-source/crates/feltdb/tests/state_store_boundary_evidence.rs +0 -299
  241. package/dist/create/server-source/crates/feltdb/tests/storage_independent_versioned_object_substrate.rs +0 -328
  242. package/dist/create/server-source/crates/feltdb/tests/sync_divergence_evidence.rs +0 -255
  243. package/dist/create/server-source/crates/feltdb/tests/three_way_input_boundary_evidence.rs +0 -249
  244. package/dist/create/server-source/crates/feltdb/tests/trigger_contract_conformance.rs +0 -994
  245. package/dist/create/server-source/crates/feltdb/tests/workload_envelope_contract.rs +0 -484
  246. package/dist/studio-app/assets/feltdb_wasm_bg-TseJn2Ax.wasm +0 -0
  247. package/dist/studio-app/assets/index-1wd0uKua.js +0 -30
@@ -1,126 +0,0 @@
1
- //! Test instrumentation for the collection read paths a bounded query can take.
2
- //!
3
- //! PR33 attributed sustained-workload degradation to bounded queries cloning an
4
- //! entire collection under the state mutex before predicate, ordering and limit
5
- //! were applied. PR34 removes that clone, and a benchmark alone cannot prove a
6
- //! clone is gone: a faster number is evidence of speed, not of mechanism.
7
- //!
8
- //! These counters therefore record *which traversal a read used*, so a test can
9
- //! assert that a bounded query never entered `FeltDb::list_collection`. They
10
- //! are process-global, monotonic, carry no record data, and are not part of the
11
- //! query contract: nothing in the query path reads them, and no query result
12
- //! depends on them. The HTTP surface only exposes them when a server is started
13
- //! with `FELTDB_QUERY_DIAGNOSTICS=1`.
14
- //!
15
- //! PR35 extends them with execution attribution. An index is an optimization, so
16
- //! "the query got faster" is not evidence that it was used; these counters say
17
- //! which execution a query actually took, how many candidates the index
18
- //! produced, and how many records the predicate had to evaluate. That last
19
- //! figure is the one the PR35 claim rests on: for a selective indexed query it
20
- //! must track the candidate count rather than the collection size.
21
-
22
- use std::sync::atomic::{AtomicU64, Ordering};
23
-
24
- static FULL_COLLECTION_MATERIALIZATIONS: AtomicU64 = AtomicU64::new(0);
25
- static FULL_COLLECTION_RECORDS_CLONED: AtomicU64 = AtomicU64::new(0);
26
- static COLLECTION_SCANS: AtomicU64 = AtomicU64::new(0);
27
- static SCAN_RECORDS_VISITED: AtomicU64 = AtomicU64::new(0);
28
- static SCAN_RECORDS_MATERIALIZED: AtomicU64 = AtomicU64::new(0);
29
- static QUERIES_TOTAL: AtomicU64 = AtomicU64::new(0);
30
- static QUERIES_SCAN: AtomicU64 = AtomicU64::new(0);
31
- static QUERIES_INDEXED: AtomicU64 = AtomicU64::new(0);
32
- static INDEX_HITS: AtomicU64 = AtomicU64::new(0);
33
- static INDEX_MISSES: AtomicU64 = AtomicU64::new(0);
34
- static INDEX_CANDIDATES_EXAMINED: AtomicU64 = AtomicU64::new(0);
35
- static RECORDS_PREDICATE_EVALUATED: AtomicU64 = AtomicU64::new(0);
36
-
37
- /// A point-in-time reading of the collection read counters.
38
- #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
39
- pub struct QueryExecutionCounters {
40
- /// Calls to `FeltDb::list_collection`, which clones a whole collection.
41
- pub full_collection_materializations: u64,
42
- /// Records cloned by those calls.
43
- pub full_collection_records_cloned: u64,
44
- /// Calls to `FeltDb::query_collection`, which evaluates borrowed records.
45
- pub collection_scans: u64,
46
- /// Records a scan predicate observed, borrowed rather than cloned.
47
- pub scan_records_visited: u64,
48
- /// Records a scan actually cloned, which is at most the matching set.
49
- pub scan_records_materialized: u64,
50
- /// Collection reads that executed a query: `queries_scan + queries_indexed`.
51
- pub queries_total: u64,
52
- /// Queries answered by evaluating the predicate over the whole collection.
53
- pub queries_scan: u64,
54
- /// Queries answered from equality-index candidates.
55
- pub queries_indexed: u64,
56
- /// Queries for which at least one condition had an applicable index.
57
- pub index_hits: u64,
58
- /// Queries for which no condition had an applicable index, which fall back.
59
- pub index_misses: u64,
60
- /// Candidate record keys the index produced, after intersection.
61
- pub index_candidates_examined: u64,
62
- /// Records the predicate was actually evaluated against, on either path.
63
- /// For a selective indexed query this tracks the candidate count; for a scan
64
- /// it is the collection size.
65
- pub records_predicate_evaluated: u64,
66
- }
67
-
68
- pub(crate) fn record_full_materialization(records: usize) {
69
- FULL_COLLECTION_MATERIALIZATIONS.fetch_add(1, Ordering::Relaxed);
70
- FULL_COLLECTION_RECORDS_CLONED.fetch_add(records as u64, Ordering::Relaxed);
71
- }
72
-
73
- pub(crate) fn record_scan(visited: usize, materialized: usize) {
74
- COLLECTION_SCANS.fetch_add(1, Ordering::Relaxed);
75
- SCAN_RECORDS_VISITED.fetch_add(visited as u64, Ordering::Relaxed);
76
- SCAN_RECORDS_MATERIALIZED.fetch_add(materialized as u64, Ordering::Relaxed);
77
- QUERIES_TOTAL.fetch_add(1, Ordering::Relaxed);
78
- QUERIES_SCAN.fetch_add(1, Ordering::Relaxed);
79
- // A scan evaluates the predicate against every record it visits. This is
80
- // the O(N) figure PR35 exists to reduce, recorded on the same counter the
81
- // indexed path reports to, so the two are directly comparable.
82
- RECORDS_PREDICATE_EVALUATED.fetch_add(visited as u64, Ordering::Relaxed);
83
- }
84
-
85
- /// A query for which no condition had an applicable index, so it falls back.
86
- ///
87
- /// This deliberately does not advance `queries_total`: the scan the caller is
88
- /// about to run records the query itself, and counting it here would report
89
- /// every fallback twice.
90
- pub(crate) fn record_index_miss() {
91
- INDEX_MISSES.fetch_add(1, Ordering::Relaxed);
92
- }
93
-
94
- /// A query answered from index candidates.
95
- ///
96
- /// `examined` is the candidate set after intersection, `evaluated` the records
97
- /// the predicate actually ran against, and `materialized` the matching set that
98
- /// was cloned. `evaluated` can be below `examined` only if an index entry has no
99
- /// record behind it, which would be a maintenance defect; the gap is visible
100
- /// here rather than hidden.
101
- pub(crate) fn record_indexed_query(examined: usize, evaluated: usize, materialized: usize) {
102
- QUERIES_TOTAL.fetch_add(1, Ordering::Relaxed);
103
- QUERIES_INDEXED.fetch_add(1, Ordering::Relaxed);
104
- INDEX_HITS.fetch_add(1, Ordering::Relaxed);
105
- INDEX_CANDIDATES_EXAMINED.fetch_add(examined as u64, Ordering::Relaxed);
106
- RECORDS_PREDICATE_EVALUATED.fetch_add(evaluated as u64, Ordering::Relaxed);
107
- SCAN_RECORDS_MATERIALIZED.fetch_add(materialized as u64, Ordering::Relaxed);
108
- }
109
-
110
- /// Read the counters. Monotonic since process start, so tests compare deltas.
111
- pub fn counters() -> QueryExecutionCounters {
112
- QueryExecutionCounters {
113
- full_collection_materializations: FULL_COLLECTION_MATERIALIZATIONS.load(Ordering::Relaxed),
114
- full_collection_records_cloned: FULL_COLLECTION_RECORDS_CLONED.load(Ordering::Relaxed),
115
- collection_scans: COLLECTION_SCANS.load(Ordering::Relaxed),
116
- scan_records_visited: SCAN_RECORDS_VISITED.load(Ordering::Relaxed),
117
- scan_records_materialized: SCAN_RECORDS_MATERIALIZED.load(Ordering::Relaxed),
118
- queries_total: QUERIES_TOTAL.load(Ordering::Relaxed),
119
- queries_scan: QUERIES_SCAN.load(Ordering::Relaxed),
120
- queries_indexed: QUERIES_INDEXED.load(Ordering::Relaxed),
121
- index_hits: INDEX_HITS.load(Ordering::Relaxed),
122
- index_misses: INDEX_MISSES.load(Ordering::Relaxed),
123
- index_candidates_examined: INDEX_CANDIDATES_EXAMINED.load(Ordering::Relaxed),
124
- records_predicate_evaluated: RECORDS_PREDICATE_EVALUATED.load(Ordering::Relaxed),
125
- }
126
- }
@@ -1,218 +0,0 @@
1
- /// Query Performance Tracking & Latency Contracts
2
- ///
3
- /// Manages query performance benchmarks and latency SLAs:
4
- /// - Query latency tracking (p50, p95, p99)
5
- /// - Latency contract enforcement
6
- /// - Performance degradation detection
7
- /// - Query optimization recommendations
8
- use serde::{Deserialize, Serialize};
9
- use std::collections::HashMap;
10
- use std::time::{Duration, Instant};
11
-
12
- #[derive(Debug, Clone, Serialize, Deserialize)]
13
- pub struct LatencyContract {
14
- pub query_type: String,
15
- pub p50_target_us: u64,
16
- pub p95_target_us: u64,
17
- pub p99_target_us: u64,
18
- }
19
-
20
- #[derive(Debug, Clone, Serialize, Deserialize)]
21
- pub struct QueryMetric {
22
- pub query_type: String,
23
- pub duration_us: u64,
24
- pub timestamp: u64,
25
- pub index_name: String,
26
- pub result_count: usize,
27
- }
28
-
29
- #[derive(Debug, Clone, Serialize, Deserialize)]
30
- pub struct QueryLatencyStats {
31
- pub query_type: String,
32
- pub count: u64,
33
- pub p50_us: u64,
34
- pub p95_us: u64,
35
- pub p99_us: u64,
36
- pub min_us: u64,
37
- pub max_us: u64,
38
- pub avg_us: u64,
39
- }
40
-
41
- #[derive(Debug, Clone)]
42
- struct QueryTimer {
43
- start: Instant,
44
- }
45
-
46
- impl QueryTimer {
47
- fn new() -> Self {
48
- QueryTimer {
49
- start: Instant::now(),
50
- }
51
- }
52
-
53
- fn elapsed_us(&self) -> u64 {
54
- self.start.elapsed().as_micros() as u64
55
- }
56
- }
57
-
58
- pub struct QueryPerformanceTracker {
59
- contracts: HashMap<String, LatencyContract>,
60
- metrics: Vec<QueryMetric>,
61
- violations: Vec<String>,
62
- }
63
-
64
- impl QueryPerformanceTracker {
65
- pub fn new() -> Self {
66
- QueryPerformanceTracker {
67
- contracts: HashMap::new(),
68
- metrics: Vec::new(),
69
- violations: Vec::new(),
70
- }
71
- }
72
-
73
- pub fn register_contract(&mut self, contract: LatencyContract) {
74
- self.contracts.insert(contract.query_type.clone(), contract);
75
- }
76
-
77
- pub fn start_timer(&self) -> QueryTimer {
78
- QueryTimer::new()
79
- }
80
-
81
- pub fn record_query(
82
- &mut self,
83
- query_type: String,
84
- index_name: String,
85
- result_count: usize,
86
- duration_us: u64,
87
- ) {
88
- let metric = QueryMetric {
89
- query_type: query_type.clone(),
90
- duration_us,
91
- timestamp: std::time::SystemTime::now()
92
- .duration_since(std::time::UNIX_EPOCH)
93
- .unwrap_or_default()
94
- .as_secs(),
95
- index_name,
96
- result_count,
97
- };
98
-
99
- if let Some(contract) = self.contracts.get(&query_type) {
100
- if duration_us > contract.p99_target_us {
101
- self.violations.push(format!(
102
- "Query {} violated p99 contract: {} us > {} us",
103
- query_type, duration_us, contract.p99_target_us
104
- ));
105
- }
106
- }
107
-
108
- self.metrics.push(metric);
109
- }
110
-
111
- pub fn get_stats(&self, query_type: &str) -> Option<QueryLatencyStats> {
112
- let relevant: Vec<&QueryMetric> = self
113
- .metrics
114
- .iter()
115
- .filter(|m| m.query_type == query_type)
116
- .collect();
117
-
118
- if relevant.is_empty() {
119
- return None;
120
- }
121
-
122
- let mut durations: Vec<u64> = relevant.iter().map(|m| m.duration_us).collect();
123
- durations.sort();
124
-
125
- let count = durations.len() as u64;
126
- let sum: u64 = durations.iter().sum();
127
- let avg = sum / count;
128
-
129
- let p50_idx = (count / 2) as usize;
130
- let p95_idx = ((count * 95) / 100) as usize;
131
- let p99_idx = ((count * 99) / 100) as usize;
132
-
133
- Some(QueryLatencyStats {
134
- query_type: query_type.to_string(),
135
- count,
136
- p50_us: durations.get(p50_idx).copied().unwrap_or(0),
137
- p95_us: durations.get(p95_idx).copied().unwrap_or(0),
138
- p99_us: durations.get(p99_idx).copied().unwrap_or(0),
139
- min_us: *durations.first().unwrap_or(&0),
140
- max_us: *durations.last().unwrap_or(&0),
141
- avg_us: avg,
142
- })
143
- }
144
-
145
- pub fn get_violations(&self) -> Vec<String> {
146
- self.violations.clone()
147
- }
148
-
149
- pub fn clear_violations(&mut self) {
150
- self.violations.clear();
151
- }
152
-
153
- pub fn export_metrics_csv(&self) -> String {
154
- let mut csv = String::from("timestamp,query_type,duration_us,index_name,result_count\n");
155
- for metric in &self.metrics {
156
- csv.push_str(&format!(
157
- "{},{},{},{},{}\n",
158
- metric.timestamp,
159
- metric.query_type,
160
- metric.duration_us,
161
- metric.index_name,
162
- metric.result_count
163
- ));
164
- }
165
- csv
166
- }
167
- }
168
-
169
- impl Default for QueryPerformanceTracker {
170
- fn default() -> Self {
171
- Self::new()
172
- }
173
- }
174
-
175
- #[cfg(test)]
176
- mod tests {
177
- use super::*;
178
-
179
- #[test]
180
- fn test_latency_contract() {
181
- let mut tracker = QueryPerformanceTracker::new();
182
- tracker.register_contract(LatencyContract {
183
- query_type: "index_lookup".to_string(),
184
- p50_target_us: 100,
185
- p95_target_us: 500,
186
- p99_target_us: 1000,
187
- });
188
-
189
- let timer = tracker.start_timer();
190
- std::thread::sleep(Duration::from_micros(50));
191
- let elapsed = timer.elapsed_us();
192
- // A sleep lasts at least as long as asked, and on a loaded machine
193
- // arbitrarily longer, so only the lower bound is a property.
194
- assert!(elapsed >= 50, "timer measured {elapsed}us for a 50us sleep");
195
-
196
- tracker.record_query("index_lookup".to_string(), "idx_1".to_string(), 10, elapsed);
197
-
198
- let stats = tracker.get_stats("index_lookup").unwrap();
199
- assert_eq!(stats.count, 1);
200
- assert_eq!(stats.p50_us, elapsed);
201
- }
202
-
203
- #[test]
204
- fn test_violation_detection() {
205
- let mut tracker = QueryPerformanceTracker::new();
206
- tracker.register_contract(LatencyContract {
207
- query_type: "slow_query".to_string(),
208
- p50_target_us: 100,
209
- p95_target_us: 200,
210
- p99_target_us: 500,
211
- });
212
-
213
- tracker.record_query("slow_query".to_string(), "idx_1".to_string(), 100, 600);
214
-
215
- let violations = tracker.get_violations();
216
- assert_eq!(violations.len(), 1);
217
- }
218
- }
@@ -1,257 +0,0 @@
1
- //! Read-basis fences: commit only if the state a decision read is unchanged.
2
- //!
3
- //! ```text
4
- //! basis = read_basis(records, predicates) -- one token, under the lock
5
- //! ... decide ...
6
- //! commit fenced by basis -- re-read under the commit lock
7
- //! unchanged -> commit
8
- //! changed -> PreconditionFailed(Fence), ZERO writes
9
- //! ```
10
- //!
11
- //! The fence reads stored rows, not bookkeeping a writer maintains, so it holds
12
- //! whichever write path changed them. Only the named records and the named
13
- //! collections' matching rows are read: everything else is outside the fence
14
- //! and never conflicts.
15
-
16
- #[cfg(test)]
17
- mod tests {
18
- use crate::{
19
- AtomicMutation, FeltDb, FlowError, PreconditionFailure, ReadBasis, ReadCondition,
20
- ReadLayout, ReadPredicate, ReadRecord, ReadSet,
21
- };
22
- use serde_json::json;
23
- use tempfile::TempDir;
24
-
25
- fn db(dir: &TempDir) -> FeltDb {
26
- FeltDb::open(dir.path().join("app.log")).expect("open")
27
- }
28
-
29
- fn set(collection: &str, id: &str, value: serde_json::Value) -> AtomicMutation {
30
- AtomicMutation {
31
- capability: collection.to_string(),
32
- key: format!("{collection}:{id}"),
33
- value: Some(value),
34
- }
35
- }
36
-
37
- fn delete(collection: &str, id: &str) -> AtomicMutation {
38
- AtomicMutation {
39
- capability: collection.to_string(),
40
- key: format!("{collection}:{id}"),
41
- value: None,
42
- }
43
- }
44
-
45
- fn write(db: &FeltDb, id: &str, mutations: &[AtomicMutation]) {
46
- db.apply_atomic_transaction(id, None, &[], mutations, None)
47
- .expect("write commits");
48
- }
49
-
50
- fn reads() -> ReadSet {
51
- ReadSet {
52
- records: vec![ReadRecord {
53
- collection: "A".into(),
54
- id: "a1".into(),
55
- }],
56
- predicates: vec![ReadPredicate {
57
- collection: "B".into(),
58
- conditions: vec![ReadCondition {
59
- field: "a".into(),
60
- eq: json!("a1"),
61
- }],
62
- }],
63
- }
64
- }
65
-
66
- fn seed(db: &FeltDb) {
67
- write(
68
- db,
69
- "seed",
70
- &[
71
- set("A", "a1", json!({ "id": "a1", "n": 1 })),
72
- set("B", "b1", json!({ "id": "b1", "a": "a1" })),
73
- set("B", "b2", json!({ "id": "b2", "a": "a2" })),
74
- ],
75
- );
76
- }
77
-
78
- fn fenced(db: &FeltDb, id: &str, basis: &ReadBasis) -> Result<crate::AtomicCommit, FlowError> {
79
- db.apply_atomic_transaction_fenced(
80
- id,
81
- None,
82
- None,
83
- &[],
84
- &[],
85
- std::slice::from_ref(basis),
86
- &[set("Z", id, json!({ "id": id }))],
87
- None,
88
- )
89
- }
90
-
91
- fn is_fence_conflict(result: Result<crate::AtomicCommit, FlowError>) -> bool {
92
- matches!(result, Err(FlowError::PreconditionFailed(failure)) if matches!(*failure, PreconditionFailure::Fence { .. }))
93
- }
94
-
95
- #[test]
96
- fn an_unchanged_basis_commits_and_a_changed_one_commits_nothing() {
97
- let dir = TempDir::new().unwrap();
98
- let db = db(&dir);
99
- seed(&db);
100
- let basis = db.read_basis(&reads()).unwrap();
101
- assert!(fenced(&db, "z1", &basis).is_ok());
102
- write(&db, "raw", &[set("A", "a1", json!({ "id": "a1", "n": 2 }))]);
103
- assert!(is_fence_conflict(fenced(&db, "z2", &basis)));
104
- assert!(
105
- db.get_value("Z:z2").unwrap().is_none(),
106
- "a refused transaction writes nothing"
107
- );
108
- }
109
-
110
- #[test]
111
- fn records_entering_or_leaving_a_predicate_conflict_and_others_do_not() {
112
- let dir = TempDir::new().unwrap();
113
- let db = db(&dir);
114
- seed(&db);
115
- let basis = db.read_basis(&reads()).unwrap();
116
- write(
117
- &db,
118
- "outside",
119
- &[
120
- set("B", "b3", json!({ "id": "b3", "a": "a9" })),
121
- set("C", "c1", json!({ "id": "c1" })),
122
- ],
123
- );
124
- assert!(
125
- fenced(&db, "z1", &basis).is_ok(),
126
- "writes outside the read set never conflict"
127
- );
128
-
129
- write(
130
- &db,
131
- "enter",
132
- &[set("B", "b4", json!({ "id": "b4", "a": "a1" }))],
133
- );
134
- assert!(is_fence_conflict(fenced(&db, "z2", &basis)));
135
-
136
- let basis = db.read_basis(&reads()).unwrap();
137
- write(
138
- &db,
139
- "leave",
140
- &[set("B", "b1", json!({ "id": "b1", "a": "a2" }))],
141
- );
142
- assert!(is_fence_conflict(fenced(&db, "z3", &basis)));
143
- }
144
-
145
- #[test]
146
- fn delete_and_recreate_with_different_content_conflicts() {
147
- let dir = TempDir::new().unwrap();
148
- let db = db(&dir);
149
- seed(&db);
150
- let basis = db.read_basis(&reads()).unwrap();
151
- write(&db, "delete", &[delete("A", "a1")]);
152
- write(
153
- &db,
154
- "recreate",
155
- &[set("A", "a1", json!({ "id": "a1", "n": 7 }))],
156
- );
157
- assert!(is_fence_conflict(fenced(&db, "z1", &basis)));
158
- }
159
-
160
- #[test]
161
- fn tokens_are_deterministic_and_survive_restart() {
162
- let dir = TempDir::new().unwrap();
163
- let basis = {
164
- let db = db(&dir);
165
- seed(&db);
166
- let first = db.read_basis(&reads()).unwrap();
167
- let mut shuffled = reads();
168
- shuffled.records.push(ReadRecord {
169
- collection: "A".into(),
170
- id: "a1".into(),
171
- });
172
- assert_eq!(
173
- first,
174
- db.read_basis(&shuffled).unwrap(),
175
- "normalised: duplicates do not matter"
176
- );
177
- first
178
- };
179
- let db = db(&dir);
180
- assert_eq!(db.read_basis(&reads()).unwrap().token, basis.token);
181
- assert!(fenced(&db, "z1", &basis).is_ok());
182
- }
183
-
184
- #[test]
185
- fn invalid_and_foreign_bases_are_refused_as_invalid_not_as_conflicts() {
186
- let dir = TempDir::new().unwrap();
187
- let db = db(&dir);
188
- seed(&db);
189
- assert!(db.read_basis(&ReadSet::default()).is_err());
190
- let mut foreign = db.read_basis(&reads()).unwrap();
191
- foreign.token = format!("fb1:{}", "0".repeat(64));
192
- let result = fenced(&db, "z1", &foreign);
193
- assert!(
194
- matches!(result, Err(FlowError::CapabilityError(ref message)) if message.starts_with("INVALID_READ_SET:"))
195
- );
196
- }
197
-
198
- #[test]
199
- fn namespace_bases_read_namespace_rows_and_are_scoped_to_their_namespace() {
200
- let dir = TempDir::new().unwrap();
201
- let db = db(&dir);
202
- let ns = ReadLayout::Namespace("tenant-a".into());
203
- let row = |collection: &str, id: &str, value: serde_json::Value| AtomicMutation {
204
- capability: format!("tenant-a:{collection}"),
205
- key: id.to_string(),
206
- value: Some(value),
207
- };
208
- write(
209
- &db,
210
- "seed",
211
- &[
212
- row("A", "a1", json!({ "id": "a1", "n": 1 })),
213
- row("B", "b1", json!({ "id": "b1", "a": "a1" })),
214
- ],
215
- );
216
- let basis = db.read_basis_in(&reads(), &ns).unwrap();
217
- assert!(basis.token.starts_with(&ns.token_prefix()));
218
- let commit = |id: &str, layout: &ReadLayout, basis: &ReadBasis| {
219
- db.apply_atomic_transaction_fenced_in(
220
- id,
221
- None,
222
- None,
223
- &[],
224
- &[],
225
- layout,
226
- std::slice::from_ref(basis),
227
- &[row("Z", id, json!({ "id": id }))],
228
- None,
229
- )
230
- };
231
- let invalid = |result: Result<crate::AtomicCommit, FlowError>| matches!(result, Err(FlowError::CapabilityError(ref message)) if message.starts_with("INVALID_READ_SET:"));
232
- // A token from another scope is invalid, never compared.
233
- assert!(invalid(commit("z0", &ReadLayout::Direct, &basis)));
234
- assert!(invalid(commit(
235
- "z0",
236
- &ReadLayout::Namespace("tenant-b".into()),
237
- &basis
238
- )));
239
- let direct = db.read_basis(&reads()).unwrap();
240
- assert!(invalid(commit("z0", &ns, &direct)));
241
- // Direct-layout writes to the same names are outside the namespace.
242
- write(
243
- &db,
244
- "direct",
245
- &[set("A", "a1", json!({ "id": "a1", "n": 9 }))],
246
- );
247
- assert!(commit("z1", &ns, &basis).is_ok());
248
- // A namespace write the basis read refuses the commit.
249
- write(
250
- &db,
251
- "raw",
252
- &[row("B", "b9", json!({ "id": "b9", "a": "a1" }))],
253
- );
254
- let result = commit("z2", &ns, &basis);
255
- assert!(is_fence_conflict(result));
256
- }
257
- }