fiber_audit 0.2.1 → 0.3.1

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/.fiber-audit.example.yml +7 -8
  3. data/ARCHITECTURE.md +97 -673
  4. data/CHANGELOG.md +52 -0
  5. data/README.md +163 -86
  6. data/lib/fiber_audit/cli.rb +19 -5
  7. data/lib/fiber_audit/configuration.rb +31 -6
  8. data/lib/fiber_audit/operation_semantics.rb +172 -0
  9. data/lib/fiber_audit/operation_vocabulary.rb +2 -1
  10. data/lib/fiber_audit/runtime/active_operations.rb +39 -9
  11. data/lib/fiber_audit/runtime/boot.rb +4 -0
  12. data/lib/fiber_audit/runtime/environment.rb +58 -0
  13. data/lib/fiber_audit/runtime/execution_context.rb +55 -43
  14. data/lib/fiber_audit/runtime/lifecycle.rb +91 -50
  15. data/lib/fiber_audit/runtime/operation_liveness_monitor.rb +282 -0
  16. data/lib/fiber_audit/runtime/operation_liveness_policy.rb +47 -0
  17. data/lib/fiber_audit/runtime/probes/base.rb +27 -4
  18. data/lib/fiber_audit/runtime/probes/subprocess.rb +89 -8
  19. data/lib/fiber_audit/runtime/probes/thread_state.rb +0 -14
  20. data/lib/fiber_audit/runtime/scheduler_evidence_classifier.rb +60 -0
  21. data/lib/fiber_audit/runtime/scheduler_observer.rb +54 -18
  22. data/lib/fiber_audit/runtime/scheduler_snapshot.rb +95 -0
  23. data/lib/fiber_audit/runtime/watchdog.rb +54 -4
  24. data/lib/fiber_audit/runtime.rb +5 -0
  25. data/lib/fiber_audit/static/call_site_extractor.rb +1 -0
  26. data/lib/fiber_audit/static/rules/base.rb +19 -0
  27. data/lib/fiber_audit/static/rules/blocking_subprocess.rb +67 -10
  28. data/lib/fiber_audit/static/rules/direct_socket.rb +54 -19
  29. data/lib/fiber_audit/static/rules/io_select.rb +6 -6
  30. data/lib/fiber_audit/static/rules/net_http_in_request.rb +11 -8
  31. data/lib/fiber_audit/static/rules/synchronization.rb +13 -8
  32. data/lib/fiber_audit/static/rules/thread_current_state.rb +20 -30
  33. data/lib/fiber_audit/static/rules/thread_join.rb +9 -7
  34. data/lib/fiber_audit/version.rb +1 -1
  35. metadata +6 -1
@@ -4,22 +4,72 @@ require_relative 'base'
4
4
  require_relative '../../findings/evidence'
5
5
  require_relative '../../correlation/fingerprint'
6
6
  require_relative '../../findings/finding'
7
+ require_relative '../../operation_semantics'
7
8
  require_relative '../../operation_vocabulary'
8
9
 
9
10
  module FiberAudit
10
11
  module Static
11
12
  module Rules
13
+ # FA1001: Subprocess lifecycle operations that may interfere with
14
+ # the fiber scheduler. Detects subprocess creation, replacement,
15
+ # waiting, detachment, and stream lifecycle operations.
16
+ #
17
+ # Operations are classified into semantic categories:
18
+ # - creation: spawning a new process (info)
19
+ # - replacement: replacing the current process via exec (info)
20
+ # - waiting: blocking waits for subprocess completion (medium)
21
+ # - detach: detaching a subprocess without waiting (info)
22
+ # - stream: subprocess pipe/stream lifecycle via IO.popen (medium)
23
+ #
24
+ # Severity: info for creation/replacement/detach, medium for waits/stream.
25
+ # These are scheduler-cooperation requirements, so execution context does
26
+ # not by itself escalate them to critical.
12
27
  class BlockingSubprocess < Base
13
28
  id 'FA1001'
14
- severity :high
29
+ severity :medium
15
30
  default_confidence :high
