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
@@ -8,7 +8,7 @@
8
8
  "agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
9
9
  "config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
10
10
  "config/slash-commands.json": "5390f0d26f8117a62e56c58147d3a0d2deab1a20956302b212703281d13fa84e",
11
- "config/torusguard.json": "218eeae10b538aca9b548d1b756d7d4f91a5b624e0bce07533f0c187860586e6",
11
+ "config/torusguard.json": "b979d6ead31e64a63729e050d820f3e3228d3c825972a60ccae2087e6b27f574",
12
12
  "references/django-security.md": "a15b7eb11b51dd1970d3d65544cf79ebea91fb99dc0e085e58a56532a718dce7",
13
13
  "references/drf-security.md": "c7a7af3acaef895bf4798590acc88b3a2e9831a49eb2d23b4d8f31540ab264cc",
14
14
  "references/express-security.md": "dff1db15e614d29d8c272f9da345b418077e62dc883fe210c7a50c552c76493f",
@@ -28,20 +28,24 @@
28
28
  "schemas/confidence.schema.json": "08b3a564d7370e123dd5bfadde9fb077d2954e36b523685b9e1d7bdd2aa4b8cb",
29
29
  "schemas/evidence.schema.json": "d3dcaa10fd2420a4046ea68836fb836a55d003ada4cdc6682229f232881182bf",
30
30
  "schemas/finding.schema.json": "e0a7c28fa4a5f84bdedb5cf5223da26348250d633479d2dbf7ce3ebd6790a852",
31
+ "schemas/memory-context.schema.json": "6b9e032c55ba87b2517dd1e7ca0043b8e2439e85fa4a6eac6fc6041f3091e571",
32
+ "schemas/memory-event.schema.json": "4f653610e04fd480325d0ec77a4339bea4690f85e1d2fa0bd4f6b654c813c905",
33
+ "schemas/memory-pattern.schema.json": "df4aae2a3034a7c64ec50b3ae27b6ee9296aac7371c2a1938508834e5f778afe",
31
34
  "schemas/provenance.schema.json": "781215801249532414643638b6608dc8f52febc9bca43ae03827b90aecc03256",
32
35
  "schemas/remediation.schema.json": "217cb2743ae1a912dc074382e9f05634da93f2e30a880c03f6020600ef7e43d3",
33
36
  "schemas/retest.schema.json": "773b764082f6d2e8c3656ea105e0ce09febd1020520bf262bbcd17f5924da11e",
34
37
  "schemas/runtime-evidence.schema.json": "dbe13741a7fb68cca2a044d47a644ee0bdaacb83a28621dc2a98bffdd59989a6",
35
- "scripts/diff_guard.py": "227bf56d2e6c9aef293a51ad1a3209782e6d9204dc1775956d372c3a6851a736",
36
- "scripts/finding_scorer.py": "b78c6315f22000fb64f5d4e6ff1f3467439769d3d5507aaa99380453df4eb464",
37
- "scripts/manifest_builder.py": "b759131592966053db17ef710dc5f313127a9583295cb867a39ab22a7c996580",
38
+ "scripts/diff_guard.py": "5937b657c1047c78b7b9f0a36f3438cb699457cdb5ee56136d68b97edf56af42",
39
+ "scripts/finding_scorer.py": "c9f34c9153f5322c92bba824ce199ea281c450cd8edc637e61442c5f556d6183",
40
+ "scripts/manifest_builder.py": "136d5650a97dbb52fdf42c6d55b330a4f9593816e344b07913b0b2ba6b5cc409",
41
+ "scripts/memory_engine.py": "e99d34951b953bf3d96b6fca2413192de76778e6519278d4213fa3a72bc9b05f",
38
42
  "scripts/monorepo_detector.py": "38f1eb948ee2856f175e1212956bce211effdd1327d3a31f7303d32ba9478ebe",
39
- "scripts/run_manager.py": "e853874e4fb0cb697596ea338f71ba7e955f2b41a6fc649733b45fa755e94768",
43
+ "scripts/run_manager.py": "b576fc3be9929ee6a52e67662e67f801e4e9317c158243582911e10c94a07619",
40
44
  "scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
41
45
  "scripts/sarif_exporter.py": "35c66637413afc4b72d5bd426638447c77231d2a8594dce5addceffd4803a20d",
42
46
  "scripts/stack_detect.py": "99b7bdf9829d58ff5b8c59afd6e8b6429bbb11d830ac73dec491101cbbc41574",
43
- "skills/torusguard/SKILL.md": "5282a9e73c2faad97f079ff527def34b96709615c0dd297fe9b1bb2894f03e20",
44
- "skills/torusguard/bootstrap.py": "7e348065a622089ab1d51e9bf4864e5b0022aaee1ccb2ecbf7057c14e792e2c7",
47
+ "skills/torusguard/SKILL.md": "e772e348716aee26e424ec96be5bd6750dbebcefc248bc4dab0df1e6c0e24fcf",
48
+ "skills/torusguard/bootstrap.py": "7c5a13687578a8736aef25cf767d1ef3c8b82dcae0eb7efce41bf131d27a120f",
45
49
  "skills/torusguard/references/auth-and-sessions.md": "34c2843f8c0dbe3574e54f00a39a92a1f431527ec5f69b2d64c84240d424a39e",
46
50
  "skills/torusguard/references/business-logic-and-abuse.md": "0d6088936bc1a01023070332fccef0f2e0734358a5119379055f3d2895c22567",
47
51
  "skills/torusguard/references/cache-and-sensitive-responses.md": "8f920cacde29c50b1f5f98de341a60db0bc607fe8c212a7e618ef7af08c86511",
@@ -66,13 +70,13 @@
66
70
  "skills/torusguard/references/webhook-security.md": "a0c7efb663c664dd840ba99b689cb67d4688643106f8b6e80d18a424c6add386",
67
71
  "skills/torusguard/references/websocket-security.md": "5624a84abd75bbb4eed029cd217e0c794ee452cbecc0730a8ab4d0f371537cd7",
68
72
  "skills/torusguard-apply/SKILL.md": "9436fa5cdefa661677ada22936a3949de06aca276e4f4bb27e0ef5b7ea34edc3",
69
- "skills/torusguard-audit/SKILL.md": "d0e0c21d6c36d9d128ccce6ad628b978ff771d27552ba80e0a4981e18b9f5a51",
73
+ "skills/torusguard-audit/SKILL.md": "f879e280d357ea7f124c647ce39af2b24b79db608c9edd018f26e5312625a8b5",
70
74
  "skills/torusguard-authorize/SKILL.md": "da849585f2e46c08ef528b89737be14647f1109fd365fd27f3f6da57a396724b",
71
75
  "skills/torusguard-exploit-check/SKILL.md": "e9a173e154a88cc9cb929c59d79a65ab13d5cf9567b4112bd7f272746cf9c3f9",
72
76
  "skills/torusguard-full/SKILL.md": "cc97684d37de378e51fefd12f6f9a7cd15cc469ce46079a0599440aa7b073f7b",
73
- "skills/torusguard-harden/SKILL.md": "86a8dee6c614477e2122287752f5c16e3688c0451d0e7ae9bfd2a23802bcdde3",
77
+ "skills/torusguard-harden/SKILL.md": "326fa84bda4832f96b19d73824c3472dfe185247ed3e3db9715dd943d46d9874",
74
78
  "skills/torusguard-init/SKILL.md": "1f7844d66219955581fdb266029eefdc355dbebb5741b848daf0062e606202a2",
75
- "skills/torusguard-recheck/SKILL.md": "4725a9be6a6ddedb3d389d1957c7ce3e0f9ce288107816fce85b5953951e13e5",
79
+ "skills/torusguard-recheck/SKILL.md": "457b2a1cce064a738fbe43f0dba6b4393f1630a82f60698ea5ebe655ec017e50",
76
80
  "skills/torusguard-report/SKILL.md": "bde44d114bdc85c04472644a644a7796ed2f182a23e0c057838a3251e4910a09",
77
81
  "skills/torusguard-status/SKILL.md": "4e71d03c71b240afd7f6108569530b7da3702634c512a74ca8dc3174f3c6b0fb",
78
82
  "skills/torusguard-verify/SKILL.md": "10c19e0926255686351e3b75ae774880cf35562d42bd30b87a877bb8f284fc1f",
@@ -87,6 +91,7 @@
87
91
  "workflows/exploit-check.md": "9684009b835a61d5aca8827a971ee686a24c800425d86ef96f963dd27de845b8",
88
92
  "workflows/harden.md": "509484f844c9dcd10dd14c8bb6e3456021928e6cf6abd374faaf34be8fc34ce2",
89
93
  "workflows/init.md": "3d1668a9f6b87417c31f47c887c495f863595ed4a29074e0c5a8ee1ece1d4a35",
94
+ "workflows/memory.md": "c034f9266380db3c05e9ffed943c2bb4ba73c060507e3508e47b543a035a5873",
90
95
  "workflows/recheck.md": "7d374c29a5585c31b81f84fb32d6a466f2e9cb339726dc0523dba25e57bc5d13",
91
96
  "workflows/report.md": "56b3449cff362172c63093ee6150446d11bf05e3c8143661966dad9d42df1470",
92
97
  "workflows/status.md": "921129646518c592cb47ad8e8ccf3d703e8d11ea6eb89bd21a206f545e022dba",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "../schemas/torusguard-config.schema.json",
3
- "version": "0.9.4",
3
+ "version": "1.0.0",
4
4
  "product": "TorusGuard Security Skill Kit",
5
5
  "severity_threshold": "medium",
6
6
  "auto_detect_stack": true,
@@ -0,0 +1,95 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "torusguard-memory-context.schema.json",
4
+ "title": "TorusGuard Memory Context Window",
5
+ "description": "Pre-computed, token-budgeted context window for AI agent consumption formatted as structured JSON cards.",
6
+ "type": "object",
7
+ "required": ["version", "generated_at", "token_estimate", "max_token_budget", "project_profile", "cards"],
8
+ "properties": {
9
+ "version": {
10
+ "type": "string",
11
+ "description": "TorusGuard engine version (e.g., 1.0.0)."
12
+ },
13
+ "generated_at": {
14
+ "type": "string",
15
+ "format": "date-time",
16
+ "description": "ISO 8601 UTC timestamp when this context window was computed."
17
+ },
18
+ "token_estimate": {
19
+ "type": "integer",
20
+ "minimum": 0,
21
+ "description": "Estimated token count of this context document."
22
+ },
23
+ "max_token_budget": {
24
+ "type": "integer",
25
+ "default": 2000,
26
+ "description": "Maximum allowed tokens for agent context injection (default: 2000)."
27
+ },
28
+ "project_profile": {
29
+ "type": "object",
30
+ "required": ["stack", "total_events", "active_patterns_count"],
31
+ "properties": {
32
+ "stack": {
33
+ "type": "array",
34
+ "items": { "type": "string" },
35
+ "description": "Detected technology stack frameworks/languages."
36
+ },
37
+ "total_events": {
38
+ "type": "integer",
39
+ "minimum": 0
40
+ },
41
+ "active_patterns_count": {
42
+ "type": "integer",
43
+ "minimum": 0
44
+ },
45
+ "fix_rate_percentage": {
46
+ "type": ["number", "null"],
47
+ "minimum": 0,
48
+ "maximum": 100
49
+ },
50
+ "top_vulnerabilities": {
51
+ "type": "array",
52
+ "items": { "type": "string" }
53
+ }
54
+ }
55
+ },
56
+ "cards": {
57
+ "type": "array",
58
+ "description": "Ordered list of high-priority intelligence cards for LLM grounding.",
59
+ "items": {
60
+ "type": "object",
61
+ "required": ["card_id", "card_type", "priority", "title", "summary", "card_data"],
62
+ "properties": {
63
+ "card_id": {
64
+ "type": "string",
65
+ "description": "Unique card identifier (e.g., CARD-001)."
66
+ },
67
+ "card_type": {
68
+ "type": "string",
69
+ "enum": ["pattern", "profile", "regression_watch", "false_positive", "fix_idiom"],
70
+ "description": "Semantic category of this context card."
71
+ },
72
+ "priority": {
73
+ "type": "integer",
74
+ "minimum": 1,
75
+ "maximum": 100,
76
+ "description": "Rank order priority (higher = more relevant/critical)."
77
+ },
78
+ "title": {
79
+ "type": "string",
80
+ "description": "Short, human-readable and agent-scannable card title."
81
+ },
82
+ "summary": {
83
+ "type": "string",
84
+ "description": "One-line operational summary for rapid agent reasoning."
85
+ },
86
+ "card_data": {
87
+ "type": "object",
88
+ "description": "Structured card payload containing rule_id, fix_strategy, confidence, affected_files, etc.",
89
+ "additionalProperties": true
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "torusguard-memory-event.schema.json",
4
+ "title": "TorusGuard Memory Event",
5
+ "description": "Schema for individual memory events recorded during audit/fix/recheck cycles.",
6
+ "type": "object",
7
+ "required": ["event_id", "event_type", "timestamp", "version"],
8
+ "properties": {
9
+ "event_id": {
10
+ "type": "string",
11
+ "description": "Unique event identifier (UUID v4 or timestamp-based)."
12
+ },
13
+ "event_type": {
14
+ "type": "string",
15
+ "enum": ["audit_finding", "fix_applied", "fix_verified", "false_positive", "pattern_learned", "stack_changed"],
16
+ "description": "Category of security event."
17
+ },
18
+ "timestamp": {
19
+ "type": "string",
20
+ "format": "date-time",
21
+ "description": "ISO 8601 UTC timestamp."
22
+ },
23
+ "version": {
24
+ "type": "string",
25
+ "description": "TorusGuard version that recorded this event."
26
+ },
27
+ "rule_id": {
28
+ "type": ["string", "null"],
29
+ "description": "TorusGuard rule ID (e.g., TG-DB-004)."
30
+ },
31
+ "file_path": {
32
+ "type": ["string", "null"],
33
+ "description": "Relative file path within the project."
34
+ },
35
+ "line_number": {
36
+ "type": ["integer", "null"],
37
+ "description": "Line number of the finding."
38
+ },
39
+ "severity": {
40
+ "type": ["string", "null"],
41
+ "enum": ["critical", "high", "medium", "low", "info", null]
42
+ },
43
+ "confidence_score": {
44
+ "type": ["integer", "null"],
45
+ "minimum": 0,
46
+ "maximum": 100
47
+ },
48
+ "code_hash": {
49
+ "type": ["string", "null"],
50
+ "description": "SHA-256 hash of the relevant code snippet for pattern matching."
51
+ },
52
+ "fix_strategy": {
53
+ "type": ["string", "null"],
54
+ "description": "Human-readable description of the fix approach used."
55
+ },
56
+ "verification_result": {
57
+ "type": ["string", "null"],
58
+ "enum": ["fixed", "regressed", "partial", "not_tested", null]
59
+ },
60
+ "suppression_reason": {
61
+ "type": ["string", "null"],
62
+ "description": "Reason for false positive suppression."
63
+ },
64
+ "metadata": {
65
+ "type": "object",
66
+ "description": "Additional event-specific metadata.",
67
+ "additionalProperties": true
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "torusguard-memory-pattern.schema.json",
4
+ "title": "TorusGuard Memory Pattern",
5
+ "description": "Schema for distilled security patterns extracted from raw events. Patterns represent recurring fix strategies, vulnerability classes, and project-specific security idioms.",
6
+ "type": "object",
7
+ "required": ["pattern_id", "rule_id", "pattern_type", "confidence", "occurrences", "first_seen", "last_seen"],
8
+ "properties": {
9
+ "pattern_id": {
10
+ "type": "string",
11
+ "description": "Unique pattern identifier (PAT-NNN)."
12
+ },
13
+ "rule_id": {
14
+ "type": "string",
15
+ "description": "TorusGuard rule ID this pattern relates to."
16
+ },
17
+ "pattern_type": {
18
+ "type": "string",
19
+ "enum": ["recurring_fix", "common_vulnerability", "false_positive_class", "regression_watch", "security_idiom"],
20
+ "description": "Category of the distilled pattern."
21
+ },
22
+ "description": {
23
+ "type": "string",
24
+ "description": "Human-readable summary of the pattern."
25
+ },
26
+ "fix_strategy": {
27
+ "type": ["string", "null"],
28
+ "description": "The preferred fix approach observed across multiple occurrences."
29
+ },
30
+ "confidence": {
31
+ "type": "integer",
32
+ "minimum": 0,
33
+ "maximum": 100,
34
+ "description": "Pattern confidence (amplified by repeated confirmations, decayed by TTL)."
35
+ },
36
+ "occurrences": {
37
+ "type": "integer",
38
+ "minimum": 1,
39
+ "description": "Number of times this pattern has been observed."
40
+ },
41
+ "affected_files": {
42
+ "type": "array",
43
+ "items": { "type": "string" },
44
+ "description": "List of relative file paths where this pattern has been observed."
45
+ },
46
+ "first_seen": {
47
+ "type": "string",
48
+ "format": "date-time"
49
+ },
50
+ "last_seen": {
51
+ "type": "string",
52
+ "format": "date-time"
53
+ },
54
+ "decay_checkpoint": {
55
+ "type": ["string", "null"],
56
+ "format": "date-time",
57
+ "description": "Last timestamp when this pattern's confidence was reconfirmed or decayed."
58
+ },
59
+ "source_events": {
60
+ "type": "array",
61
+ "items": { "type": "string" },
62
+ "description": "List of event_ids that contributed to this pattern."
63
+ }
64
+ }
65
+ }
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- TorusGuard Content-Aware Diff Line Scanner (v0.9.3)
4
- Evaluates unified diff patches against security invariants before harden or apply.
3
+ TorusGuard Content-Aware Diff Line Scanner (v1.0.0)
4
+ Evaluates unified diff patches against security invariants before harden or apply,
5
+ including regression watch checks against persistent memory patterns.
5
6
  Pure Python 3.10+ standard library (zero external dependencies).
6
7
  """
7
8
 
@@ -38,16 +39,69 @@ TENANT_FILTER_PATTERNS = [
38
39
  ]
39
40
 
40
41
 
41
- def audit_diff(diff_content: str) -> Dict[str, Any]:
42
+ def check_memory_regressions(
43
+ current_file: str,
44
+ current_line: int,
45
+ added_content: str,
46
+ root_dir: Optional[Path] = None
47
+ ) -> List[Dict[str, Any]]:
48
+ """
49
+ Check if the added line re-introduces a vulnerability in a file
50
+ that is tracked under active Regression Watch in .torusguard/memory/patterns.json.
51
+ """
52
+ violations = []
53
+ base = Path(root_dir or Path.cwd()).resolve()
54
+ torusguard_dir = base / ".torusguard"
55
+ if not torusguard_dir.exists():
56
+ for parent in base.parents:
57
+ if (parent / ".torusguard").exists():
58
+ torusguard_dir = parent / ".torusguard"
59
+ break
60
+
61
+ patterns_file = torusguard_dir / "memory" / "patterns.json"
62
+ if not patterns_file.exists():
63
+ return violations
64
+
65
+ try:
66
+ with open(patterns_file, "r", encoding="utf-8") as f:
67
+ patterns = json.load(f)
68
+ except Exception:
69
+ return violations
70
+
71
+ clean_file = current_file.replace("\\", "/")
72
+ for pat in patterns:
73
+ if pat.get("pattern_type") == "regression_watch":
74
+ affected = [f.replace("\\", "/") for f in pat.get("affected_files", [])]
75
+ if clean_file in affected or any(clean_file.endswith(a) for a in affected):
76
+ rule_id = pat.get("rule_id", "TG-REG")
77
+ desc = pat.get("description", "Regression watch violation")
78
+ violations.append({
79
+ "rule_id": "TG-DIFF-004",
80
+ "category": "Regression Watch",
81
+ "severity": "HIGH",
82
+ "file": current_file,
83
+ "line": current_line,
84
+ "content": added_content.strip(),
85
+ "description": f"File {current_file} matches active Regression Watch for {rule_id}: {desc}"
86
+ })
87
+ return violations
88
+
89
+
90
+ def audit_diff(
91
+ diff_content: str,
92
+ check_memory: bool = False,
93
+ root_dir: Optional[Path] = None
94
+ ) -> Dict[str, Any]:
42
95
  """
43
96
  Parses a unified diff and returns detected violations.
97
+ Optionally checks against active regression watch patterns in memory.
44
98
  """
45
99
  lines = diff_content.splitlines()
46
100
  violations: List[Dict[str, Any]] = []
47
-
101
+
48
102
  current_file = "unknown"
49
103
  current_line = 0
50
-
104
+
51
105
  additions: List[tuple[int, str]] = []
52
106
  deletions: List[tuple[int, str]] = []
53
107
 
@@ -68,7 +122,7 @@ def audit_diff(diff_content: str) -> Dict[str, Any]:
68
122
  current_line += 1
69
123
  added_content = line[1:]
70
124
  additions.append((current_line, added_content))
71
-
125
+
72
126
  # Check bypass patterns
73
127
  for pat, desc in BYPASS_PATTERNS:
74
128
  if pat.search(added_content):
@@ -81,7 +135,7 @@ def audit_diff(diff_content: str) -> Dict[str, Any]:
81
135
  "content": added_content.strip(),
82
136
  "description": desc
83
137
  })
84
-
138
+
85
139
  # Check secret ingestion
86
140
  for pat, desc in SECRET_PATTERNS:
87
141
  if pat.search(added_content):
@@ -95,6 +149,11 @@ def audit_diff(diff_content: str) -> Dict[str, Any]:
95
149
  "description": desc
96
150
  })
97
151
 
152
+ # Check memory regression watch if requested
153
+ if check_memory:
154
+ reg_violations = check_memory_regressions(current_file, current_line, added_content, root_dir=root_dir)
155
+ violations.extend(reg_violations)
156
+
98
157
  elif line.startswith('-') and not line.startswith('---'):
99
158
  deleted_content = line[1:]
100
159
  deletions.append((line_idx, deleted_content))
@@ -127,7 +186,7 @@ def audit_diff(diff_content: str) -> Dict[str, Any]:
127
186
  }
128
187
 
129
188
 
130
- def audit_diff_file(file_path: str) -> Dict[str, Any]:
189
+ def audit_diff_file(file_path: str, check_memory: bool = False, root_dir: Optional[Path] = None) -> Dict[str, Any]:
131
190
  path = Path(file_path)
132
191
  if not path.is_file():
133
192
  return {
@@ -136,23 +195,24 @@ def audit_diff_file(file_path: str) -> Dict[str, Any]:
136
195
  "violations": []
137
196
  }
138
197
  content = path.read_text(encoding="utf-8", errors="replace")
139
- return audit_diff(content)
198
+ return audit_diff(content, check_memory=check_memory, root_dir=root_dir)
140
199
 
141
200
 
142
201
  def main():
143
202
  parser = argparse.ArgumentParser(description="TorusGuard Unified Diff Security Scanner")
144
203
  parser.add_argument("diff_path", nargs="?", help="Path to unified diff file (or read stdin if omitted)")
204
+ parser.add_argument("--check-memory", action="store_true", help="Check additions against persistent memory regression watch patterns")
145
205
  parser.add_argument("--json", action="store_true", help="Output results as JSON")
146
206
  args = parser.parse_args()
147
207
 
148
208
  if args.diff_path:
149
- res = audit_diff_file(args.diff_path)
209
+ res = audit_diff_file(args.diff_path, check_memory=args.check_memory)
150
210
  else:
151
211
  if sys.stdin.isatty():
152
212
  parser.print_help()
153
213
  sys.exit(1)
154
214
  diff_text = sys.stdin.read()
155
- res = audit_diff(diff_text)
215
+ res = audit_diff(diff_text, check_memory=args.check_memory)
156
216
 
157
217
  if args.json:
158
218
  print(json.dumps(res, indent=2))