lex-privatecore 0.1.4 → 0.1.6
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 +4 -4
- data/Gemfile +1 -0
- data/lex-privatecore.gemspec +8 -0
- data/lib/legion/extensions/privatecore/actors/audit_prune.rb +1 -1
- data/lib/legion/extensions/privatecore/runners/embedding_guard.rb +8 -8
- data/lib/legion/extensions/privatecore/runners/privatecore.rb +14 -14
- data/lib/legion/extensions/privatecore/version.rb +1 -1
- data/lib/legion/extensions/privatecore.rb +1 -1
- data/spec/spec_helper.rb +29 -5
- metadata +100 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68cb796e6e99ce901512ecf159fc1b4abf151d59b14d3acd212ec38374ab584c
|
|
4
|
+
data.tar.gz: e780847abcbd06b0f5ffb67dffa96b9cdc1c11c48448b4078b7d3d8bbd0cabca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82b5a79904f3b653de6896c54f603323a2fcf175359acce3d7d98f51329f2879335aea31597f7d694d50c600b3efcd14d6597f9f3eb5623929bd33b112939f4b
|
|
7
|
+
data.tar.gz: 3f7dd3c81e36f114190c6382156b746a937226829c70559a9445b0db58d7ed864c5e77d0f342935dd3905e4ae4170f008f74b0f0ec2f7cd72d3badec11c1f872
|
data/Gemfile
CHANGED
data/lex-privatecore.gemspec
CHANGED
|
@@ -25,4 +25,12 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
Dir.glob('{lib,spec}/**/*') + %w[lex-privatecore.gemspec Gemfile]
|
|
26
26
|
end
|
|
27
27
|
spec.require_paths = ['lib']
|
|
28
|
+
|
|
29
|
+
spec.add_dependency 'legion-cache', '>= 1.3.11'
|
|
30
|
+
spec.add_dependency 'legion-crypt', '>= 1.4.9'
|
|
31
|
+
spec.add_dependency 'legion-data', '>= 1.4.17'
|
|
32
|
+
spec.add_dependency 'legion-json', '>= 1.2.1'
|
|
33
|
+
spec.add_dependency 'legion-logging', '>= 1.3.2'
|
|
34
|
+
spec.add_dependency 'legion-settings', '>= 1.3.14'
|
|
35
|
+
spec.add_dependency 'legion-transport', '>= 1.3.9'
|
|
28
36
|
end
|
|
@@ -6,7 +6,7 @@ module Legion
|
|
|
6
6
|
module Extensions
|
|
7
7
|
module Privatecore
|
|
8
8
|
module Actor
|
|
9
|
-
class AuditPrune < Legion::Extensions::Actors::Every
|
|
9
|
+
class AuditPrune < Legion::Extensions::Actors::Every # rubocop:disable Legion/Extension/EveryActorRequiresTime
|
|
10
10
|
def runner_class
|
|
11
11
|
Legion::Extensions::Privatecore::Runners::Privatecore
|
|
12
12
|
end
|
|
@@ -4,7 +4,7 @@ module Legion
|
|
|
4
4
|
module Extensions
|
|
5
5
|
module Privatecore
|
|
6
6
|
module Runners
|
|
7
|
-
module EmbeddingGuard
|
|
7
|
+
module EmbeddingGuard # rubocop:disable Legion/Extension/RunnerIncludeHelpers
|
|
8
8
|
DEFAULT_ADVERSARIAL_PATTERNS = [
|
|
9
9
|
'ignore previous instructions',
|
|
10
10
|
'you are now',
|
|
@@ -28,13 +28,13 @@ module Legion
|
|
|
28
28
|
effective_patterns = patterns || DEFAULT_ADVERSARIAL_PATTERNS
|
|
29
29
|
|
|
30
30
|
unless defined?(Legion::LLM)
|
|
31
|
-
|
|
31
|
+
log.debug '[privatecore] embedding guard: Legion::LLM unavailable, skipping'
|
|
32
32
|
return { safe: true, max_similarity: 0.0, matched_pattern: nil, details: [], skipped: true }
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
input_vec = embed(input)
|
|
36
36
|
if input_vec.nil?
|
|
37
|
-
|
|
37
|
+
log.warn '[privatecore] embedding guard: failed to embed input'
|
|
38
38
|
return { safe: true, max_similarity: 0.0, matched_pattern: nil, details: [], error: :embed_failed }
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -45,8 +45,8 @@ module Legion
|
|
|
45
45
|
matched = max_sim >= effective_threshold ? max_entry[:pattern] : nil
|
|
46
46
|
safe = matched.nil?
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
log.debug "[privatecore] embedding guard: max_similarity=#{max_sim.round(4)} threshold=#{effective_threshold} safe=#{safe}"
|
|
49
|
+
log.warn "[privatecore] ADVERSARIAL INPUT DETECTED via embedding: #{matched}" unless safe
|
|
50
50
|
|
|
51
51
|
{ safe: safe, max_similarity: max_sim, matched_pattern: matched, details: details }
|
|
52
52
|
end
|
|
@@ -61,7 +61,7 @@ module Legion
|
|
|
61
61
|
private
|
|
62
62
|
|
|
63
63
|
def resolve_threshold(override)
|
|
64
|
-
return override unless override.nil?
|
|
64
|
+
return override unless override.nil? # rubocop:disable Legion/Extension/RunnerReturnHash
|
|
65
65
|
|
|
66
66
|
if defined?(Legion::Settings)
|
|
67
67
|
Legion::Settings.dig(:privatecore, :embedding_guard, :threshold) || 0.85
|
|
@@ -71,9 +71,9 @@ module Legion
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def embed(text)
|
|
74
|
-
Legion::LLM.embed(text)
|
|
74
|
+
Legion::LLM.embed(text) # rubocop:disable Legion/HelperMigration/DirectLlm
|
|
75
75
|
rescue StandardError => e
|
|
76
|
-
|
|
76
|
+
log.debug "[privatecore] embed error: #{e.message}"
|
|
77
77
|
nil
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -5,16 +5,16 @@ module Legion
|
|
|
5
5
|
module Privatecore
|
|
6
6
|
module Runners
|
|
7
7
|
module Privatecore
|
|
8
|
-
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
|
|
9
|
-
Legion::Extensions::Helpers.const_defined?(:Lex)
|
|
8
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
9
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
10
10
|
|
|
11
11
|
def enforce_boundary(text:, direction: :outbound, **)
|
|
12
12
|
case direction
|
|
13
13
|
when :outbound
|
|
14
14
|
pii_found = Helpers::Boundary.contains_pii?(text)
|
|
15
15
|
stripped = Helpers::Boundary.strip_pii(text)
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
log.debug "[privatecore] boundary outbound: length=#{text.length} pii_found=#{pii_found}"
|
|
17
|
+
log.warn '[privatecore] PII stripped from outbound text' if pii_found
|
|
18
18
|
{
|
|
19
19
|
original_length: text.length,
|
|
20
20
|
cleaned: stripped,
|
|
@@ -24,8 +24,8 @@ module Legion
|
|
|
24
24
|
when :inbound
|
|
25
25
|
probe = Helpers::Boundary.detect_probe(text)
|
|
26
26
|
action = probe ? :flag_and_log : :allow
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
log.debug "[privatecore] boundary inbound: probe=#{!probe.nil?} action=#{action}"
|
|
28
|
+
log.warn '[privatecore] PROBE DETECTED in inbound text' if probe
|
|
29
29
|
{
|
|
30
30
|
text: text,
|
|
31
31
|
probe: probe,
|
|
@@ -37,7 +37,7 @@ module Legion
|
|
|
37
37
|
|
|
38
38
|
def check_pii(text:, **)
|
|
39
39
|
has_pii = Helpers::Boundary.contains_pii?(text)
|
|
40
|
-
|
|
40
|
+
log.debug "[privatecore] pii check: contains_pii=#{has_pii}"
|
|
41
41
|
{
|
|
42
42
|
contains_pii: has_pii,
|
|
43
43
|
stripped: Helpers::Boundary.strip_pii(text)
|
|
@@ -46,27 +46,27 @@ module Legion
|
|
|
46
46
|
|
|
47
47
|
def detect_probe(text:, **)
|
|
48
48
|
probe = Helpers::Boundary.detect_probe(text)
|
|
49
|
-
|
|
49
|
+
log.debug "[privatecore] probe check: detected=#{!probe.nil?}"
|
|
50
50
|
Legion::Events.emit('privatecore.probe_detected', text_length: text.length) if probe && defined?(Legion::Events)
|
|
51
51
|
{ probe_detected: probe }
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def erasure_audit(**)
|
|
55
55
|
count = erasure_engine.audit_log.size
|
|
56
|
-
|
|
56
|
+
log.debug "[privatecore] erasure audit: entries=#{count}"
|
|
57
57
|
{ audit_log: erasure_engine.audit_log, count: count }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def prune_audit_log(**)
|
|
61
|
-
|
|
61
|
+
audit = erasure_engine.audit_log
|
|
62
62
|
cap = Helpers::Boundary::MAX_AUDIT_LOG_SIZE
|
|
63
63
|
pruned = 0
|
|
64
|
-
while
|
|
65
|
-
|
|
64
|
+
while audit.size > cap
|
|
65
|
+
audit.shift
|
|
66
66
|
pruned += 1
|
|
67
67
|
end
|
|
68
|
-
|
|
69
|
-
{ pruned: pruned, remaining:
|
|
68
|
+
log.debug "[privatecore] audit prune: pruned=#{pruned} remaining=#{audit.size}"
|
|
69
|
+
{ pruned: pruned, remaining: audit.size }
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
private
|
|
@@ -10,7 +10,7 @@ require 'legion/extensions/privatecore/runners/embedding_guard'
|
|
|
10
10
|
module Legion
|
|
11
11
|
module Extensions
|
|
12
12
|
module Privatecore
|
|
13
|
-
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
13
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core, false
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'bundler/setup'
|
|
4
|
+
require 'legion/logging'
|
|
5
|
+
require 'legion/settings'
|
|
6
|
+
require 'legion/cache/helper'
|
|
7
|
+
require 'legion/crypt/helper'
|
|
8
|
+
require 'legion/data/helper'
|
|
9
|
+
require 'legion/json/helper'
|
|
10
|
+
require 'legion/transport/helper'
|
|
4
11
|
|
|
5
12
|
module Legion
|
|
6
|
-
module
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
module Extensions
|
|
14
|
+
module Helpers
|
|
15
|
+
module Lex
|
|
16
|
+
include Legion::Logging::Helper
|
|
17
|
+
include Legion::Settings::Helper
|
|
18
|
+
include Legion::Cache::Helper
|
|
19
|
+
include Legion::Crypt::Helper
|
|
20
|
+
include Legion::Data::Helper
|
|
21
|
+
include Legion::JSON::Helper
|
|
22
|
+
include Legion::Transport::Helper
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Actors
|
|
27
|
+
class Every
|
|
28
|
+
include Helpers::Lex
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class Once
|
|
32
|
+
include Helpers::Lex
|
|
33
|
+
end
|
|
34
|
+
end
|
|
11
35
|
end
|
|
12
36
|
end
|
|
13
37
|
|
metadata
CHANGED
|
@@ -1,14 +1,112 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-privatecore
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: legion-cache
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 1.3.11
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 1.3.11
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: legion-crypt
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.4.9
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 1.4.9
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: legion-data
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 1.4.17
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 1.4.17
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: legion-json
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 1.2.1
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 1.2.1
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: legion-logging
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 1.3.2
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 1.3.2
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: legion-settings
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: 1.3.14
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: 1.3.14
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: legion-transport
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: 1.3.9
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: 1.3.9
|
|
12
110
|
description: Privacy boundary enforcement and cryptographic erasure for brain-modeled
|
|
13
111
|
agentic AI
|
|
14
112
|
email:
|