secure-code-agent 0.12.2__tar.gz → 0.12.3__tar.gz

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 (52) hide show
  1. {secure_code_agent-0.12.2/src/secure_code_agent.egg-info → secure_code_agent-0.12.3}/PKG-INFO +4 -2
  2. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/README.md +3 -1
  3. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3/src/secure_code_agent.egg-info}/PKG-INFO +4 -2
  4. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/__init__.py +1 -1
  5. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/git_tools.py +11 -0
  6. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/suppressions.py +10 -2
  7. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/LICENSE +0 -0
  8. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/pyproject.toml +0 -0
  9. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/setup.cfg +0 -0
  10. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_agent.egg-info/SOURCES.txt +0 -0
  11. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_agent.egg-info/dependency_links.txt +0 -0
  12. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_agent.egg-info/entry_points.txt +0 -0
  13. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_agent.egg-info/requires.txt +0 -0
  14. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_agent.egg-info/top_level.txt +0 -0
  15. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/baseline.py +0 -0
  16. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/cli.py +0 -0
  17. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/config.py +0 -0
  18. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/data/semgrep-offline.yaml +0 -0
  19. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/demo.py +0 -0
  20. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/findings.py +0 -0
  21. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/history.py +0 -0
  22. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/instructions.py +0 -0
  23. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/mcp_server.py +0 -0
  24. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/pillar.py +0 -0
  25. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/practice.py +0 -0
  26. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/remediation.py +0 -0
  27. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/renderers.py +0 -0
  28. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/ruleset.py +0 -0
  29. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/sarif.py +0 -0
  30. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanner_status.py +0 -0
  31. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/__init__.py +0 -0
  32. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/bandit_scanner.py +0 -0
  33. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/base.py +0 -0
  34. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/builtin_rules.py +0 -0
  35. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/checkov_scanner.py +0 -0
  36. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/floor.py +0 -0
  37. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/gitleaks_scanner.py +0 -0
  38. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/gosec_scanner.py +0 -0
  39. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/hadolint_scanner.py +0 -0
  40. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/njsscan_scanner.py +0 -0
  41. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/npm_audit_scanner.py +0 -0
  42. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/osv_scanner.py +0 -0
  43. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/pip_audit_scanner.py +0 -0
  44. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/rubocop_scanner.py +0 -0
  45. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/scorecard_scanner.py +0 -0
  46. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/semgrep_scanner.py +0 -0
  47. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/trivy_scanner.py +0 -0
  48. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scanners/trufflehog_scanner.py +0 -0
  49. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/scoring.py +0 -0
  50. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/standards.py +0 -0
  51. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/triage.py +0 -0
  52. {secure_code_agent-0.12.2 → secure_code_agent-0.12.3}/src/secure_code_audit/verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secure-code-agent
3
- Version: 0.12.2
3
+ Version: 0.12.3
4
4
  Summary: Deterministic security gate + bounded AI remediation prompt generator. NIST SSDF / OWASP ASVS / CWE Top 25 anchored.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -448,6 +448,8 @@ for repositories whose `pyproject.toml` is their authoritative audit input.
448
448
  expires: "2027-05-13"
449
449
  ```
450
450
 
451
+ `paths` entries are repository-relative and use the same pattern syntax as `exclude_patterns`: a trailing `/` means that directory at any depth, a bare name matches at any depth, and `**/` includes the root.
452
+
451
453
  Wildcard rule (`rule_id: "*"`) requires a `file` or `paths` scope — you cannot disable a rule globally.
452
454
 
453
455
  ## Baseline + incremental adoption
@@ -511,7 +513,7 @@ For agents that support invokable skills, this repo ships a portable skill under
511
513
  ## GitHub Action
512
514
 
513
515
  ```yaml
514
- - uses: marshallguillory86/secure-code-agent@v0.12.2
516
+ - uses: marshallguillory86/secure-code-agent@v0.12.3
515
517
  with:
516
518
  config: secure-code-agent.json
517
519
  fail-on-gate: true
@@ -400,6 +400,8 @@ for repositories whose `pyproject.toml` is their authoritative audit input.
400
400
  expires: "2027-05-13"
401
401
  ```
402
402
 
403
+ `paths` entries are repository-relative and use the same pattern syntax as `exclude_patterns`: a trailing `/` means that directory at any depth, a bare name matches at any depth, and `**/` includes the root.
404
+
403
405
  Wildcard rule (`rule_id: "*"`) requires a `file` or `paths` scope — you cannot disable a rule globally.
404
406
 
405
407
  ## Baseline + incremental adoption
@@ -463,7 +465,7 @@ For agents that support invokable skills, this repo ships a portable skill under
463
465
  ## GitHub Action
464
466
 
465
467
  ```yaml
466
- - uses: marshallguillory86/secure-code-agent@v0.12.2
468
+ - uses: marshallguillory86/secure-code-agent@v0.12.3
467
469
  with:
