torusguard 0.9.4 → 1.0.0

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 (44) hide show
  1. package/.torusguard/.manifest.json +15 -10
  2. package/.torusguard/config/torusguard.json +1 -1
  3. package/.torusguard/schemas/memory-context.schema.json +95 -0
  4. package/.torusguard/schemas/memory-event.schema.json +70 -0
  5. package/.torusguard/schemas/memory-pattern.schema.json +65 -0
  6. package/.torusguard/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
  7. package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
  8. package/.torusguard/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
  9. package/.torusguard/scripts/diff_guard.py +71 -11
  10. package/.torusguard/scripts/finding_scorer.py +171 -86
  11. package/.torusguard/scripts/manifest_builder.py +2 -0
  12. package/.torusguard/scripts/memory_engine.py +912 -0
  13. package/.torusguard/scripts/run_manager.py +171 -89
  14. package/.torusguard/skills/torusguard/SKILL.md +12 -7
  15. package/.torusguard/skills/torusguard/bootstrap.py +344 -56
  16. package/.torusguard/skills/torusguard-audit/SKILL.md +25 -25
  17. package/.torusguard/skills/torusguard-harden/SKILL.md +3 -3
  18. package/.torusguard/skills/torusguard-recheck/SKILL.md +3 -3
  19. package/.torusguard/workflows/memory.md +53 -0
  20. package/README.md +12 -2
  21. package/bin/torusguard.js +173 -43
  22. package/package.json +1 -1
  23. package/skills/torusguard/SKILL.md +4 -3
  24. package/skills/torusguard/__pycache__/bootstrap.cpython-311.pyc +0 -0
  25. package/skills/torusguard/bootstrap.py +244 -80
  26. package/skills/torusguard/payload/.manifest.json +15 -10
  27. package/skills/torusguard/payload/config/torusguard.json +1 -1
  28. package/skills/torusguard/payload/schemas/memory-context.schema.json +95 -0
  29. package/skills/torusguard/payload/schemas/memory-event.schema.json +70 -0
  30. package/skills/torusguard/payload/schemas/memory-pattern.schema.json +65 -0
  31. package/skills/torusguard/payload/scripts/diff_guard.py +71 -11
  32. package/skills/torusguard/payload/scripts/finding_scorer.py +171 -86
  33. package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
  34. package/skills/torusguard/payload/scripts/memory_engine.py +912 -0
  35. package/skills/torusguard/payload/scripts/run_manager.py +171 -89
  36. package/skills/torusguard/payload/skills/torusguard/SKILL.md +12 -7
  37. package/skills/torusguard/payload/skills/torusguard/bootstrap.py +344 -56
  38. package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +25 -25
  39. package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +3 -3
  40. package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +3 -3
  41. package/skills/torusguard/payload/workflows/memory.md +53 -0
  42. package/skills/torusguard-audit/SKILL.md +25 -25
  43. package/skills/torusguard-harden/SKILL.md +3 -3
  44. package/skills/torusguard-recheck/SKILL.md +3 -3
