steer.go raw
1 package oracle
2
3 import (
4 "path/filepath"
5 "strings"
6 )
7
8 // WalkWeights converts oracle directives into file weight modifiers for
9 // walk.BuildWeighted. Files whose paths match the oracle's focus keywords
10 // get higher weights, causing them to appear earlier in the walk order.
11 //
12 // The returned map is keyed by relative file path and valued by weight
13 // multiplier (default = 1.0, boosted = 2.0-4.0).
14 func WalkWeights(r *Reading, files []string) map[string]float64 {
15 if r == nil || len(files) == 0 {
16 return nil
17 }
18
19 weights := make(map[string]float64, len(files))
20
21 // Collect all keywords from the domain and changing line focuses.
22 domain := TrigramToDomain(r.OuterTrigram())
23 keywords := DomainKeywords(domain)
24
25 // Build a set of focus terms from directives.
26 var focusTerms []string
27 for _, kw := range keywords {
28 focusTerms = append(focusTerms, strings.ToLower(kw))
29 }
30
31 // Add changing line dimension focuses.
32 for _, lineIdx := range r.ChangingLines() {
33 bit := lineIdx % 3
34 isInner := lineIdx < 3
35 focus := ChangingBitFocus(bit, isInner)
36 for word := range strings.FieldsSeq(strings.ToLower(focus)) {
37 if len(word) > 3 { // skip short words
38 focusTerms = append(focusTerms, word)
39 }
40 }
41 }
42
43 // Score each file by keyword matches in its path.
44 for _, f := range files {
45 lowerPath := strings.ToLower(f)
46 base := strings.ToLower(filepath.Base(f))
47 w := 1.0
48
49 for _, term := range focusTerms {
50 if strings.Contains(lowerPath, term) || strings.Contains(base, term) {
51 w += 1.0
52 }
53 }
54
55 // Style modulation: targeted and reference styles boost test files;
56 // broad style boosts non-test files.
57 style := ADSRToStyle(0)
58 if len(r.Directives) > 0 {
59 style = r.Directives[0].Style
60 }
61 isTest := strings.HasSuffix(base, "_test.go") || strings.Contains(base, "test")
62 switch style {
63 case StyleTargeted, StyleReference:
64 if isTest {
65 w += 0.5
66 }
67 case StyleBroad:
68 if !isTest {
69 w += 0.5
70 }
71 case StyleSynthesis:
72 // Synthesis boosts files that connect packages (main, cmd, etc.).
73 if strings.Contains(lowerPath, "cmd/") || base == "main.go" {
74 w += 1.0
75 }
76 }
77
78 if w > 1.0 {
79 weights[f] = w
80 }
81 }
82
83 return weights
84 }
85
86 // DominantADSRPhase returns the ADSR phase with the highest count.
87 // Used to determine the organism's current lifecycle position for oracle casting.
88 func DominantADSRPhase(counts [4]uint32) uint8 {
89 maxIdx := uint8(0)
90 maxVal := counts[0]
91 for i := uint8(1); i < 4; i++ {
92 if counts[i] > maxVal {
93 maxVal = counts[i]
94 maxIdx = i
95 }
96 }
97 return maxIdx
98 }
99