468
470
  config: secure-code-agent.json
469
471
  fail-on-gate: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secure-code-agent
3
- Version: 0.12.2
3
+ Version: 0.12.3
4
4
  Summary: Deterministic security gate + bounded AI remediation prompt generator. NIST SSDF / OWASP ASVS / CWE Top 25 anchored.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -448,6 +448,8 @@ for repositories whose `pyproject.toml` is their authoritative audit input.
448
448
  expires: "2027-05-13"
449
449
  ```
450
450
 
451
+ `paths` entries are repository-relative and use the same pattern syntax as `exclude_patterns`: a trailing `/` means that directory at any depth, a bare name matches at any depth, and `**/` includes the root.
452
+
451
453
  Wildcard rule (`rule_id: "*"`) requires a `file` or `paths` scope — you cannot disable a rule globally.
452
454
 
453
455
  ## Baseline + incremental adoption
@@ -511,7 +513,7 @@ For agents that support invokable skills, this repo ships a portable skill under
511
513
  ## GitHub Action
512
514
 
513
515
  ```yaml
514
- - uses: marshallguillory86/secure-code-agent@v0.12.2
516
+ - uses: marshallguillory86/secure-code-agent@v0.12.3
515
517
  with:
516
518
  config: secure-code-agent.json
517
519
  fail-on-gate: true
@@ -12,4 +12,4 @@
12
12
  #:
13
13
  #: PyPI is immutable, so 0.4.0 stays wrong. 0.5.0 is the first build whose
14
14
  #: artifacts name their own producer correctly.
15
- __version__ = "0.12.2"
15
+ __version__ = "0.12.3"
@@ -48,6 +48,17 @@ def is_excluded(path: Path, root: Path, patterns: Iterable[str]) -> bool:
48
48
  return any(_matches(rel, path.name, pat) for pat in patterns)
49
49
 
50
50
 
51
+ def matches_pattern(rel: str, pattern: str) -> bool:
52
+ """One configured path pattern against one repository-relative POSIX path.
53
+
54
+ The pattern language every path setting shares: `exclude_patterns`,
55
+ `test_patterns`, `docs_patterns`, and `.scignore.yaml` `paths:`. There is
56
+ one of it so the same string cannot mean two things in one configuration
57
+ (D21).
58
+ """
59
+ return _matches(rel, rel.rsplit("/", 1)[-1], pattern)
60
+
61
+
51
62
  def _matches(rel: str, name: str, pat: str) -> bool:
52
63
  """One glob against one path, already made relative to the root.
53
64
 
@@ -17,7 +17,7 @@ Entry schema (.scignore.yaml)::
17
17
  ...
18
18
  expires: 2027-08-01 # required; max 365 days out
19
19
  file: api/tests/x.py # optional path (suffix match)
20
- paths: ["api/**"] # optional fnmatch patterns, repository-relative
20
+ paths: ["api/"] # optional; exclude_patterns syntax, repository-relative
21
21
  fingerprint: 0aaa689f8a967d8c # optional; 16 hex chars, from the report
22
22
  line: 18 # optional; positive integer
23
23
 
@@ -37,6 +37,7 @@ from dataclasses import dataclass, field
37
37
  from pathlib import Path
38
38
 
39
39
  from secure_code_audit.findings import Category, Confidence, Finding, Severity
40
+ from secure_code_audit.git_tools import matches_pattern
40
41
 
41
42
  _DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$")
42
43
  _MAX_TTL_DAYS = 365
@@ -77,6 +78,13 @@ class SuppressionRule:
77
78
  against the path with a leading `/`, and `*/src/app.py` matches
78
79
  `/src/app.py`. `root` lets an absolute `file:` and a fingerprint
79
80
  recorded by an earlier release keep matching the finding they named.
81
+
82
+ **A `paths:` glob is an exclude pattern (D21).** It is matched by
83
+ `git_tools.matches_pattern`, the matcher `exclude_patterns` uses, so a
84
+ trailing slash means "this directory, at any depth" and a bare name
85
+ matches at any depth. Through 0.12.2 it was bare `fnmatch`, under which
86
+ `paths: ["tests/"]` — the example README, `design.md` and the skill all
87
+ show — matched nothing.
80
88
  """
81
89
  if self.rule_id != "*" and self.rule_id != finding.rule_id:
82
90
  return False
@@ -88,7 +96,7 @@ class SuppressionRule:
88
96
  if self.line is not None and self.line != finding.line_start:
89
97
  return False
90
98
  return not self.paths or any(
91
- fnmatch.fnmatch(rel, p) or fnmatch.fnmatch(f"/{rel}", p) for p in self.paths
99
+ matches_pattern(rel, p) or fnmatch.fnmatch(f"/{rel}", p) for p in self.paths
92
100
  )
93
101
 
94
102
  def _names_file(self, rel: str, finding: Finding, root: Path | None) -> bool: