refactorai-core 3.0.0__py3-none-any.whl
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.
- refactor_core/__init__.py +27 -0
- refactor_core/apply.py +252 -0
- refactor_core/budgeting.py +153 -0
- refactor_core/capabilities.py +56 -0
- refactor_core/compliance/__init__.py +34 -0
- refactor_core/compliance/detectors.py +109 -0
- refactor_core/compliance/evidence.py +45 -0
- refactor_core/compliance/loader.py +233 -0
- refactor_core/compliance/models.py +68 -0
- refactor_core/compliance/packs/__init__.py +2 -0
- refactor_core/compliance/packs/hipaa-ephi.json +55 -0
- refactor_core/compliance/packs/iso27001-sdlc.json +62 -0
- refactor_core/compliance/packs/pci-payments.json +63 -0
- refactor_core/compliance/packs/privacy-gdpr.json +71 -0
- refactor_core/compliance/packs/soc2-core.json +63 -0
- refactor_core/compliance/projection.py +252 -0
- refactor_core/compliance_settings.py +173 -0
- refactor_core/constitution.py +354 -0
- refactor_core/gate.py +48 -0
- refactor_core/indexing.py +225 -0
- refactor_core/model_catalog.py +127 -0
- refactor_core/models.py +69 -0
- refactor_core/op_classifier.py +243 -0
- refactor_core/op_feasibility.py +237 -0
- refactor_core/paths.py +47 -0
- refactor_core/refactor_ops.py +152 -0
- refactor_core/refactor_requests.py +858 -0
- refactor_core/rules/__init__.py +19 -0
- refactor_core/rules/injection.py +124 -0
- refactor_core/rules/loader.py +91 -0
- refactor_core/rules/matcher.py +41 -0
- refactor_core/rules/models.py +46 -0
- refactor_core/rules/resolver.py +150 -0
- refactor_core/rules/system_rules.json +170 -0
- refactor_core/security/__init__.py +35 -0
- refactor_core/security/finding_merge.py +159 -0
- refactor_core/security/semgrep_parser.py +129 -0
- refactor_core/security/semgrep_runner.py +360 -0
- refactor_core/security/suppression.py +88 -0
- refactor_core/store.py +354 -0
- refactor_core/testcmd.py +64 -0
- refactorai_core-3.0.0.dist-info/METADATA +27 -0
- refactorai_core-3.0.0.dist-info/RECORD +45 -0
- refactorai_core-3.0.0.dist-info/WHEEL +5 -0
- refactorai_core-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"""Managed compliance pack loader (R18 Phase 2)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
from importlib import resources
|
|
8
|
+
|
|
9
|
+
from refactor_core import __version__ as CORE_VERSION
|
|
10
|
+
from refactor_core.compliance.models import CompliancePack, CompliancePackResolution, ComplianceRuleDef
|
|
11
|
+
|
|
12
|
+
VALID_LEVELS = {"off", "advisory", "standard", "strict"}
|
|
13
|
+
_PACK_FILES_BY_FRAMEWORK = {
|
|
14
|
+
"soc2": "soc2-core.json",
|
|
15
|
+
"iso27001": "iso27001-sdlc.json",
|
|
16
|
+
"privacy-gdpr": "privacy-gdpr.json",
|
|
17
|
+
"pci-payments": "pci-payments.json",
|
|
18
|
+
"hipaa-ephi": "hipaa-ephi.json",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CompliancePackError(RuntimeError):
|
|
23
|
+
"""Raised when a compliance pack cannot be loaded/validated."""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _norm_framework(value: str) -> str:
|
|
27
|
+
return str(value or "").strip().lower()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _norm_level(value: str) -> str:
|
|
31
|
+
level = str(value or "").strip().lower()
|
|
32
|
+
return level if level in VALID_LEVELS else "standard"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _version_tuple(value: str) -> tuple[int, ...]:
|
|
36
|
+
chunks = []
|
|
37
|
+
for part in str(value or "").split("."):
|
|
38
|
+
token = "".join(ch for ch in part if ch.isdigit())
|
|
39
|
+
if not token:
|
|
40
|
+
break
|
|
41
|
+
chunks.append(int(token))
|
|
42
|
+
return tuple(chunks or [0])
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _canonical_rules_hash(rules: list[dict]) -> str:
|
|
46
|
+
text = json.dumps(rules, sort_keys=True, separators=(",", ":"))
|
|
47
|
+
return hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _load_embedded_payload(filename: str) -> dict:
|
|
51
|
+
try:
|
|
52
|
+
text = resources.files("refactor_core.compliance.packs").joinpath(filename).read_text(
|
|
53
|
+
encoding="utf-8"
|
|
54
|
+
)
|
|
55
|
+
except Exception as exc: # pragma: no cover - defensive
|
|
56
|
+
raise CompliancePackError(f"Could not read embedded compliance pack {filename}: {exc}") from exc
|
|
57
|
+
try:
|
|
58
|
+
payload = json.loads(text)
|
|
59
|
+
except json.JSONDecodeError as exc:
|
|
60
|
+
raise CompliancePackError(f"Invalid JSON in embedded compliance pack {filename}: {exc}") from exc
|
|
61
|
+
if not isinstance(payload, dict):
|
|
62
|
+
raise CompliancePackError(f"Invalid compliance pack {filename}: root must be an object")
|
|
63
|
+
return payload
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _parse_pack(payload: dict, *, origin: str) -> CompliancePack:
|
|
67
|
+
schema_version = int(payload.get("schema_version", 0) or 0)
|
|
68
|
+
if schema_version != 1:
|
|
69
|
+
raise CompliancePackError(
|
|
70
|
+
f"Incompatible compliance pack schema in {origin}: expected 1, got {schema_version}"
|
|
71
|
+
)
|
|
72
|
+
pack_id = str(payload.get("pack_id", "") or "").strip()
|
|
73
|
+
framework = _norm_framework(str(payload.get("framework", "") or ""))
|
|
74
|
+
version = str(payload.get("version", "") or "").strip()
|
|
75
|
+
channel = str(payload.get("channel", "stable") or "stable").strip().lower()
|
|
76
|
+
runtime = payload.get("runtime_compat")
|
|
77
|
+
runtime = runtime if isinstance(runtime, dict) else {}
|
|
78
|
+
min_core_version = str(runtime.get("min_core_version", "0.0.0") or "0.0.0")
|
|
79
|
+
signature = str(payload.get("signature", "") or "").strip()
|
|
80
|
+
rules_sha256 = str(payload.get("rules_sha256", "") or "").strip().lower()
|
|
81
|
+
if not pack_id or not framework or not version:
|
|
82
|
+
raise CompliancePackError(
|
|
83
|
+
f"Invalid compliance pack {origin}: pack_id/framework/version are required"
|
|
84
|
+
)
|
|
85
|
+
if not signature:
|
|
86
|
+
raise CompliancePackError(f"Invalid compliance pack {origin}: signature is required")
|
|
87
|
+
raw_depends = payload.get("depends_on", [])
|
|
88
|
+
if raw_depends is None:
|
|
89
|
+
raw_depends = []
|
|
90
|
+
if not isinstance(raw_depends, list):
|
|
91
|
+
raise CompliancePackError(f"Invalid compliance pack {origin}: depends_on must be a list")
|
|
92
|
+
depends_on = tuple(_norm_framework(str(item)) for item in raw_depends if str(item).strip())
|
|
93
|
+
raw_coverage = payload.get("coverage", {})
|
|
94
|
+
if raw_coverage is None:
|
|
95
|
+
raw_coverage = {}
|
|
96
|
+
if not isinstance(raw_coverage, dict):
|
|
97
|
+
raise CompliancePackError(f"Invalid compliance pack {origin}: coverage must be an object")
|
|
98
|
+
coverage = {
|
|
99
|
+
str(key).strip(): str(value).strip().lower()
|
|
100
|
+
for key, value in raw_coverage.items()
|
|
101
|
+
if str(key).strip() and str(value).strip()
|
|
102
|
+
}
|
|
103
|
+
raw_rules = payload.get("rules", [])
|
|
104
|
+
if not isinstance(raw_rules, list):
|
|
105
|
+
raise CompliancePackError(f"Invalid compliance pack {origin}: rules must be a list")
|
|
106
|
+
computed_hash = _canonical_rules_hash(raw_rules)
|
|
107
|
+
if rules_sha256 == "__placeholder__":
|
|
108
|
+
# Development-time embedded packs may carry a placeholder that is
|
|
109
|
+
# replaced during pack publishing/signing. Keep runtime deterministic by
|
|
110
|
+
# normalizing to the computed hash.
|
|
111
|
+
rules_sha256 = computed_hash
|
|
112
|
+
if not rules_sha256 or rules_sha256 != computed_hash:
|
|
113
|
+
raise CompliancePackError(
|
|
114
|
+
f"Integrity check failed for compliance pack {origin}: rules_sha256 mismatch"
|
|
115
|
+
)
|
|
116
|
+
rules: list[ComplianceRuleDef] = []
|
|
117
|
+
for item in raw_rules:
|
|
118
|
+
if not isinstance(item, dict):
|
|
119
|
+
continue
|
|
120
|
+
rule_id = str(item.get("rule_id", "") or "").strip()
|
|
121
|
+
operation_intent = str(item.get("operation_intent", "") or "").strip()
|
|
122
|
+
base_severity = str(item.get("base_severity", "") or "").strip().lower()
|
|
123
|
+
try:
|
|
124
|
+
priority = int(item.get("priority", 100) or 100)
|
|
125
|
+
except (TypeError, ValueError):
|
|
126
|
+
priority = 100
|
|
127
|
+
if not rule_id or not operation_intent:
|
|
128
|
+
continue
|
|
129
|
+
rules.append(
|
|
130
|
+
ComplianceRuleDef(
|
|
131
|
+
rule_id=rule_id,
|
|
132
|
+
operation_intent=operation_intent,
|
|
133
|
+
base_severity=base_severity or "medium",
|
|
134
|
+
priority=priority,
|
|
135
|
+
source_standard=str(item.get("source_standard", "") or "").strip(),
|
|
136
|
+
control_objective=str(item.get("control_objective", "") or "").strip(),
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
if not rules:
|
|
140
|
+
raise CompliancePackError(f"Invalid compliance pack {origin}: no valid rules found")
|
|
141
|
+
if _version_tuple(CORE_VERSION) < _version_tuple(min_core_version):
|
|
142
|
+
raise CompliancePackError(
|
|
143
|
+
f"Compliance pack {origin} requires core>={min_core_version} (current={CORE_VERSION})"
|
|
144
|
+
)
|
|
145
|
+
return CompliancePack(
|
|
146
|
+
pack_id=pack_id,
|
|
147
|
+
framework=framework,
|
|
148
|
+
version=version,
|
|
149
|
+
channel=channel,
|
|
150
|
+
schema_version=schema_version,
|
|
151
|
+
min_core_version=min_core_version,
|
|
152
|
+
depends_on=depends_on,
|
|
153
|
+
rules=tuple(rules),
|
|
154
|
+
coverage=coverage,
|
|
155
|
+
signature=signature,
|
|
156
|
+
rules_sha256=rules_sha256,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def load_compliance_pack_for_framework(framework: str) -> CompliancePack:
|
|
161
|
+
"""Load and validate one embedded pack by framework id."""
|
|
162
|
+
normalized = _norm_framework(framework)
|
|
163
|
+
filename = _PACK_FILES_BY_FRAMEWORK.get(normalized)
|
|
164
|
+
if not filename:
|
|
165
|
+
raise CompliancePackError(f"Unknown compliance framework: {framework}")
|
|
166
|
+
payload = _load_embedded_payload(filename)
|
|
167
|
+
return _parse_pack(payload, origin=filename)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def resolve_compliance_packs(
|
|
171
|
+
frameworks: tuple[str, ...] | list[str] | None,
|
|
172
|
+
*,
|
|
173
|
+
level: str,
|
|
174
|
+
) -> CompliancePackResolution:
|
|
175
|
+
"""Resolve selected frameworks to validated packs (+ dependencies).
|
|
176
|
+
|
|
177
|
+
Strict-mode behavior:
|
|
178
|
+
- any loader/validation/integrity error raises `CompliancePackError`
|
|
179
|
+
|
|
180
|
+
Non-strict behavior (`advisory`/`standard`/`off`):
|
|
181
|
+
- pack errors become warnings and invalid packs are skipped
|
|
182
|
+
"""
|
|
183
|
+
selected = tuple(_norm_framework(item) for item in (frameworks or ()) if str(item).strip())
|
|
184
|
+
level_norm = _norm_level(level)
|
|
185
|
+
if not selected:
|
|
186
|
+
return CompliancePackResolution(
|
|
187
|
+
packs=(),
|
|
188
|
+
warnings=(),
|
|
189
|
+
selected_frameworks=(),
|
|
190
|
+
level=level_norm,
|
|
191
|
+
)
|
|
192
|
+
warnings: list[str] = []
|
|
193
|
+
resolved: dict[str, CompliancePack] = {}
|
|
194
|
+
stack = list(selected)
|
|
195
|
+
seen: set[str] = set()
|
|
196
|
+
while stack:
|
|
197
|
+
framework = _norm_framework(stack.pop(0))
|
|
198
|
+
if not framework or framework in seen:
|
|
199
|
+
continue
|
|
200
|
+
seen.add(framework)
|
|
201
|
+
try:
|
|
202
|
+
pack = load_compliance_pack_for_framework(framework)
|
|
203
|
+
except CompliancePackError as exc:
|
|
204
|
+
if level_norm == "strict":
|
|
205
|
+
raise
|
|
206
|
+
warnings.append(str(exc))
|
|
207
|
+
continue
|
|
208
|
+
resolved[framework] = pack
|
|
209
|
+
for dep in pack.depends_on:
|
|
210
|
+
dep_norm = _norm_framework(dep)
|
|
211
|
+
if dep_norm and dep_norm not in seen:
|
|
212
|
+
stack.append(dep_norm)
|
|
213
|
+
# deterministic order by original selection then dependency tail.
|
|
214
|
+
ordered: list[CompliancePack] = []
|
|
215
|
+
added: set[str] = set()
|
|
216
|
+
for fw in selected:
|
|
217
|
+
pack = resolved.get(fw)
|
|
218
|
+
if pack and pack.pack_id not in added:
|
|
219
|
+
ordered.append(pack)
|
|
220
|
+
added.add(pack.pack_id)
|
|
221
|
+
for fw in sorted(resolved):
|
|
222
|
+
pack = resolved[fw]
|
|
223
|
+
if pack.pack_id in added:
|
|
224
|
+
continue
|
|
225
|
+
ordered.append(pack)
|
|
226
|
+
added.add(pack.pack_id)
|
|
227
|
+
return CompliancePackResolution(
|
|
228
|
+
packs=tuple(ordered),
|
|
229
|
+
warnings=tuple(warnings),
|
|
230
|
+
selected_frameworks=selected,
|
|
231
|
+
level=level_norm,
|
|
232
|
+
)
|
|
233
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Compliance pack models (R18 Phase 2)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
|
|
7
|
+
from refactor_core.refactor_ops import OperationScope
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True)
|
|
11
|
+
class ComplianceRuleDef:
|
|
12
|
+
"""Minimal machine-readable rule record for pack validation/loading."""
|
|
13
|
+
|
|
14
|
+
rule_id: str
|
|
15
|
+
operation_intent: str
|
|
16
|
+
base_severity: str
|
|
17
|
+
priority: int = 100
|
|
18
|
+
source_standard: str = ""
|
|
19
|
+
control_objective: str = ""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class CompliancePack:
|
|
24
|
+
"""Validated compliance pack manifest."""
|
|
25
|
+
|
|
26
|
+
pack_id: str
|
|
27
|
+
framework: str
|
|
28
|
+
version: str
|
|
29
|
+
channel: str = "stable"
|
|
30
|
+
schema_version: int = 1
|
|
31
|
+
min_core_version: str = "0.0.0"
|
|
32
|
+
depends_on: tuple[str, ...] = ()
|
|
33
|
+
rules: tuple[ComplianceRuleDef, ...] = ()
|
|
34
|
+
coverage: dict[str, str] = field(default_factory=dict)
|
|
35
|
+
signature: str = ""
|
|
36
|
+
rules_sha256: str = ""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class CompliancePackResolution:
|
|
41
|
+
"""Resolved packs for one run with non-fatal loader warnings."""
|
|
42
|
+
|
|
43
|
+
packs: tuple[CompliancePack, ...] = ()
|
|
44
|
+
warnings: tuple[str, ...] = ()
|
|
45
|
+
selected_frameworks: tuple[str, ...] = ()
|
|
46
|
+
level: str = "standard"
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def pack_versions(self) -> dict[str, str]:
|
|
50
|
+
return {pack.pack_id: pack.version for pack in self.packs}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True)
|
|
54
|
+
class ComplianceProjectedRule:
|
|
55
|
+
"""One projected compliance decision for a finding."""
|
|
56
|
+
|
|
57
|
+
rule_id: str
|
|
58
|
+
pack_id: str
|
|
59
|
+
framework: str
|
|
60
|
+
decision: str # allow | warn | block
|
|
61
|
+
reason_code: str
|
|
62
|
+
message: str
|
|
63
|
+
operation_intent: str
|
|
64
|
+
priority: int = 100
|
|
65
|
+
operation_type: str = ""
|
|
66
|
+
scope: OperationScope = field(default_factory=OperationScope)
|
|
67
|
+
|
|
68
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"pack_id": "hipaa-ephi",
|
|
4
|
+
"framework": "hipaa-ephi",
|
|
5
|
+
"version": "2026.06",
|
|
6
|
+
"channel": "stable",
|
|
7
|
+
"runtime_compat": {
|
|
8
|
+
"min_core_version": "0.1.1"
|
|
9
|
+
},
|
|
10
|
+
"depends_on": [
|
|
11
|
+
"soc2"
|
|
12
|
+
],
|
|
13
|
+
"coverage": {
|
|
14
|
+
"164.312.a": "covered",
|
|
15
|
+
"164.312.b": "covered",
|
|
16
|
+
"164.312.c": "assert_only"
|
|
17
|
+
},
|
|
18
|
+
"rules": [
|
|
19
|
+
{
|
|
20
|
+
"rule_id": "HIPAA.164.312.b.audit-integrity",
|
|
21
|
+
"source_standard": "HIPAA 164.312(b)",
|
|
22
|
+
"control_objective": "Record and examine activity in systems handling ePHI.",
|
|
23
|
+
"operation_intent": "file_merge",
|
|
24
|
+
"base_severity": "high",
|
|
25
|
+
"priority": 220
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"rule_id": "HIPAA.164.312.a.access-isolation",
|
|
29
|
+
"source_standard": "HIPAA 164.312(a)",
|
|
30
|
+
"control_objective": "Restrict ePHI access paths to controlled modules.",
|
|
31
|
+
"operation_intent": "path_move",
|
|
32
|
+
"base_severity": "high",
|
|
33
|
+
"priority": 220
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"rule_id": "HIPAA.164.312.c.integrity-guard",
|
|
37
|
+
"source_standard": "HIPAA 164.312(c)",
|
|
38
|
+
"control_objective": "Protect ePHI integrity from unauthorized alteration/destruction.",
|
|
39
|
+
"operation_intent": "assert_only",
|
|
40
|
+
"base_severity": "high",
|
|
41
|
+
"priority": 210
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"rule_id": "HIPAA.164.312.b.phi-logging-min",
|
|
45
|
+
"source_standard": "HIPAA 164.312(b)",
|
|
46
|
+
"control_objective": "Minimize PHI in logs and auditing sinks.",
|
|
47
|
+
"operation_intent": "content_patch",
|
|
48
|
+
"base_severity": "high",
|
|
49
|
+
"priority": 210
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"signature": "managed:local-dev-signature",
|
|
53
|
+
"rules_sha256": "__PLACEHOLDER__"
|
|
54
|
+
}
|
|
55
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"pack_id": "iso27001-sdlc",
|
|
4
|
+
"framework": "iso27001",
|
|
5
|
+
"version": "2026.06",
|
|
6
|
+
"channel": "stable",
|
|
7
|
+
"runtime_compat": {
|
|
8
|
+
"min_core_version": "0.1.1"
|
|
9
|
+
},
|
|
10
|
+
"depends_on": [],
|
|
11
|
+
"coverage": {
|
|
12
|
+
"A.8.24": "covered",
|
|
13
|
+
"A.8.25": "covered",
|
|
14
|
+
"A.8.26": "covered",
|
|
15
|
+
"A.8.28": "covered"
|
|
16
|
+
},
|
|
17
|
+
"rules": [
|
|
18
|
+
{
|
|
19
|
+
"rule_id": "ISO.A8.25.pipeline-owner-guard",
|
|
20
|
+
"source_standard": "ISO 27001 Annex A 8.25",
|
|
21
|
+
"control_objective": "Changes to CI/pipeline definitions require controlled ownership.",
|
|
22
|
+
"operation_intent": "assert_only",
|
|
23
|
+
"base_severity": "high",
|
|
24
|
+
"priority": 210
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"rule_id": "ISO.A8.28.injection-sink-harden",
|
|
28
|
+
"source_standard": "ISO 27001 Annex A 8.28",
|
|
29
|
+
"control_objective": "Neutralize common injection sinks.",
|
|
30
|
+
"operation_intent": "content_patch",
|
|
31
|
+
"base_severity": "high",
|
|
32
|
+
"priority": 200
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"rule_id": "ISO.A8.24.weak-crypto-replace",
|
|
36
|
+
"source_standard": "ISO 27001 Annex A 8.24",
|
|
37
|
+
"control_objective": "Replace weak cryptographic primitives.",
|
|
38
|
+
"operation_intent": "content_patch",
|
|
39
|
+
"base_severity": "high",
|
|
40
|
+
"priority": 200
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"rule_id": "ISO.A8.26.input-validation-guard",
|
|
44
|
+
"source_standard": "ISO 27001 Annex A 8.26",
|
|
45
|
+
"control_objective": "Input validation is enforced at system boundaries.",
|
|
46
|
+
"operation_intent": "content_patch",
|
|
47
|
+
"base_severity": "high",
|
|
48
|
+
"priority": 180
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"rule_id": "ISO.A8.4.source-integrity-name",
|
|
52
|
+
"source_standard": "ISO 27001 Annex A 8.4",
|
|
53
|
+
"control_objective": "Security-sensitive symbols have clear, controlled naming.",
|
|
54
|
+
"operation_intent": "symbol_rename",
|
|
55
|
+
"base_severity": "medium",
|
|
56
|
+
"priority": 130
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"signature": "managed:local-dev-signature",
|
|
60
|
+
"rules_sha256": "__PLACEHOLDER__"
|
|
61
|
+
}
|
|
62
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"pack_id": "pci-payments",
|
|
4
|
+
"framework": "pci-payments",
|
|
5
|
+
"version": "2026.06",
|
|
6
|
+
"channel": "stable",
|
|
7
|
+
"runtime_compat": {
|
|
8
|
+
"min_core_version": "0.1.1"
|
|
9
|
+
},
|
|
10
|
+
"depends_on": [
|
|
11
|
+
"soc2"
|
|
12
|
+
],
|
|
13
|
+
"coverage": {
|
|
14
|
+
"6.2.4": "covered",
|
|
15
|
+
"6.5.1": "covered",
|
|
16
|
+
"3.x": "covered"
|
|
17
|
+
},
|
|
18
|
+
"rules": [
|
|
19
|
+
{
|
|
20
|
+
"rule_id": "PCI.6.5.1.cde-isolation",
|
|
21
|
+
"source_standard": "PCI DSS 6.5.1",
|
|
22
|
+
"control_objective": "Changes affecting CDE boundaries require controlled handling.",
|
|
23
|
+
"operation_intent": "assert_only",
|
|
24
|
+
"base_severity": "critical",
|
|
25
|
+
"priority": 240
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"rule_id": "PCI.3.x.pan-logging-mask",
|
|
29
|
+
"source_standard": "PCI DSS 3.x",
|
|
30
|
+
"control_objective": "Do not expose PAN in application logs.",
|
|
31
|
+
"operation_intent": "content_patch",
|
|
32
|
+
"base_severity": "high",
|
|
33
|
+
"priority": 220
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"rule_id": "PCI.6.2.4.injection-harden",
|
|
37
|
+
"source_standard": "PCI DSS 6.2.4",
|
|
38
|
+
"control_objective": "Bespoke payment code follows secure coding controls.",
|
|
39
|
+
"operation_intent": "content_patch",
|
|
40
|
+
"base_severity": "high",
|
|
41
|
+
"priority": 220
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"rule_id": "PCI.6.2.4.weak-crypto-replace",
|
|
45
|
+
"source_standard": "PCI DSS 6.2.4",
|
|
46
|
+
"control_objective": "Weak cryptography in payment flows is replaced.",
|
|
47
|
+
"operation_intent": "content_patch",
|
|
48
|
+
"base_severity": "high",
|
|
49
|
+
"priority": 220
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"rule_id": "PCI.6.5.1.change-evidence",
|
|
53
|
+
"source_standard": "PCI DSS 6.5.1",
|
|
54
|
+
"control_objective": "Sensitive production changes require approval and rollback evidence.",
|
|
55
|
+
"operation_intent": "assert_only",
|
|
56
|
+
"base_severity": "high",
|
|
57
|
+
"priority": 210
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"signature": "managed:local-dev-signature",
|
|
61
|
+
"rules_sha256": "__PLACEHOLDER__"
|
|
62
|
+
}
|
|
63
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"pack_id": "privacy-gdpr",
|
|
4
|
+
"framework": "privacy-gdpr",
|
|
5
|
+
"version": "2026.06",
|
|
6
|
+
"channel": "stable",
|
|
7
|
+
"runtime_compat": {
|
|
8
|
+
"min_core_version": "0.1.1"
|
|
9
|
+
},
|
|
10
|
+
"depends_on": [],
|
|
11
|
+
"coverage": {
|
|
12
|
+
"Art25.1": "covered",
|
|
13
|
+
"Art25.2": "covered",
|
|
14
|
+
"Art5.1.c": "covered",
|
|
15
|
+
"Art17": "assert_only",
|
|
16
|
+
"Art32": "covered"
|
|
17
|
+
},
|
|
18
|
+
"rules": [
|
|
19
|
+
{
|
|
20
|
+
"rule_id": "GDPR.Art25.2.pii-isolation",
|
|
21
|
+
"source_standard": "GDPR Art.25(2)",
|
|
22
|
+
"control_objective": "Isolate PII processing by default.",
|
|
23
|
+
"operation_intent": "file_split",
|
|
24
|
+
"base_severity": "high",
|
|
25
|
+
"priority": 200
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"rule_id": "GDPR.Art5.logging-minimization",
|
|
29
|
+
"source_standard": "GDPR Art.5(1)(c)",
|
|
30
|
+
"control_objective": "Avoid raw personal data in logs.",
|
|
31
|
+
"operation_intent": "content_patch",
|
|
32
|
+
"base_severity": "high",
|
|
33
|
+
"priority": 200
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"rule_id": "GDPR.Art32.transport-encryption",
|
|
37
|
+
"source_standard": "GDPR Art.32",
|
|
38
|
+
"control_objective": "Personal data transport/storage uses encryption controls.",
|
|
39
|
+
"operation_intent": "content_patch",
|
|
40
|
+
"base_severity": "high",
|
|
41
|
+
"priority": 190
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"rule_id": "GDPR.Art25.retention-coupling",
|
|
45
|
+
"source_standard": "GDPR Art.25(2)",
|
|
46
|
+
"control_objective": "Retention path changes remain coupled to policy updates.",
|
|
47
|
+
"operation_intent": "assert_only",
|
|
48
|
+
"base_severity": "high",
|
|
49
|
+
"priority": 180
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"rule_id": "GDPR.Art17.erasure-workflow-guard",
|
|
53
|
+
"source_standard": "GDPR Art.17",
|
|
54
|
+
"control_objective": "Erasure workflow changes require policy-linked review.",
|
|
55
|
+
"operation_intent": "assert_only",
|
|
56
|
+
"base_severity": "medium",
|
|
57
|
+
"priority": 150
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"rule_id": "GDPR.Art25.1.pii-symbol-clarity",
|
|
61
|
+
"source_standard": "GDPR Art.25(1)",
|
|
62
|
+
"control_objective": "PII-handling symbols are explicit and reviewable.",
|
|
63
|
+
"operation_intent": "symbol_rename",
|
|
64
|
+
"base_severity": "medium",
|
|
65
|
+
"priority": 120
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"signature": "managed:local-dev-signature",
|
|
69
|
+
"rules_sha256": "__PLACEHOLDER__"
|
|
70
|
+
}
|
|
71
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"pack_id": "soc2-core",
|
|
4
|
+
"framework": "soc2",
|
|
5
|
+
"version": "2026.06",
|
|
6
|
+
"channel": "stable",
|
|
7
|
+
"runtime_compat": {
|
|
8
|
+
"min_core_version": "0.1.1"
|
|
9
|
+
},
|
|
10
|
+
"depends_on": [],
|
|
11
|
+
"coverage": {
|
|
12
|
+
"CC6.1": "covered",
|
|
13
|
+
"CC6.6": "covered",
|
|
14
|
+
"CC7.1": "assert_only",
|
|
15
|
+
"CC7.2": "covered",
|
|
16
|
+
"CC8.1": "covered"
|
|
17
|
+
},
|
|
18
|
+
"rules": [
|
|
19
|
+
{
|
|
20
|
+
"rule_id": "SOC2.CC8.1.protected-path-change",
|
|
21
|
+
"source_standard": "SOC2 CC8.1",
|
|
22
|
+
"control_objective": "Authorized, tested, traceable change for sensitive paths.",
|
|
23
|
+
"operation_intent": "assert_only",
|
|
24
|
+
"base_severity": "high",
|
|
25
|
+
"priority": 220
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"rule_id": "SOC2.CC6.1.secret-externalize",
|
|
29
|
+
"source_standard": "SOC2 CC6.1",
|
|
30
|
+
"control_objective": "No hardcoded credentials in source.",
|
|
31
|
+
"operation_intent": "content_patch",
|
|
32
|
+
"base_severity": "high",
|
|
33
|
+
"priority": 200
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"rule_id": "SOC2.CC6.6.authz-check-insert",
|
|
37
|
+
"source_standard": "SOC2 CC6.6",
|
|
38
|
+
"control_objective": "Authorization checks enforced around sensitive operations.",
|
|
39
|
+
"operation_intent": "content_patch",
|
|
40
|
+
"base_severity": "high",
|
|
41
|
+
"priority": 200
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"rule_id": "SOC2.CC7.2.audit-logging-centralize",
|
|
45
|
+
"source_standard": "SOC2 CC7.2",
|
|
46
|
+
"control_objective": "Monitoring and logging are centralized and reviewable.",
|
|
47
|
+
"operation_intent": "file_merge",
|
|
48
|
+
"base_severity": "medium",
|
|
49
|
+
"priority": 140
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"rule_id": "SOC2.CC7.1.config-drift-guard",
|
|
53
|
+
"source_standard": "SOC2 CC7.1",
|
|
54
|
+
"control_objective": "Configuration drift-prone paths are explicitly guarded.",
|
|
55
|
+
"operation_intent": "assert_only",
|
|
56
|
+
"base_severity": "medium",
|
|
57
|
+
"priority": 120
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"signature": "managed:local-dev-signature",
|
|
61
|
+
"rules_sha256": "__PLACEHOLDER__"
|
|
62
|
+
}
|
|
63
|
+
|