secure-code-agent 0.13.0__tar.gz → 0.13.1__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 (58) hide show
  1. {secure_code_agent-0.13.0/src/secure_code_agent.egg-info → secure_code_agent-0.13.1}/PKG-INFO +4 -2
  2. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/README.md +3 -1
  3. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1/src/secure_code_agent.egg-info}/PKG-INFO +4 -2
  4. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/__init__.py +1 -1
  5. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/sarif.py +35 -11
  6. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/LICENSE +0 -0
  7. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/pyproject.toml +0 -0
  8. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/setup.cfg +0 -0
  9. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_agent.egg-info/SOURCES.txt +0 -0
  10. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_agent.egg-info/dependency_links.txt +0 -0
  11. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_agent.egg-info/entry_points.txt +0 -0
  12. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_agent.egg-info/requires.txt +0 -0
  13. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_agent.egg-info/top_level.txt +0 -0
  14. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/baseline.py +0 -0
  15. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/capabilities.py +0 -0
  16. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/cli.py +0 -0
  17. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/config.py +0 -0
  18. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/data/semgrep-offline.yaml +0 -0
  19. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/data/standards.yaml +0 -0
  20. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/demo.py +0 -0
  21. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/findings.py +0 -0
  22. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/git_tools.py +0 -0
  23. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/history.py +0 -0
  24. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/instructions.py +0 -0
  25. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/mcp_server.py +0 -0
  26. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/pillar.py +0 -0
  27. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/practice.py +0 -0
  28. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/remediation.py +0 -0
  29. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/renderers.py +0 -0
  30. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/ruleset.py +0 -0
  31. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanner_status.py +0 -0
  32. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/__init__.py +0 -0
  33. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/_exclusions.py +0 -0
  34. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/_execution.py +0 -0
  35. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/_finding_builder.py +0 -0
  36. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/_resolution.py +0 -0
  37. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/bandit_scanner.py +0 -0
  38. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/base.py +0 -0
  39. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/builtin_rules.py +0 -0
  40. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/checkov_scanner.py +0 -0
  41. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/floor.py +0 -0
  42. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/gitleaks_scanner.py +0 -0
  43. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/gosec_scanner.py +0 -0
  44. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/hadolint_scanner.py +0 -0
  45. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/njsscan_scanner.py +0 -0
  46. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/npm_audit_scanner.py +0 -0
  47. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/osv_scanner.py +0 -0
  48. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/pip_audit_scanner.py +0 -0
  49. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/rubocop_scanner.py +0 -0
  50. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/scorecard_scanner.py +0 -0
  51. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/semgrep_scanner.py +0 -0
  52. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/trivy_scanner.py +0 -0
  53. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scanners/trufflehog_scanner.py +0 -0
  54. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/scoring.py +0 -0
  55. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/standards.py +0 -0
  56. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/suppressions.py +0 -0
  57. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/src/secure_code_audit/triage.py +0 -0
  58. {secure_code_agent-0.13.0 → secure_code_agent-0.13.1}/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.13.0
3
+ Version: 0.13.1
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
@@ -49,6 +49,8 @@ Dynamic: license-file
49
49
 
50
50
  # secure-code-agent
51
51
 