16
- description 'Blocking subprocess call in the fiber scheduler path'
31
+ description 'Subprocess lifecycle operations may interfere with the fiber scheduler'
17
32
 
18
33
  TARGETS = OperationVocabulary::FA1001_TARGETS
19
34
  BARE_KERNEL_METHODS = OperationVocabulary::FA1001_KERNEL_METHODS
20
35
 
21
- MESSAGE = 'Subprocess operation may block the thread running the fiber scheduler.'
22
- REMEDIATION = 'Move long-running subprocess work outside the request path, or verify scheduler behaviour under load.'
36
+ OPERATION_CATEGORY = OperationSemantics::FA1001_CATEGORIES
37
+
38
+ # Per-category metadata
39
+ CATEGORY_METADATA = {
40
+ creation: {
41
+ severity: :info,
42
+ title: 'Subprocess creation',
43
+ message: 'Spawning a subprocess may leave background processes that outlive the fiber scheduler session.',
44
+ remediation: 'Track spawned processes or move subprocess creation outside the fiber-scheduled path.'
45
+ },
46
+ replacement: {
47
+ severity: :info,
48
+ title: 'Process replacement',
49
+ message: 'Process replacement via exec replaces the current process image, terminating the fiber scheduler.',
50
+ remediation: 'Avoid exec in fiber-scheduled code; prefer subprocess creation with explicit lifecycle management.'
51
+ },
52
+ waiting: {
53
+ severity: :medium,
54
+ title: 'Subprocess wait',
55
+ message: 'Subprocess waiting requires scheduler process-wait cooperation in a non-blocking Fiber.',
56
+ remediation: 'Verify scheduler process_wait support and runtime progress, ' \
57
+ 'or move waits outside the fiber-scheduled path.'
58
+ },
59
+ detach: {
60
+ severity: :info,
61
+ title: 'Subprocess detach',
62
+ message: 'Detaching a subprocess may leave it unmanaged by the fiber scheduler.',
63
+ remediation: 'Avoid detaching subprocesses in fiber-scheduled code; use explicit lifecycle management.'
64
+ },
65
+ stream: {
66
+ severity: :medium,
67
+ title: 'Subprocess pipe stream',
68
+ message: 'Subprocess pipe I/O requires scheduler cooperation while the stream is open.',
69
+ remediation: 'Verify scheduler-aware I/O and runtime progress on the pipe, ' \
70
+ 'or move pipe operations outside the fiber-scheduled path.'
71
+ }
72
+ }.freeze
23
73
 
24
74
  def analyze(call_sites:)
25
75
  call_sites.filter_map do |site|
@@ -60,11 +110,14 @@ module FiberAudit
60
110
  def build_finding(site, match)
61
111
  operation = "#{match[:constant]}.#{match[:method]}"
62
112
  context = site.execution_context || :unknown
63
- sev = severity_for(self.class.severity, context)
113
+ category = OperationSemantics.resolve(operation).category
114
+ metadata = CATEGORY_METADATA.fetch(category)
115
+ base_severity = metadata[:severity]
116
+ sev = advisory_severity(base_severity)
64
117
 
65
118
  Finding.new(
66
119
  rule_id: self.class.id,
67
- title: 'Blocking subprocess call',
120
+ title: metadata[:title],
68
121
  category: :subprocess,
69
122
  severity: sev,
70
123
  confidence: match[:confidence],
@@ -72,15 +125,19 @@ module FiberAudit
72
125
  symbol: site.enclosing_symbol,
73
126
  operation: operation,
74
127
  execution_context: context,
75
- message: MESSAGE,
128
+ message: metadata[:message],
76
129
  evidence: [
77
130
  Evidence.new(
78
131
  source: :static,
79
- message: "Matched #{operation}",
80
- details: { receiver: match[:constant], method: match[:method] }
132
+ message: "Matched #{operation} (#{category})",
133
+ details: {
134
+ receiver: match[:constant],
135
+ method: match[:method],
136
+ semantic: category
137
+ }
81
138
  )
82
139
  ],
83
- remediation: REMEDIATION
140
+ remediation: metadata[:remediation]
84
141
  )
85
142
  end
86
143
  end
@@ -4,28 +4,51 @@ require_relative 'base'
4
4
  require_relative '../../findings/evidence'
5
5
  require_relative '../../correlation/fingerprint'
6
6
  require_relative '../../findings/finding'
7
+ require_relative '../../operation_semantics'
7
8
  require_relative '../../operation_vocabulary'
8
9
 
9
10
  module FiberAudit
10
11
  module Static
11
12
  module Rules
12
- # FA1006 Detects direct socket creation that may bypass
13
- # scheduler-aware networking and block the scheduler thread.
13
+ # FA1006: Inventory and semantic classification for direct socket constructors.
14
14
  class DirectSocket < Base
15
15
  id 'FA1006'
16
- severity :medium
16
+ severity :low
17
17
  default_confidence :high
18
- description 'Detects direct socket creation that may bypass scheduler-aware networking.'
18
+ description 'Direct socket constructors range from inventory-only allocation to endpoint setup.'
19
19
 
20
- TITLE = 'Direct socket creation'
20
+ TITLE = 'Direct socket construction'
21
21
  CATEGORY = :network
22
-
23
22
  EXACT = OperationVocabulary::FA1006_EXACT
24
-
25
- MESSAGE = 'Direct socket use may bypass scheduler-aware networking ' \
26
- 'and block the scheduler thread.'
27
- REMEDIATION = 'Use scheduler-aware networking APIs or verify the ' \
28
- 'socket operations cooperate with the active Fiber scheduler.'
23
+ CATEGORY_METADATA = {
24
+ socket_allocation: {
25
+ title: 'Direct socket allocation',
26
+ message: 'This constructor is inventory-level socket setup without a client connection; ' \
27
+ 'later accept, connect, address resolution, or I/O may require scheduler cooperation.',
28
+ remediation: 'Treat allocation as inventory and verify scheduler-aware behavior at later ' \
29
+ 'accept, connect, resolution, and I/O calls.'
30
+ },
31
+ socket_resolve_connect: {
32
+ title: 'Direct socket endpoint setup',
33
+ message: 'This constructor may resolve an address and establish a network endpoint, requiring ' \
34
+ 'scheduler cooperation from address-resolution and I/O hooks.',
35
+ remediation: 'Verify address_resolve and scheduler-aware I/O hooks, and confirm runtime progress ' \
36
+ 'for endpoint setup.'
37
+ },
38
+ socket_local_connect: {
39
+ title: 'Direct local-socket connection',
40
+ message: 'This constructor may establish a local socket connection and wait for endpoint progress.',
41
+ remediation: 'Verify runtime progress for local-socket connection and move blocking setup outside ' \
42
+ 'the fiber-scheduled path.'
43
+ },
44
+ socket_constructor_unknown: {
45
+ title: 'Direct socket subclass construction',
46
+ message: 'This IPSocket subclass constructor has unknown allocation/connect semantics and may ' \
47
+ 'require scheduler cooperation.',
48
+ remediation: 'Inspect the subclass constructor and verify scheduler-aware resolution, connection, ' \
49
+ 'and I/O behavior.'
50
+ }
51
+ }.freeze
29
52
 
30
53
  class << self
31
54
  def title = TITLE
@@ -82,27 +105,39 @@ module FiberAudit
82
105
 
83
106
  def build_finding(site, const)
84
107
  operation = "#{const}.new"
85
- ctx = site.execution_context || :unknown
108
+ profile = if EXACT.include?(const)
109
+ OperationSemantics.resolve(operation)
110
+ else
111
+ OperationSemantics.resolve_socket_constructor(operation)
112
+ end
113
+ metadata = CATEGORY_METADATA.fetch(profile.category)
86
114
 
