@feltdb/core 0.4.11 → 0.4.13

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 (164) hide show
  1. package/dist/cli/commands.js +5 -2
  2. package/dist/cli/index.js +1 -1
  3. package/dist/create/cli.js +16 -1
  4. package/dist/create/create.js +30 -16
  5. package/dist/create/docker-compose-generator.js +48 -9
  6. package/dist/create/package-versions.js +1 -1
  7. package/dist/create/server-source/Cargo.lock +2238 -0
  8. package/dist/create/server-source/Cargo.toml +7 -0
  9. package/dist/create/server-source/crates/feltdb/Cargo.lock +175 -0
  10. package/dist/create/server-source/crates/feltdb/Cargo.toml +79 -0
  11. package/dist/create/server-source/crates/feltdb/benches/baselines/gate-13-redux.json +370 -0
  12. package/dist/create/server-source/crates/feltdb/benches/gate13_baseline.rs +589 -0
  13. package/dist/create/server-source/crates/feltdb/benches/gate13_phase_7_1_release_economics.rs +259 -0
  14. package/dist/create/server-source/crates/feltdb/benches/gate_13_redux.rs +446 -0
  15. package/dist/create/server-source/crates/feltdb/benches/gate_13_regression_runner.rs +272 -0
  16. package/dist/create/server-source/crates/feltdb/benches/gate_14a_concurrent_writer_scaling.rs +378 -0
  17. package/dist/create/server-source/crates/feltdb/benches/gate_14a_production_admission_revalidation.rs +414 -0
  18. package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc2_admission_contract.rs +486 -0
  19. package/dist/create/server-source/crates/feltdb/benches/gate_14a_rc_root_cause.rs +273 -0
  20. package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync1_queued_prototype.rs +587 -0
  21. package/dist/create/server-source/crates/feltdb/benches/gate_14a_sync_economics.rs +513 -0
  22. package/dist/create/server-source/crates/feltdb/benches/gate_14b_causal_backlog_scaling.rs +395 -0
  23. package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_contract_test.rs +469 -0
  24. package/dist/create/server-source/crates/feltdb/benches/gate_14c_replication_scaling.rs +409 -0
  25. package/dist/create/server-source/crates/feltdb/benches/gate_14d_combined_dimension_scaling.rs +627 -0
  26. package/dist/create/server-source/crates/feltdb/benches/phase_7_1_2_optimization_benchmark.rs +383 -0
  27. package/dist/create/server-source/crates/feltdb/benches/phase_7_1_3_crossover_analysis.rs +298 -0
  28. package/dist/create/server-source/crates/feltdb/src/acceptance_tests.rs +1698 -0
  29. package/dist/create/server-source/crates/feltdb/src/acquisition.rs +286 -0
  30. package/dist/create/server-source/crates/feltdb/src/admission.rs +192 -0
  31. package/dist/create/server-source/crates/feltdb/src/admission_contract_tests.rs +477 -0
  32. package/dist/create/server-source/crates/feltdb/src/adversarial_transport.rs +566 -0
  33. package/dist/create/server-source/crates/feltdb/src/analytics.rs +475 -0
  34. package/dist/create/server-source/crates/feltdb/src/application.rs +2244 -0
  35. package/dist/create/server-source/crates/feltdb/src/application_runtime.rs +1070 -0
  36. package/dist/create/server-source/crates/feltdb/src/authorization.rs +1030 -0
  37. package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +266 -0
  38. package/dist/create/server-source/crates/feltdb/src/capabilities/mod.rs +8 -0
  39. package/dist/create/server-source/crates/feltdb/src/capabilities/search.rs +418 -0
  40. package/dist/create/server-source/crates/feltdb/src/capabilities/vector.rs +482 -0
  41. package/dist/create/server-source/crates/feltdb/src/capability.rs +903 -0
  42. package/dist/create/server-source/crates/feltdb/src/cardinality_diagnostics.rs +261 -0
  43. package/dist/create/server-source/crates/feltdb/src/cardinality_endpoint.rs +78 -0
  44. package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier.rs +2214 -0
  45. package/dist/create/server-source/crates/feltdb/src/causal_dependency_barrier_phase_7_1.rs +194 -0
  46. package/dist/create/server-source/crates/feltdb/src/concurrency_fuzzing.rs +427 -0
  47. package/dist/create/server-source/crates/feltdb/src/consistency_contract.rs +453 -0
  48. package/dist/create/server-source/crates/feltdb/src/content_distribution.rs +465 -0
  49. package/dist/create/server-source/crates/feltdb/src/convergence.rs +618 -0
  50. package/dist/create/server-source/crates/feltdb/src/crash_atomic_boundary.rs +418 -0
  51. package/dist/create/server-source/crates/feltdb/src/crash_injection.rs +380 -0
  52. package/dist/create/server-source/crates/feltdb/src/crash_recovery_tests.rs +362 -0
  53. package/dist/create/server-source/crates/feltdb/src/cron.rs +294 -0
  54. package/dist/create/server-source/crates/feltdb/src/distributed_indexing.rs +474 -0
  55. package/dist/create/server-source/crates/feltdb/src/distributed_tests.rs +1003 -0
  56. package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +536 -0
  57. package/dist/create/server-source/crates/feltdb/src/durability_guarantees.rs +364 -0
  58. package/dist/create/server-source/crates/feltdb/src/durable_dedup_set.rs +235 -0
  59. package/dist/create/server-source/crates/feltdb/src/durable_operation_log.rs +207 -0
  60. package/dist/create/server-source/crates/feltdb/src/durable_sync.rs +316 -0
  61. package/dist/create/server-source/crates/feltdb/src/execution.rs +426 -0
  62. package/dist/create/server-source/crates/feltdb/src/in_process_transport.rs +219 -0
  63. package/dist/create/server-source/crates/feltdb/src/indexing.rs +779 -0
  64. package/dist/create/server-source/crates/feltdb/src/lib.rs +2838 -0
  65. package/dist/create/server-source/crates/feltdb/src/materialization.rs +184 -0
  66. package/dist/create/server-source/crates/feltdb/src/metrics.rs +267 -0
  67. package/dist/create/server-source/crates/feltdb/src/multi_node_convergence.rs +311 -0
  68. package/dist/create/server-source/crates/feltdb/src/observability.rs +366 -0
  69. package/dist/create/server-source/crates/feltdb/src/operation.rs +251 -0
  70. package/dist/create/server-source/crates/feltdb/src/operation_algebra.rs +438 -0
  71. package/dist/create/server-source/crates/feltdb/src/operation_log.rs +344 -0
  72. package/dist/create/server-source/crates/feltdb/src/partition_reconciliation.rs +477 -0
  73. package/dist/create/server-source/crates/feltdb/src/peer_registry.rs +166 -0
  74. package/dist/create/server-source/crates/feltdb/src/permutation_scheduler.rs +261 -0
  75. package/dist/create/server-source/crates/feltdb/src/persistence_reality.rs +560 -0
  76. package/dist/create/server-source/crates/feltdb/src/phase1b_acceptance.rs +3226 -0
  77. package/dist/create/server-source/crates/feltdb/src/phase1c1_acceptance.rs +201 -0
  78. package/dist/create/server-source/crates/feltdb/src/phase1c2_acceptance.rs +263 -0
  79. package/dist/create/server-source/crates/feltdb/src/phase1c3_acceptance.rs +484 -0
  80. package/dist/create/server-source/crates/feltdb/src/phase1c_atomicity_proof.rs +216 -0
  81. package/dist/create/server-source/crates/feltdb/src/phase5_integration.rs +281 -0
  82. package/dist/create/server-source/crates/feltdb/src/phase5_scenarios.rs +323 -0
  83. package/dist/create/server-source/crates/feltdb/src/phase6_adversarial_scenarios.rs +573 -0
  84. package/dist/create/server-source/crates/feltdb/src/phase6_convergence_validator.rs +404 -0
  85. package/dist/create/server-source/crates/feltdb/src/phase6_persistence.rs +418 -0
  86. package/dist/create/server-source/crates/feltdb/src/phase_1c_real_tcp.rs +381 -0
  87. package/dist/create/server-source/crates/feltdb/src/phase_1c_three_node.rs +523 -0
  88. package/dist/create/server-source/crates/feltdb/src/phase_2a_failures.rs +334 -0
  89. package/dist/create/server-source/crates/feltdb/src/phase_2b_network.rs +306 -0
  90. package/dist/create/server-source/crates/feltdb/src/phase_2c_cascading.rs +355 -0
  91. package/dist/create/server-source/crates/feltdb/src/phase_3_durability.rs +395 -0
  92. package/dist/create/server-source/crates/feltdb/src/phase_4_baseline.rs +346 -0
  93. package/dist/create/server-source/crates/feltdb/src/phase_5_soak.rs +430 -0
  94. package/dist/create/server-source/crates/feltdb/src/production_api.rs +400 -0
  95. package/dist/create/server-source/crates/feltdb/src/provenance.rs +207 -0
  96. package/dist/create/server-source/crates/feltdb/src/query_performance.rs +217 -0
  97. package/dist/create/server-source/crates/feltdb/src/references.rs +404 -0
  98. package/dist/create/server-source/crates/feltdb/src/replay_fuzzing.rs +401 -0
  99. package/dist/create/server-source/crates/feltdb/src/replication_manager.rs +160 -0
  100. package/dist/create/server-source/crates/feltdb/src/replication_protocol.rs +132 -0
  101. package/dist/create/server-source/crates/feltdb/src/routing.rs +409 -0
  102. package/dist/create/server-source/crates/feltdb/src/sharding.rs +523 -0
  103. package/dist/create/server-source/crates/feltdb/src/state_contract.rs +3118 -0
  104. package/dist/create/server-source/crates/feltdb/src/state_hash.rs +291 -0
  105. package/dist/create/server-source/crates/feltdb/src/state_transition_store.rs +376 -0
  106. package/dist/create/server-source/crates/feltdb/src/storage.rs +267 -0
  107. package/dist/create/server-source/crates/feltdb/src/submission.rs +477 -0
  108. package/dist/create/server-source/crates/feltdb/src/sync.rs +483 -0
  109. package/dist/create/server-source/crates/feltdb/src/sync_contract.rs +822 -0
  110. package/dist/create/server-source/crates/feltdb/src/tcp_transport.rs +366 -0
  111. package/dist/create/server-source/crates/feltdb/src/transaction_api.rs +473 -0
  112. package/dist/create/server-source/crates/feltdb/src/transaction_invariants.rs +949 -0
  113. package/dist/create/server-source/crates/feltdb/src/transactions.rs +646 -0
  114. package/dist/create/server-source/crates/feltdb/src/trigger.rs +390 -0
  115. package/dist/create/server-source/crates/feltdb/src/worker_mesh.rs +928 -0
  116. package/dist/create/server-source/crates/feltdb/src/workflow.rs +713 -0
  117. package/dist/create/server-source/crates/feltdb/src/workflow_acceptance_tests.rs +510 -0
  118. package/dist/create/server-source/crates/feltdb/src/workflow_integration.rs +354 -0
  119. package/dist/create/server-source/crates/feltdb/src/workflow_runtime.rs +594 -0
  120. package/dist/create/server-source/crates/feltdb/src/workload.rs +1310 -0
  121. package/dist/create/server-source/crates/feltdb-server/Cargo.toml +23 -0
  122. package/dist/create/server-source/crates/feltdb-server/README.md +79 -0
  123. package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +73 -0
  124. package/dist/create/server-source/crates/feltdb-server/src/application_contract.rs +425 -0
  125. package/dist/create/server-source/crates/feltdb-server/src/artifacts.rs +449 -0
  126. package/dist/create/server-source/crates/feltdb-server/src/audit.rs +59 -0
  127. package/dist/create/server-source/crates/feltdb-server/src/auth.rs +308 -0
  128. package/dist/create/server-source/crates/feltdb-server/src/authorization.rs +228 -0
  129. package/dist/create/server-source/crates/feltdb-server/src/backup.rs +416 -0
  130. package/dist/create/server-source/crates/feltdb-server/src/causal.rs +218 -0
  131. package/dist/create/server-source/crates/feltdb-server/src/certification.rs +223 -0
  132. package/dist/create/server-source/crates/feltdb-server/src/clock.rs +132 -0
  133. package/dist/create/server-source/crates/feltdb-server/src/cluster.rs +165 -0
  134. package/dist/create/server-source/crates/feltdb-server/src/connections.rs +1044 -0
  135. package/dist/create/server-source/crates/feltdb-server/src/content.rs +111 -0
  136. package/dist/create/server-source/crates/feltdb-server/src/identity.rs +250 -0
  137. package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +78 -0
  138. package/dist/create/server-source/crates/feltdb-server/src/key_provider.rs +247 -0
  139. package/dist/create/server-source/crates/feltdb-server/src/leases.rs +123 -0
  140. package/dist/create/server-source/crates/feltdb-server/src/lib.rs +25 -0
  141. package/dist/create/server-source/crates/feltdb-server/src/main.rs +8715 -0
  142. package/dist/create/server-source/crates/feltdb-server/src/metrics.rs +97 -0
  143. package/dist/create/server-source/crates/feltdb-server/src/portable_bundle.rs +350 -0
  144. package/dist/create/server-source/crates/feltdb-server/src/principals.rs +510 -0
  145. package/dist/create/server-source/crates/feltdb-server/src/providers.rs +269 -0
  146. package/dist/create/server-source/crates/feltdb-server/src/releases.rs +2563 -0
  147. package/dist/create/server-source/crates/feltdb-server/src/sessions.rs +156 -0
  148. package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +1097 -0
  149. package/dist/create/server-source/crates/feltdb-server/src/versions.rs +264 -0
  150. package/dist/create/server-source/crates/feltdb-wasm/Cargo.toml +31 -0
  151. package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +1086 -0
  152. package/dist/create/server-source/crates/feltdb-wasm/test.db +0 -0
  153. package/dist/flowspec.d.ts +2 -0
  154. package/dist/flowspec.d.ts.map +1 -1
  155. package/dist/flowspec.js +28 -4
  156. package/dist/state-contract.d.ts +7 -1
  157. package/dist/state-contract.d.ts.map +1 -1
  158. package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -1
  159. package/dist/studio/components/index.js +1 -1
  160. package/dist/studio/{components-q43NSTTH.js → components-bHTARBin.js} +160 -89
  161. package/dist/studio/index.js +31 -28
  162. package/dist/studio-app/assets/{index-DZpBoVMp.js → index-BqKquLuU.js} +8 -8
  163. package/dist/studio-app/index.html +1 -1
  164. package/package.json +1 -1