52
+ ![secure-code-agent — a deterministic security gate whose findings become a bounded remediation work order for your AI coding agent](https://raw.githubusercontent.com/marshallguillory86/secure-code-agent/main/docs/brand/sca.png)
53
+
52
54
  > **Deterministic security gate + bounded AI remediation prompts for repos with AI coding agents in the loop.**
53
55
  > Anchored to NIST SSDF · OWASP ASVS · OWASP Top 10 · MITRE CWE Top 25 · OpenSSF Scorecard · SARIF 2.1.0.
54
56
 
@@ -554,7 +556,7 @@ For agents that support invokable skills, this repo ships a portable skill under
554
556
  ## GitHub Action
555
557
 
556
558
  ```yaml
557
- - uses: marshallguillory86/secure-code-agent@v0.13.0
559
+ - uses: marshallguillory86/secure-code-agent@v0.13.1
558
560
  with:
559
561
  config: secure-code-agent.json
560
562
  fail-on-gate: true
@@ -1,5 +1,7 @@
1
1
  # secure-code-agent
2
2
 
3
+ ![secure-code-agent — a deterministic security gate whose findings become a bounded remediation work order for your AI coding agent](https://raw.githubusercontent.com/marshallguillory86/secure-code-agent/main/docs/brand/sca.png)
4
+
3
5
  > **Deterministic security gate + bounded AI remediation prompts for repos with AI coding agents in the loop.**
4
6
  > Anchored to NIST SSDF · OWASP ASVS · OWASP Top 10 · MITRE CWE Top 25 · OpenSSF Scorecard · SARIF 2.1.0.
5
7
 
@@ -505,7 +507,7 @@ For agents that support invokable skills, this repo ships a portable skill under
505
507
  ## GitHub Action
506
508
 
507
509
  ```yaml
508
- - uses: marshallguillory86/secure-code-agent@v0.13.0
510
+ - uses: marshallguillory86/secure-code-agent@v0.13.1
509
511
  with:
510
512
  config: secure-code-agent.json
511
513
  fail-on-gate: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secure-code-agent
3
- Version: 0.13.0
3
+ Version: 0.13.1
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
@@ -49,6 +49,8 @@ Dynamic: license-file
49
49
 
50
50
  # secure-code-agent
51
51
 
52
+ ![secure-code-agent — a deterministic security gate whose findings become a bounded remediation work order for your AI coding agent](https://raw.githubusercontent.com/marshallguillory86/secure-code-agent/main/docs/brand/sca.png)
53
+
52
54
  > **Deterministic security gate + bounded AI remediation prompts for repos with AI coding agents in the loop.**
53
55
  > Anchored to NIST SSDF · OWASP ASVS · OWASP Top 10 · MITRE CWE Top 25 · OpenSSF Scorecard · SARIF 2.1.0.
54
56
 
@@ -554,7 +556,7 @@ For agents that support invokable skills, this repo ships a portable skill under
554
556
  ## GitHub Action
555
557
 
556
558
  ```yaml
557
- - uses: marshallguillory86/secure-code-agent@v0.13.0
559
+ - uses: marshallguillory86/secure-code-agent@v0.13.1
558
560
  with:
559
561
  config: secure-code-agent.json
560
562
  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.13.0"
15
+ __version__ = "0.13.1"
@@ -13,8 +13,8 @@ from pathlib import Path
13
13
  from secure_code_audit import __version__
14
14
  from secure_code_audit.findings import Category, Confidence, Finding, Severity
15
15
  from secure_code_audit.scanner_status import (
16
+ COVERING_OUTCOMES,
16
17
  CoverageReport,
17
- CoverageStatus,
18
18
  ScannerExecution,
19
19
  ScannerOutcome,
20
20
  )
@@ -92,8 +92,20 @@ def emit(
92
92
 
93
93
 
94
94
  def _invocation(coverage: CoverageReport) -> dict:
95
+ """The run, and what it covered, on two separate axes.
96
+
97
+ `executionSuccessful` says whether this tool ran to completion, and a
98
+ document is only written when it did. It was set from coverage instead,
99
+ so `maintainability-agent` — every scanner completed, PARTIAL only because
100
+ nothing in the floor reads shell — uploaded "unsuccessful tool execution,
101
+ exit code 0" on every run, and GitHub code scanning put a configuration
102
+ error banner on its Security overview. Coverage stays in
103
+ `properties.coverageStatus`, and each gap is a notification naming what
104
+ was not read: `error` for a required scanner that broke the gate,
105
+ `warning` for a limit of the floor.
106
+ """
95
107
  invocation = {
96
- "executionSuccessful": coverage.status is CoverageStatus.COMPLETE,
108
+ "executionSuccessful": True,
97
109
  "properties": {
98
110
  "coverageStatus": coverage.status.value,
99
111
  "requiredScanners": list(coverage.required),
@@ -108,18 +120,30 @@ def _invocation(coverage: CoverageReport) -> dict:
108
120
  ],
109
121
  },
110
122
  }
111
- if coverage.failures:
112
- invocation["toolExecutionNotifications"] = [
113
- {
114
- "level": "error",
115
- "message": {"text": failure},
116
- "descriptor": {"id": "scanner-coverage"},
117
- }
118
- for failure in coverage.failures
119
- ]
123
+ notifications = [_coverage_notification("error", failure) for failure in coverage.failures]
124
+ notifications += [
125
+ _coverage_notification("warning", f"language not covered: {entry}")
126
+ for entry in coverage.unread_languages
127
+ ]
128
+ notifications += [
129
+ _coverage_notification(
130
+ "warning",
131
+ f"scanner {execution.name!r} did not complete: {execution.outcome.value}"
132
+ + (f" — {execution.reason}" if execution.reason else ""),
133
+ )
134
+ for execution in coverage.executions
135
+ if execution.name not in coverage.required
136
+ and execution.outcome not in (*COVERING_OUTCOMES, ScannerOutcome.NOT_APPLICABLE)
137
+ ]
138
+ if notifications:
139
+ invocation["toolExecutionNotifications"] = notifications
120
140
  return invocation
121
141
 
122
142
 
143
+ def _coverage_notification(level: str, text: str) -> dict:
144
+ return {"level": level, "message": {"text": text}, "descriptor": {"id": "scanner-coverage"}}
145
+
146
+
123
147
  def _rule(f: Finding) -> dict:
124
148
  rule: dict = {
125
149
  "id": f.rule_id,