@@ -1,86 +1,171 @@
1
- #!/usr/bin/env python3
2
- """
3
- TorusGuard 5-Factor Finding Confidence Scorer
4
- Evaluates finding confidence against the objective 0–100 scoring model.
5
- """
6
-
7
- import sys
8
- import json
9
- import argparse
10
- from typing import Dict, Any, Tuple
11
-
12
- def compute_confidence_score(
13
- evidence_quality: int = 35,
14
- reproduction_success: int = 0,
15
- independent_confirmations: int = 5,
16
- environmental_clarity: int = 15,
17
- manual_review_status: int = 0
18
- ) -> Tuple[int, str, Dict[str, int]]:
19
- """
20
- Computes total score and assigns confidence band.
21
- Max points:
22
- - evidence_quality: 35
23
- - reproduction_success: 25
24
- - independent_confirmations: 15
25
- - environmental_clarity: 15
26
- - manual_review_status: 10
27
- """
28
- eq = min(max(evidence_quality, 0), 35)
29
- rs = min(max(reproduction_success, 0), 25)
30
- ic = min(max(independent_confirmations, 0), 15)
31
- ec = min(max(environmental_clarity, 0), 15)
32
- mr = min(max(manual_review_status, 0), 10)
33
-
34
- total = eq + rs + ic + ec + mr
35
-
36
- if total >= 90:
37
- band = "Confirmed"
38
- elif total >= 70:
39
- band = "High Confidence"
40
- elif total >= 50:
41
- band = "Medium Confidence"
42
- else:
43
- band = "Needs Review"
44
-
45
- factors = {
46
- "evidence_quality": eq,
47
- "reproduction_success": rs,
48
- "independent_confirmations": ic,
49
- "environmental_clarity": ec,
50
- "manual_review_status": mr,
51
- "total_score": total,
52
- "classification_band": band
53
- }
54
- return total, band, factors
55
-
56
-
57
- def main():
58
- parser = argparse.ArgumentParser(description="TorusGuard Confidence Scorer")
59
- parser.add_argument("--eq", type=int, default=35, help="Evidence quality score (0-35)")
60
- parser.add_argument("--rs", type=int, default=0, help="Reproduction success score (0-25)")
61
- parser.add_argument("--ic", type=int, default=5, help="Independent confirmations score (0-15)")
62
- parser.add_argument("--ec", type=int, default=15, help="Environmental clarity score (0-15)")
63
- parser.add_argument("--mr", type=int, default=0, help="Manual review status score (0-10)")
64
- parser.add_argument("--json", action="store_true", help="Output JSON")
65
- args = parser.parse_args()
66
-
67
- total, band, factors = compute_confidence_score(
68
- evidence_quality=args.eq,
69
- reproduction_success=args.rs,
70
- independent_confirmations=args.ic,
71
- environmental_clarity=args.ec,
72
- manual_review_status=args.mr
73
- )
74
-
75
- if args.json:
76
- print(json.dumps(factors, indent=2))
77
- else:
78
- print(f"Total Confidence Score: {total}/100")
79
- print(f"Classification Band: {band}")
80
- print("Factor Breakdown:")
81
- for k, v in factors.items():
82
- if k not in ("total_score", "classification_band"):
83
- print(f" - {k}: {v}")
84
-
85
- if __name__ == "__main__":
86
- main()
1
+ #!/usr/bin/env python3
2
+ """
3
+ TorusGuard Finding Confidence Scorer (v1.0.0)
4
+ Evaluates finding confidence against the objective 0–100 scoring model,
5
+ augmented by persistent memory patterns and false-positive suppression.
6
+ """
7
+
8
+ import sys
9
+ import json
10
+ import argparse
11
+ from pathlib import Path
12
+ from typing import Dict, Any, Tuple, Optional
13
+
14
+
15
+ def compute_memory_boost(
16
+ rule_id: str,
17
+ file_path: Optional[str] = None,
18
+ root_dir: Optional[Path] = None
19
+ ) -> int:
20
+ """
21
+ Query .torusguard/memory/patterns.json to calculate memory confidence modifier:
22
+ - False positive class: -30 (heavily suppressed)
23
+ - Regression watch: +15 (high alert / known recurrence)
24
+ - Recurring fix / Common vulnerability: +10
25
+ - Security idiom: +5
26
+ - Multi-file pattern match bonus: +5
27
+ """
28
+ if not rule_id:
29
+ return 0
30
+
31
+ base = Path(root_dir or Path.cwd()).resolve()
32
+ # Search for .torusguard
33
+ torusguard_dir = base / ".torusguard"
34
+ if not torusguard_dir.exists():
35
+ for parent in base.parents:
36
+ if (parent / ".torusguard").exists():
37
+ torusguard_dir = parent / ".torusguard"
38
+ break
39
+
40
+ patterns_file = torusguard_dir / "memory" / "patterns.json"
41
+ if not patterns_file.exists():
42
+ return 0
43
+
44
+ try:
45
+ with open(patterns_file, "r", encoding="utf-8") as f:
46
+ patterns = json.load(f)
47
+ except Exception:
48
+ return 0
49
+
50
+ boost = 0
51
+ matched_file = False
52
+
53
+ for pat in patterns:
54
+ if pat.get("rule_id") == rule_id:
55
+ ptype = pat.get("pattern_type")
56
+ if ptype == "false_positive_class":
57
+ boost -= 30
58
+ elif ptype == "regression_watch":
59
+ boost += 15
60
+ elif ptype in ("recurring_fix", "common_vulnerability"):
61
+ boost += 10
62
+ elif ptype == "security_idiom":
63
+ boost += 5
64
+
65
+ # File-specific correlation bonus
66
+ if file_path and file_path in pat.get("affected_files", []):
67
+ matched_file = True
68
+
69
+ if matched_file and boost > 0:
70
+ boost += 5
71
+ elif matched_file and boost < 0:
72
+ boost -= 10
73
+
74
+ return boost
75
+
76
+
77
+ def compute_confidence_score(
78
+ evidence_quality: int = 35,
79
+ reproduction_success: int = 0,
80
+ independent_confirmations: int = 5,
81
+ environmental_clarity: int = 15,
82
+ manual_review_status: int = 0,
83
+ memory_boost: int = 0,
84
+ rule_id: Optional[str] = None,
85
+ file_path: Optional[str] = None,
86
+ root_dir: Optional[Path] = None
87
+ ) -> Tuple[int, str, Dict[str, int]]:
88
+ """
89
+ Computes total score and assigns confidence band.
90
+ Max points:
91
+ - evidence_quality: 35
92
+ - reproduction_success: 25
93
+ - independent_confirmations: 15
94
+ - environmental_clarity: 15
95
+ - manual_review_status: 10
96
+ - memory_boost: -30 to +20 (modifier from persistent memory)
97
+ Total is clamped to [0, 100].
98
+ """
99
+ eq = min(max(evidence_quality, 0), 35)
100
+ rs = min(max(reproduction_success, 0), 25)
101
+ ic = min(max(independent_confirmations, 0), 15)
102
+ ec = min(max(environmental_clarity, 0), 15)
103
+ mr = min(max(manual_review_status, 0), 10)
104
+
105
+ # Auto-calculate memory boost if rule_id provided and memory_boost == 0
106
+ eff_mem_boost = memory_boost
107
+ if rule_id and eff_mem_boost == 0:
108
+ eff_mem_boost = compute_memory_boost(rule_id, file_path=file_path, root_dir=root_dir)
109
+
110
+ raw_total = eq + rs + ic + ec + mr + eff_mem_boost
111
+ total = min(max(raw_total, 0), 100)
112
+
113
+ if total >= 90:
114
+ band = "Confirmed"
115
+ elif total >= 70:
116
+ band = "High Confidence"
117
+ elif total >= 50:
118
+ band = "Medium Confidence"
119
+ else:
120
+ band = "Needs Review"
121
+
122
+ factors = {
123
+ "evidence_quality": eq,
124
+ "reproduction_success": rs,
125
+ "independent_confirmations": ic,
126
+ "environmental_clarity": ec,
127
+ "manual_review_status": mr,
128
+ "memory_boost": eff_mem_boost,
129
+ "total_score": total,
130
+ "classification_band": band
131
+ }
132
+ return total, band, factors
133
+
134
+
135
+ def main():
136
+ parser = argparse.ArgumentParser(description="TorusGuard Confidence Scorer")
137
+ parser.add_argument("--eq", type=int, default=35, help="Evidence quality score (0-35)")
138
+ parser.add_argument("--rs", type=int, default=0, help="Reproduction success score (0-25)")
139
+ parser.add_argument("--ic", type=int, default=5, help="Independent confirmations score (0-15)")
140
+ parser.add_argument("--ec", type=int, default=15, help="Environmental clarity score (0-15)")
141
+ parser.add_argument("--mr", type=int, default=0, help="Manual review status score (0-10)")
142
+ parser.add_argument("--memory-boost", type=int, default=0, help="Memory boost score (-30 to +20)")
143
+ parser.add_argument("--rule-id", type=str, help="TorusGuard rule ID for memory pattern matching")
144
+ parser.add_argument("--file", type=str, help="File path for correlation matching")
145
+ parser.add_argument("--json", action="store_true", help="Output JSON")
146
+ args = parser.parse_args()
147
+
148
+ total, band, factors = compute_confidence_score(
149
+ evidence_quality=args.eq,
150
+ reproduction_success=args.rs,
151
+ independent_confirmations=args.ic,
152
+ environmental_clarity=args.ec,
153
+ manual_review_status=args.mr,
154
+ memory_boost=args.memory_boost,
155
+ rule_id=args.rule_id,
156
+ file_path=args.file
157
+ )
158
+
159
+ if args.json:
160
+ print(json.dumps(factors, indent=2))
161
+ else:
162
+ print(f"Total Confidence Score: {total}/100")
163
+ print(f"Classification Band: {band}")
164
+ print("Factor Breakdown:")
165
+ for k, v in factors.items():
166
+ if k not in ("total_score", "classification_band"):
167
+ print(f" - {k}: {v}")
168
+
169
+
170
+ if __name__ == "__main__":
171
+ main()
@@ -29,6 +29,8 @@ def scan_workspace_files(base_dir):
29
29
  for root, dirs, files in os.walk(base_dir):
30
30
  if "runs" in dirs:
31
31
  dirs.remove("runs")
32
+ if "memory" in dirs:
33
+ dirs.remove("memory")
32
34
  if "__pycache__" in dirs:
33
35
  dirs.remove("__pycache__")
34
36