@@ -0,0 +1,269 @@
1
+ use serde::{Deserialize, Serialize};
2
+ use serde_json::Value;
3
+ use std::{
4
+ collections::{BTreeMap, BTreeSet},
5
+ fs,
6
+ path::PathBuf,
7
+ sync::{Arc, RwLock},
8
+ time::{SystemTime, UNIX_EPOCH},
9
+ };
10
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
11
+ #[serde(rename_all = "snake_case")]
12
+ pub enum ProviderType {
13
+ Connection,
14
+ Storage,
15
+ Search,
16
+ Vector,
17
+ Llm,
18
+ Embedding,
19
+ Identity,
20
+ Delivery,
21
+ Worker,
22
+ Execution,
23
+ Scheduler,
24
+ Deployment,
25
+ Observability,
26
+ Ui,
27
+ Workflow,
28
+ Capability,
29
+ Agent,
30
+ }
31
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
32
+ #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
33
+ pub enum ProviderStatus {
34
+ Installed,
35
+ Available,
36
+ Enabled,
37
+ Disabled,
38
+ Revoked,
39
+ UpgradePending,
40
+ Failed,
41
+ }
42
+ #[derive(Debug, Clone, Serialize, Deserialize)]
43
+ pub struct ProviderManifest {
44
+ pub provider_id: String,
45
+ pub namespace: String,
46
+ pub provider_type: ProviderType,
47
+ pub version: String,
48
+ pub feltdb_contract: String,
49
+ pub capabilities: BTreeSet<String>,
50
+ pub permissions: BTreeSet<String>,
51
+ pub environments: BTreeSet<String>,
52
+ pub runtimes: BTreeSet<String>,
53
+ pub dependencies: BTreeMap<String, String>,
54
+ pub configuration_schema: Value,
55
+ pub secret_requirements: Vec<String>,
56
+ pub migration_required: bool,
57
+ pub publisher: String,
58
+ pub package_ref: String,
59
+ pub package_hash: String,
60
+ pub signature: Option<String>,
61
+ }
62
+ #[derive(Debug, Clone, Serialize, Deserialize)]
63
+ pub struct ProviderHealth {
64
+ pub status: String,
65
+ pub ready: bool,
66
+ pub version: String,
67
+ pub last_invocation: Option<u64>,
68
+ pub last_failure: Option<String>,
69
+ }
70
+ #[derive(Debug, Clone, Serialize, Deserialize)]
71
+ pub struct InstalledProvider {
72
+ pub manifest: ProviderManifest,
73
+ pub status: ProviderStatus,
74
+ pub installed_at: u64,
75
+ pub tenant_bindings: BTreeSet<String>,
76
+ pub application_bindings: BTreeSet<String>,
77
+ pub granted_capabilities: BTreeSet<String>,
78
+ pub configuration_revision: Option<String>,
79
+ pub health: ProviderHealth,
80
+ }
81
+ #[derive(Debug, Clone, Serialize, Deserialize)]
82
+ pub struct ProviderExecutionContext {
83
+ pub tenant_id: String,
84
+ pub application_id: String,
85
+ pub provider_id: String,
86
+ pub capabilities: BTreeSet<String>,
87
+ pub resource_scope: String,
88
+ pub workload_id: Option<String>,
89
+ pub deadline: u64,
90
+ pub causal_id: Option<String>,
91
+ }
92
+ #[derive(Debug, Default, Serialize, Deserialize)]
93
+ struct Records {
94
+ providers: BTreeMap<String, InstalledProvider>,
95
+ }
96
+ #[derive(Clone)]
97
+ pub struct ProviderStore {
98
+ path: PathBuf,
99
+ records: Arc<RwLock<Records>>,
100
+ }
101
+ fn now() -> u64 {
102
+ SystemTime::now()
103
+ .duration_since(UNIX_EPOCH)
104
+ .unwrap_or_default()
105
+ .as_secs()
106
+ }
107
+ impl ProviderStore {
108
+ pub fn load(path: impl Into<PathBuf>) -> Result<Self, String> {
109
+ let path = path.into();
110
+ let records = if path.exists() {
111
+ serde_json::from_slice(&fs::read(&path).map_err(|e| e.to_string())?)
112
+ .map_err(|e| e.to_string())?
113
+ } else {
114
+ Records::default()
115
+ };
116
+ Ok(Self {
117
+ path,
118
+ records: Arc::new(RwLock::new(records)),
119
+ })
120
+ }
121
+ fn persist(&self, r: &Records) -> Result<(), String> {
122
+ if let Some(p) = self.path.parent() {
123
+ fs::create_dir_all(p).map_err(|e| e.to_string())?
124
+ }
125
+ let t = self.path.with_extension("tmp");
126
+ fs::write(&t, serde_json::to_vec_pretty(r).map_err(|e| e.to_string())?)
127
+ .map_err(|e| e.to_string())?;
128
+ fs::rename(t, &self.path).map_err(|e| e.to_string())
129
+ }
130
+ pub fn verify(&self, m: &ProviderManifest) -> Result<(), String> {
131
+ if m.provider_id.trim().is_empty() || m.namespace.trim().is_empty() {
132
+ return Err("provider identity is required".into());
133
+ }
134
+ if m.package_hash.is_empty() {
135
+ return Err("provider package hash is required".into());
136
+ }
137
+ if m.signature.is_none() {
138
+ return Err("unsigned provider packages cannot be activated".into());
139
+ }
140
+ if m.feltdb_contract != "1" {
141
+ return Err("incompatible FeltDB provider contract".into());
142
+ }
143
+ Ok(())
144
+ }
145
+ pub fn install(
146
+ &self,
147
+ m: ProviderManifest,
148
+ tenant: Option<String>,
149
+ application: Option<String>,
150
+ ) -> Result<InstalledProvider, String> {
151
+ self.verify(&m)?;
152
+ let mut r = self
153
+ .records
154
+ .write()
155
+ .map_err(|_| "provider store lock poisoned")?;
156
+ if r.providers.contains_key(&m.provider_id) {
157
+ return Err("provider already installed".into());
158
+ }
159
+ let id = m.provider_id.clone();
160
+ let p = InstalledProvider {
161
+ health: ProviderHealth {
162
+ status: "unknown".into(),
163
+ ready: false,
164
+ version: m.version.clone(),
165
+ last_invocation: None,
166
+ last_failure: None,
167
+ },
168
+ manifest: m,
169
+ status: ProviderStatus::Installed,
170
+ installed_at: now(),
171
+ tenant_bindings: tenant.into_iter().collect(),
172
+ application_bindings: application.into_iter().collect(),
173
+ granted_capabilities: BTreeSet::new(),
174
+ configuration_revision: None,
175
+ };
176
+ r.providers.insert(id, p.clone());
177
+ self.persist(&r)?;
178
+ Ok(p)
179
+ }
180
+ pub fn list(&self) -> Vec<InstalledProvider> {
181
+ self.records
182
+ .read()
183
+ .map(|r| r.providers.values().cloned().collect())
184
+ .unwrap_or_default()
185
+ }
186
+ pub fn get(&self, id: &str) -> Option<InstalledProvider> {
187
+ self.records.read().ok()?.providers.get(id).cloned()
188
+ }
189
+ pub fn set_status(
190
+ &self,
191
+ id: &str,
192
+ status: ProviderStatus,
193
+ ) -> Result<InstalledProvider, String> {
194
+ let mut r = self
195
+ .records
196
+ .write()
197
+ .map_err(|_| "provider store lock poisoned")?;
198
+ let p = r.providers.get_mut(id).ok_or("provider not found")?;
199
+ if status == ProviderStatus::Enabled && p.manifest.signature.is_none() {
200
+ return Err("unsigned provider cannot be enabled".into());
201
+ }
202
+ p.status = status;
203
+ p.health.ready = p.status == ProviderStatus::Enabled;
204
+ p.health.status = if p.health.ready {
205
+ "healthy".into()
206
+ } else {
207
+ "unknown".into()
208
+ };
209
+ let out = p.clone();
210
+ self.persist(&r)?;
211
+ Ok(out)
212
+ }
213
+ pub fn health(&self, id: &str) -> Result<ProviderHealth, String> {
214
+ Ok(self.get(id).ok_or("provider not found")?.health)
215
+ }
216
+ pub fn dependencies(&self, id: &str) -> Result<BTreeMap<String, String>, String> {
217
+ Ok(self
218
+ .get(id)
219
+ .ok_or("provider not found")?
220
+ .manifest
221
+ .dependencies)
222
+ }
223
+ }
224
+ #[cfg(test)]
225
+ mod tests {
226
+ use super::*;
227
+ fn manifest() -> ProviderManifest {
228
+ ProviderManifest {
229
+ provider_id: "local.test".into(),
230
+ namespace: "test".into(),
231
+ provider_type: ProviderType::Storage,
232
+ version: "1.0.0".into(),
233
+ feltdb_contract: "1".into(),
234
+ capabilities: ["storage:read".into()].into(),
235
+ permissions: ["artifact:read".into()].into(),
236
+ environments: ["development".into()].into(),
237
+ runtimes: ["wasm".into()].into(),
238
+ dependencies: BTreeMap::new(),
239
+ configuration_schema: serde_json::json!({"type":"object"}),
240
+ secret_requirements: vec![],
241
+ migration_required: false,
242
+ publisher: "test".into(),
243
+ package_ref: "artifact://pkg".into(),
244
+ package_hash: "sha256:pkg".into(),
245
+ signature: Some("sig".into()),
246
+ }
247
+ }
248
+ #[test]
249
+ fn lifecycle_persists_and_unsigned_is_rejected() {
250
+ let path = std::env::temp_dir().join(format!("providers-{}", now()));
251
+ let s = ProviderStore::load(&path).unwrap();
252
+ let p = s
253
+ .install(manifest(), Some("t".into()), Some("a".into()))
254
+ .unwrap();
255
+ assert_eq!(
256
+ s.set_status(&p.manifest.provider_id, ProviderStatus::Enabled)
257
+ .unwrap()
258
+ .status,
259
+ ProviderStatus::Enabled
260
+ );
261
+ assert!(s.set_status("missing", ProviderStatus::Enabled).is_err());
262
+ let mut bad = manifest();
263
+ bad.signature = None;
264
+ assert!(s.install(bad, None, None).is_err());
265
+ let s2 = ProviderStore::load(&path).unwrap();
266
+ assert_eq!(s2.list().len(), 1);
267
+ let _ = fs::remove_file(path);
268
+ }
269
+ }