-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgitnotes.go
More file actions
91 lines (73 loc) · 1.92 KB
/
gitnotes.go
File metadata and controls
91 lines (73 loc) · 1.92 KB
1
2
3
4
5
6
7
8
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package gitnotes
import (
"encoding/json"
"fmt"
"strings"
"github.com/chaoss/ai-detection-action/detection"
)
// metadata represents the JSON metadata section of a git-ai authorship log.
type metadata struct {
SchemaVersion string `json:"schema_version"`
Prompts map[string]promptRecord `json:"prompts"`
}
type promptRecord struct {
AgentID agentID `json:"agent_id"`
}
type agentID struct {
Tool string `json:"tool"`
Model string `json:"model"`
}
type Detector struct{}
func (d *Detector) Name() string { return "gitnotes" }
func (d *Detector) Detect(input detection.Input) []detection.Finding {
if input.Notes == "" {
return nil
}
parts := strings.SplitN(input.Notes, "\n---\n", 2)
if len(parts) != 2 {
return nil
}
attestation := parts[0]
jsonSection := parts[1]
var meta metadata
if err := json.Unmarshal([]byte(jsonSection), &meta); err != nil {
return nil
}
if !strings.HasPrefix(meta.SchemaVersion, "authorship/") {
return nil
}
// Count attributed files from the attestation section
fileCount := 0
for _, line := range strings.Split(attestation, "\n") {
if line == "" {
continue
}
// File paths start at column 0, attestation entries are indented
if !strings.HasPrefix(line, " ") {
fileCount++
}
}
seen := map[string]bool{}
var findings []detection.Finding
for _, prompt := range meta.Prompts {
tool := prompt.AgentID.Tool
if tool == "" || seen[tool] {
continue
}
seen[tool] = true
detail := fmt.Sprintf("git-ai authorship log (refs/notes/ai) attributes code to %s", tool)
if prompt.AgentID.Model != "" {
detail += fmt.Sprintf(" (model: %s)", prompt.AgentID.Model)
}
if fileCount > 0 {
detail += fmt.Sprintf(", %d file(s) attributed", fileCount)
}
findings = append(findings, detection.Finding{
Detector: d.Name(),
Tool: tool,
Confidence: detection.ConfidenceHigh,
Detail: detail,
})
}
return findings
}