9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/rail_verdict/intelligence/context_builder.rb', line 9
def self.build(outcome:, finding_ref:, repository_root: nil)
root = repository_root || outcome.context&.repository_root || Dir.pwd
findings = outcome.findings || []
target = findings.find { |f| f.id == finding_ref || f.fingerprint == finding_ref }
raise ArgumentError, "finding not found: #{finding_ref}" unless target
location = target.location || {}
path = location["path"] || location[:path]
line = location["start_line"] || location[:start_line]
snippets = []
if path
snippet = SourceReader.read_snippet(repository_root: root, path: path, target_line: line)
snippets << snippet if snippet
end
snippets = snippets.first(MAX_FILES)
rails_facts = (outcome, path)
git_slice = (outcome)
comparison_slice = (outcome)
policy_reason = outcome.result&.decision_reasons&.first&.fetch("message", nil) rescue nil
manifest = Manifest.new(
finding_id: target.id,
fingerprint: target.fingerprint,
finding: target.to_schema_h,
snippets: snippets.map { |s| { "path" => s[:path], "content" => sanitize(s[:content]), "truncated" => s[:truncated] } },
rails_facts: rails_facts,
git_slice: git_slice,
comparison_slice: comparison_slice,
policy_reason: policy_reason
)
if manifest.total_bytes > MAX_CONTEXT_BYTES
trimmed = Manifest.new(
finding_id: manifest.finding_id,
fingerprint: manifest.fingerprint,
finding: manifest.finding,
snippets: manifest.snippets.first(1).map { |s| s.merge("content" => s["content"].byteslice(0, 16 * 1024).to_s) },
rails_facts: rails_facts.is_a?(Array) ? rails_facts.first(1) : rails_facts,
git_slice: git_slice,
comparison_slice: comparison_slice,
policy_reason: policy_reason
)
return trimmed
end
manifest
end
|