lex-synapse 0.4.13 → 0.4.14
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac485ed070081893c396ca551525535a381c7dd906f481768697978644611c81
|
|
4
|
+
data.tar.gz: fa1d81ddeaf2d7193b5aee2f5145077c30c6bfb9f3be70b6b943e6605af70ea0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abbe160b11aac0d146b2fdfbddde252f9a74e85fccceba0ac9c09a155d2f181ad58e928e4fc0a423b2aaa01ec181b35721bc7b7ceb268f0d5297ba1f5ba0c776
|
|
7
|
+
data.tar.gz: c3859b52b5edb5a68ccb21fd5866acf7a6a4a2ded6dd0cbc40e37f2a0b0cf195e37c04115ae7b892bc2b2e027798c51a04b18bcddbde8c0ecdfd492f9269a955
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.14] - 2026-06-01
|
|
4
|
+
### Fixed
|
|
5
|
+
- Homeostasis actor: convert raw signal counts to signals/minute for correct spike/drought comparison; batch all updates in a single DB transaction
|
|
6
|
+
- Evaluate runner: prevent double confidence adjustment when validation fails (`run_transform` already adjusts)
|
|
7
|
+
- Revert mutation: use unique version (`synapse.version + 1`) instead of `restored_version` to avoid version collision
|
|
8
|
+
|
|
3
9
|
## [0.4.13] - 2026-05-07
|
|
4
10
|
### Fixed
|
|
5
11
|
- `Homeostasis` actor: replace per-synapse `signals_dataset.count` with a single batched `GROUP BY` query to eliminate N+1 pool contention that caused `Sequel::PoolTimeout` on Postgres
|
|
@@ -18,35 +18,49 @@ module Legion
|
|
|
18
18
|
return results unless defined?(Legion::Extensions::Synapse::Data::Model::Synapse)
|
|
19
19
|
|
|
20
20
|
cutoff = Time.now - 60
|
|
21
|
+
window_seconds = 60.0
|
|
22
|
+
signal_model = Legion::Extensions::Synapse::Data::Model::SynapseSignal
|
|
23
|
+
synapse_model = Legion::Extensions::Synapse::Data::Model::Synapse
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
# Single query: count signals per synapse in the last 60s window
|
|
26
|
+
signal_counts = signal_model.where { created_at > cutoff }
|
|
27
|
+
.group_and_count(:synapse_id)
|
|
28
|
+
.as_hash(:synapse_id, :count)
|
|
26
29
|
|
|
30
|
+
# Fetch only active synapses with a nonzero baseline — eager-load to avoid N+1
|
|
31
|
+
active_synapses = synapse_model.where(status: 'active')
|
|
32
|
+
.where { baseline_throughput > 0 } # rubocop:disable Style/NumericPredicate
|
|
33
|
+
.all
|
|
27
34
|
return results if active_synapses.empty?
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.where { created_at > cutoff }
|
|
32
|
-
.group_and_count(:synapse_id)
|
|
33
|
-
.as_hash(:synapse_id, :count)
|
|
36
|
+
# Collect updates in memory, then apply in a single batch to avoid connection churn
|
|
37
|
+
updates = []
|
|
34
38
|
|
|
35
39
|
active_synapses.each do |synapse|
|
|
36
40
|
baseline = synapse.baseline_throughput
|
|
37
|
-
|
|
41
|
+
# Convert raw count in the window to signals/minute for apples-to-apples comparison
|
|
42
|
+
current = (signal_counts.fetch(synapse.id, 0).to_f / window_seconds) * 60.0
|
|
38
43
|
|
|
39
|
-
if Helpers::Homeostasis.spike?(current, baseline, duration_seconds:
|
|
44
|
+
if Helpers::Homeostasis.spike?(current, baseline, duration_seconds: window_seconds)
|
|
40
45
|
results[:spikes] += 1
|
|
41
|
-
elsif Helpers::Homeostasis.drought?(current, baseline, silent_seconds:
|
|
46
|
+
elsif Helpers::Homeostasis.drought?(current, baseline, silent_seconds: window_seconds)
|
|
42
47
|
results[:droughts] += 1
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
new_baseline = Helpers::Homeostasis.update_baseline(baseline, current)
|
|
46
|
-
synapse.
|
|
51
|
+
updates << { synapse_id: synapse.id, baseline_throughput: new_baseline }
|
|
47
52
|
results[:updated] += 1
|
|
48
53
|
end
|
|
49
54
|
|
|
55
|
+
# Batch-update all baselines in a single transaction
|
|
56
|
+
unless updates.empty?
|
|
57
|
+
synapse_model.db.transaction do
|
|
58
|
+
updates.each do |u|
|
|
59
|
+
synapse_model.where(id: u[:synapse_id]).update(baseline_throughput: u[:baseline_throughput])
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
50
64
|
results
|
|
51
65
|
end
|
|
52
66
|
end
|
|
@@ -40,10 +40,15 @@ module Legion
|
|
|
40
40
|
# Step 3: Record signal
|
|
41
41
|
record_signal(synapse, attention_result[:passed], transform_result[:success], elapsed)
|
|
42
42
|
|
|
43
|
-
# Step 4: Adjust confidence
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
# Step 4: Adjust confidence (skip if run_transform already penalized for validation failure)
|
|
44
|
+
if transform_result[:validation_failure]
|
|
45
|
+
# run_transform already adjusted confidence; reload to get the updated value
|
|
46
|
+
new_confidence = synapse.confidence
|
|
47
|
+
else
|
|
48
|
+
event = transform_result[:success] ? :success : :failure
|
|
49
|
+
new_confidence = Helpers::Confidence.adjust(synapse.confidence, event)
|
|
50
|
+
synapse.update(confidence: new_confidence)
|
|
51
|
+
end
|
|
47
52
|
|
|
48
53
|
# Step 5: Generate proposals if autonomous
|
|
49
54
|
if Helpers::Confidence.can_self_modify?(new_confidence) && Helpers::Proposals.reactive?
|
|
@@ -100,7 +105,7 @@ module Legion
|
|
|
100
105
|
else
|
|
101
106
|
new_conf = Helpers::Confidence.adjust(synapse.confidence, :validation_failure)
|
|
102
107
|
synapse.update(confidence: new_conf)
|
|
103
|
-
{ success: false, result: payload, error: result[:errors] }
|
|
108
|
+
{ success: false, result: payload, error: result[:errors], validation_failure: true }
|
|
104
109
|
end
|
|
105
110
|
end
|
|
106
111
|
|
|
@@ -28,6 +28,7 @@ module Legion
|
|
|
28
28
|
|
|
29
29
|
restored_version = mutation_version - 1
|
|
30
30
|
before_state = Legion::JSON.load(mutation.before_state)
|
|
31
|
+
revert_version = synapse.version + 1
|
|
31
32
|
synapse.update(
|
|
32
33
|
attention: before_state[:attention],
|
|
33
34
|
transform: before_state[:transform],
|
|
@@ -40,10 +41,10 @@ module Legion
|
|
|
40
41
|
# Mark the reverted mutation
|
|
41
42
|
mutation.update(outcome: 'reverted')
|
|
42
43
|
|
|
43
|
-
# Record the revert as a new mutation
|
|
44
|
+
# Record the revert as a new mutation (uses a unique version to avoid collision)
|
|
44
45
|
Data::Model::SynapseMutation.create(
|
|
45
46
|
synapse_id: synapse.id,
|
|
46
|
-
version:
|
|
47
|
+
version: revert_version,
|
|
47
48
|
mutation_type: 'confidence_changed',
|
|
48
49
|
before_state: mutation.after_state,
|
|
49
50
|
after_state: mutation.before_state,
|