87
115
  Finding.new(
88
116
  rule_id: self.class.id,
89
- title: self.class.title,
117
+ title: metadata.fetch(:title),
90
118
  category: self.class.category,
91
- severity: severity_for(:medium, ctx),
119
+ severity: advisory_severity(:low),
92
120
  confidence: site.confidence,
93
121
  location: site.location,
94
122
  symbol: site.enclosing_symbol,
95
123
  operation: operation,
96
- execution_context: ctx,
97
- message: MESSAGE,
124
+ execution_context: site.execution_context || :unknown,
125
+ message: metadata.fetch(:message),
98
126
  evidence: [
99
127
  Evidence.new(
100
128
  source: 'static_analysis',
101
- message: "Direct socket creation: #{operation}",
102
- details: { receiver_constant: const, method: :new }
129
+ message: "Matched #{operation} (#{profile.category})",
130
+ details: {
131
+ receiver_constant: const,
132
+ method: :new,
133
+ semantic: profile.category,
134
+ wait_possible: profile.wait_possible,
135
+ inventory_only: profile.inventory_only,
136
+ scheduler_capability: profile.scheduler_capability
137
+ }
103
138
  )
104
139
  ],
105
- remediation: REMEDIATION
140
+ remediation: metadata.fetch(:remediation)
106
141
  )
107
142
  end
108
143
  end
@@ -9,19 +9,19 @@ require_relative '../../operation_vocabulary'
9
9
  module FiberAudit
10
10
  module Static
11
11
  module Rules
12
- # FA1005: Detects explicit IO.select calls that may bypass
13
- # scheduler-aware I/O and block the scheduler thread.
12
+ # FA1005: Detects explicit IO.select scheduler-capability requirements.
13
+ # Advisory rule with :medium default.
14
14
  class IOSelect < Base
15
15
  id 'FA1005'
16
16
  severity :medium
17
17
  default_confidence :high
18
- description 'Explicit IO.select call that may bypass scheduler-aware I/O'
18
+ description 'Explicit IO.select requires scheduler io_select cooperation'
19
19
 
20
20
  TITLE = 'Explicit IO.select call'
21
21
  CATEGORY = :blocking_io
22
22
 
23
- MESSAGE = 'IO.select may bypass scheduler-aware I/O and block the thread running the fiber scheduler.'
24
- REMEDIATION = 'Use scheduler-aware I/O APIs or allow the active Fiber scheduler to manage readiness.'
23
+ MESSAGE = 'IO.select requires scheduler io_select support when used from a non-blocking Fiber.'
24
+ REMEDIATION = 'Verify the selected scheduler implements io_select and confirm runtime progress under load.'
25
25
 
26
26
  TARGETS = OperationVocabulary::FA1005_TARGETS
27
27
 
@@ -79,7 +79,7 @@ module FiberAudit
79
79
  rule_id: self.class.id,
80
80
  title: TITLE,
81
81
  category: CATEGORY,
82
- severity: severity_for(:medium, context),
82
+ severity: advisory_severity(:medium),
83
83
  confidence: confidence,
84
84
  location: site.location,
85
85
  symbol: site.enclosing_symbol,
@@ -9,19 +9,22 @@ require_relative '../../operation_vocabulary'
9
9
  module FiberAudit
10
10
  module Static
11
11
  module Rules
12
- # FA1007: Detects blocking HTTP calls in request-like contexts.
12
+ # FA1007: Detects HTTP scheduler-cooperation requirements in request-like contexts.
13
13
  # Targets Net::HTTP.{get,get_response,start,request}, URI.open, OpenURI.open_uri.
14
14
  # Excludes Net::HTTP.get_print. Emits only for request/middleware/websocket/callback.
15
+ #
16
+ # Advisory rule with :medium default, no context ceiling.
15
17
  class NetHTTPInRequest < Base
16
18
  id 'FA1007'
17
- severity :high
19
+ severity :medium
18
20
  default_confidence :high
19
- description 'Blocking HTTP call in request path'
21
+ description 'HTTP calls require scheduler-aware DNS, socket, and TLS cooperation in request contexts'
20
22
 
21
- TITLE = 'Blocking HTTP call in request path'
23
+ TITLE = 'HTTP scheduler-cooperation requirement'
22
24
  CATEGORY = :network
23
- MESSAGE = 'Synchronous HTTP activity in a request-like context may block the thread running the fiber scheduler.'
24
- REMEDIATION = 'Use a scheduler-aware HTTP client, or move outbound HTTP work outside the request path.'
25
+ MESSAGE = 'HTTP activity requires scheduler-aware DNS and I/O cooperation in a non-blocking Fiber.'
26
+ REMEDIATION = 'Verify the selected HTTP/TLS/DNS stack and active scheduler ' \
27
+ 'under load; investigate correlated stalls.'
25
28
 
26
29
  NET_HTTP_METHODS = OperationVocabulary::FA1007_NET_HTTP_METHODS
27
30
  URI_METHODS = OperationVocabulary::FA1007_URI_METHODS
@@ -82,7 +85,7 @@ module FiberAudit
82
85
  def build_finding(site, match)
83
86
  context = site.execution_context
84
87
  sev, conf = if match[:type] == :net_http
85
- [severity_for(:high, context), site.confidence]
88
+ [advisory_severity(:medium), site.confidence]
86
89
  else
87
90
  %i[medium low]
88
91
  end
@@ -101,7 +104,7 @@ module FiberAudit
101
104
  evidence: [
102
105
  FiberAudit::Evidence.new(
103
106
  source: 'static_analysis',
104
- message: "Blocking HTTP call detected: #{match[:operation]}",
107
+ message: "HTTP scheduler-cooperation point: #{match[:operation]}",
105
108
  details: { receiver: site.receiver_constant, method: site.method_name, context: context }
106
109
  )
107
110
  ],
@@ -9,20 +9,24 @@ require_relative '../../operation_vocabulary'
9
9
  module FiberAudit
10
10
  module Static
11
11
  module Rules
12
+ # FA1003: Thread synchronization primitives that may interfere with
13
+ # fiber scheduler cooperation. Advisory rule with :low default.
14
+ #
15
+ # Detects Mutex, ConditionVariable, Monitor, and MonitorMixin
16
+ # synchronization operations. try_lock is treated as :info since
17
+ # it's non-blocking but indicates thread-oriented synchronization.
12
18
  class Synchronization < Base
13
19
  id 'FA1003'
14
- severity :medium
20
+ severity :low
15
21
  default_confidence :high
16
- description 'Thread synchronization primitives that may block the fiber scheduler thread'
22
+ description 'Thread synchronization may interfere with fiber scheduler cooperation'
17
23
 
18
24
  RULE_TITLE = 'Thread synchronization'
19
25
  RULE_CATEGORY = :synchronization
20
26
  TARGETS = OperationVocabulary::FA1003_TARGETS
21
- TRY_LOCK_MSG = 'Mutex.try_lock is non-blocking but may indicate ' \
22
- 'thread-oriented synchronization in fiber-scheduled code.'
23
- NORMAL_MSG = 'Synchronization operation may block the thread running the fiber scheduler.'
24
- REMEDIATION = 'Use scheduler-aware synchronization primitives, or verify ' \
25
- 'contention and scheduler behaviour under load.'
27
+ TRY_LOCK_MSG = 'Mutex#try_lock is non-blocking and identifies a thread-oriented coordination point.'
28
+ NORMAL_MSG = 'Synchronization contention requires scheduler block/unblock cooperation in a non-blocking Fiber.'
29
+ REMEDIATION = 'Verify scheduler coordination and contention behavior under load; investigate correlated stalls.'
26
30
 
27
31
  def analyze(call_sites:)
28
32
  explicit_monitor_mixins = explicit_monitor_mixin_classes(call_sites)
@@ -98,7 +102,8 @@ module FiberAudit
98
102
  def build_finding(site, target, method)
99
103
  try_lock = target == 'Mutex' && method == :try_lock
100
104
  operation = "#{target}##{method}"
101
- severity = try_lock ? :info : severity_for(:medium, site.execution_context)
105
+ # try_lock has fixed :info, no config override
106
+ severity = try_lock ? :info : advisory_severity(:low)
102
107
  confidence = try_lock ? :high : site.confidence
103
108
  message = try_lock ? TRY_LOCK_MSG : NORMAL_MSG
104
109
  evidence = Evidence.new(source: operation, message: message,
@@ -9,27 +9,28 @@ require_relative '../../operation_vocabulary'
9
9
  module FiberAudit
10
10
  module Static
11
11
  module Rules
12
- # Detect thread-variable and Thread.current index state.
12
+ # FA1004: Detect thread-variable state access without inferring stored data.
13
13
  class ThreadCurrentState < Base
14
14
  id 'FA1004'
15
- severity :high
15
+ severity :medium
16
16
  confidence :high
17
- description 'Thread-local state in fiber code may be shared across fibers and leak request-local data'
17
+ description 'Thread-variable access may share mutable state across fibers on one thread'
18
18
 
19
- TITLE = 'Thread-local state in fiber code'
19
+ TITLE = 'Thread-variable access shared across fibers'
20
20
  CATEGORY = :thread_local
21
- MESSAGE = 'Thread-local state may be shared across fibers and leak request-local data.'
22
- REMEDIATION = 'Use fiber-local or framework-provided request-local state instead of Thread thread variables.'
21
+ MESSAGE = 'Thread variables are visible to fibers sharing a thread. This access may expose mutable ' \
22
+ 'state across concurrent work, but static analysis does not establish request-sensitive leakage.'
23
+ REMEDIATION = 'Prefer fiber-local storage (Fiber[:key]) or framework-provided ' \
24
+ 'request-local state over thread_variable_get/set.'
23
25
 
24
26
  THREAD_VARIABLE_METHODS = OperationVocabulary::FA1004_THREAD_VARIABLE_METHODS
25
- INDEX_METHODS = OperationVocabulary::FA1004_INDEX_METHODS
26
27
 
27
28
  def analyze(call_sites:)
28
29
  findings = []
29
30
  call_sites.each do |site|
30
31
  next if skip?(site)
31
32
 
32
- finding = match_thread_variable(site) || match_index_op(site)
33
+ finding = match_thread_variable(site)
33
34
  findings << finding if finding
34
35
  end
35
36
  findings
@@ -68,43 +69,32 @@ module FiberAudit
68
69
 
69
70
  instance_match = site.receiver_constant == 'Thread' && site.receiver_source != 'Thread'
70
71
  current_match = site.receiver_source == 'Thread.current'
71
-
72
72
  return unless instance_match || current_match
73
73
 
74
- build_finding(site, :high, :high, operation(site))
75
- end
76
-
77
- def match_index_op(site)
78
- return unless INDEX_METHODS.include?(site.method_name)
79
- return unless site.receiver_source == 'Thread.current'
80
-
81
- build_finding(site, :medium, :high, operation(site))
74
+ build_finding(site, operation(site))
82
75
  end
83
76
 
84
77
  def operation(site)
85
- if INDEX_METHODS.include?(site.method_name)
86
- "Thread.current.#{site.method_name}"
87
- else
88
- "Thread.#{site.method_name}"
89
- end
78
+ "Thread.#{site.method_name}"
90
79
  end
91
80
 
92
- def build_finding(site, default_sev, conf, operation)
93
- context = site.execution_context
94
- severity = severity_for(default_sev, context)
95
-
81
+ def build_finding(site, operation)
96
82
  Finding.new(
97
83
  rule_id: self.class.id,
98
84
  title: TITLE,
99
85
  category: CATEGORY,
100
- severity: severity,
101
- confidence: conf,
86
+ severity: advisory_severity(:medium),
87
+ confidence: :high,
102
88
  location: site.location,
103
89
  symbol: site.enclosing_symbol,
104
90
  operation: operation,
105
- execution_context: context,
91
+ execution_context: site.execution_context,
106
92
  message: MESSAGE,
107
- evidence: [Evidence.new(source: site.receiver_source, message: "Thread-local access via #{site.method_name}")],
93
+ evidence: [Evidence.new(
94
+ source: site.receiver_source,
95
+ message: "Matched thread-variable access via #{site.method_name}",
96
+ details: { operation: operation, receiver: site.receiver_source }
97
+ )],
108
98
  remediation: REMEDIATION
109
99
  )
110
100
  end
@@ -9,7 +9,7 @@ require_relative '../../operation_vocabulary'
9
9
  module FiberAudit
10
10
  module Static
11
11
  module Rules
12
- # FA1002: Thread#join / Thread#value may block the fiber-scheduler thread.
12
+ # FA1002: Thread#join / Thread#value are scheduler coordination points.
13
13
  #
14
14
  # Matches join/value on Thread instances whose receiver_constant is
15
15
  # 'Thread' but whose receiver_source is not the bare literal 'Thread'.
@@ -20,17 +20,19 @@ module FiberAudit
20
20
  # and workspace-shadowed Thread (checked via workspace or
21
21
  # workspace.semantic_index resolve_constant seam). Adapter errors from
22
22
  # those seams are swallowed — they never raise.
23
+ #
24
+ # Advisory rule: uses advisory_severity (no context ceiling), default :low.
23
25
  class ThreadJoin < Base
24
26
  id 'FA1002'
25
- severity :high
27
+ severity :low
26
28
  confidence :high
27
- description 'Waiting for a thread may block the thread running the fiber scheduler.'
29
+ description 'Thread waits require scheduler block/unblock cooperation'
28
30
 
29
31
  TITLE = 'Thread wait'
30
32
  CATEGORY = :synchronization
31
- MESSAGE = 'Waiting for a thread may block the thread running the fiber scheduler.'
32
- REMEDIATION = 'Replace thread waits with scheduler-aware coordination, ' \
33
- 'or move the work outside the fiber-scheduled path.'
33
+ MESSAGE = 'Thread#join/value requires scheduler block/unblock cooperation in a non-blocking Fiber.'
34
+ REMEDIATION = 'Verify scheduler coordination and runtime progress, ' \
35
+ 'or move the wait outside the fiber-scheduled path.'
34
36
  TARGET_METHODS = OperationVocabulary::FA1002_METHODS
35
37
  CANONICAL_OPS = OperationVocabulary::FA1002_OPERATIONS
36
38
  DIRECT_CLASS_SOURCE = 'Thread'
@@ -73,7 +75,7 @@ module FiberAudit
73
75
  def build_finding(site)
74
76
  loc = site.location
75
77
  op = "Thread.#{site.method_name}"
76
- sev = severity_for(self.class.severity, site.execution_context)
78
+ sev = advisory_severity(self.class.severity)
77
79
  conf = site.receiver_source == 'Thread.current' ? :high : site.confidence
78
80
 
79
81
  Finding.new(
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiberAudit
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiber_audit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - FiberAudit Contributors
@@ -61,6 +61,7 @@ files:
61
61
  - lib/fiber_audit/findings/finding.rb
62
62
  - lib/fiber_audit/findings/location.rb
63
63
  - lib/fiber_audit/findings/severity.rb
64
+ - lib/fiber_audit/operation_semantics.rb
64
65
  - lib/fiber_audit/operation_vocabulary.rb
65
66
  - lib/fiber_audit/project.rb
66
67
  - lib/fiber_audit/reporters/base.rb
@@ -80,6 +81,8 @@ files:
80
81
  - lib/fiber_audit/runtime/lifecycle.rb
81
82
  - lib/fiber_audit/runtime/limits.rb
82
83
  - lib/fiber_audit/runtime/location.rb
84
+ - lib/fiber_audit/runtime/operation_liveness_monitor.rb
85
+ - lib/fiber_audit/runtime/operation_liveness_policy.rb
83
86
  - lib/fiber_audit/runtime/policy.rb
84
87
  - lib/fiber_audit/runtime/probes/base.rb
85
88
  - lib/fiber_audit/runtime/probes/http.rb
@@ -94,7 +97,9 @@ files:
94
97
  - lib/fiber_audit/runtime/recorder.rb
95
98
  - lib/fiber_audit/runtime/redactor.rb
96
99
  - lib/fiber_audit/runtime/sampler.rb
100
+ - lib/fiber_audit/runtime/scheduler_evidence_classifier.rb
97
101
  - lib/fiber_audit/runtime/scheduler_observer.rb
102
+ - lib/fiber_audit/runtime/scheduler_snapshot.rb
98
103
  - lib/fiber_audit/runtime/session.rb
99
104
  - lib/fiber_audit/runtime/supervisor.rb
100
105
  - lib/fiber_audit/runtime/validation.rb