secure-code-agent 0.12.0__tar.gz → 0.12.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 (52) hide show
  1. {secure_code_agent-0.12.0/src/secure_code_agent.egg-info → secure_code_agent-0.12.1}/PKG-INFO +7 -5
  2. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/README.md +6 -4
  3. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1/src/secure_code_agent.egg-info}/PKG-INFO +7 -5
  4. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/__init__.py +1 -1
  5. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/renderers.py +20 -6
  6. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/LICENSE +0 -0
  7. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/pyproject.toml +0 -0
  8. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/setup.cfg +0 -0
  9. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_agent.egg-info/SOURCES.txt +0 -0
  10. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_agent.egg-info/dependency_links.txt +0 -0
  11. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_agent.egg-info/entry_points.txt +0 -0
  12. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_agent.egg-info/requires.txt +0 -0
  13. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_agent.egg-info/top_level.txt +0 -0
  14. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/baseline.py +0 -0
  15. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/cli.py +0 -0
  16. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/config.py +0 -0
  17. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/data/semgrep-offline.yaml +0 -0
  18. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/demo.py +0 -0
  19. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/findings.py +0 -0
  20. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/git_tools.py +0 -0
  21. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/history.py +0 -0
  22. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/instructions.py +0 -0
  23. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/mcp_server.py +0 -0
  24. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/pillar.py +0 -0
  25. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/practice.py +0 -0
  26. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/remediation.py +0 -0
  27. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/ruleset.py +0 -0
  28. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/sarif.py +0 -0
  29. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanner_status.py +0 -0
  30. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/__init__.py +0 -0
  31. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/bandit_scanner.py +0 -0
  32. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/base.py +0 -0
  33. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/builtin_rules.py +0 -0
  34. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/checkov_scanner.py +0 -0
  35. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/floor.py +0 -0
  36. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/gitleaks_scanner.py +0 -0
  37. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/gosec_scanner.py +0 -0
  38. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/hadolint_scanner.py +0 -0
  39. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/njsscan_scanner.py +0 -0
  40. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/npm_audit_scanner.py +0 -0
  41. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/osv_scanner.py +0 -0
  42. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/pip_audit_scanner.py +0 -0
  43. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/rubocop_scanner.py +0 -0
  44. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/scorecard_scanner.py +0 -0
  45. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/semgrep_scanner.py +0 -0
  46. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/trivy_scanner.py +0 -0
  47. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scanners/trufflehog_scanner.py +0 -0
  48. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/scoring.py +0 -0
  49. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/standards.py +0 -0
  50. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/suppressions.py +0 -0
  51. {secure_code_agent-0.12.0 → secure_code_agent-0.12.1}/src/secure_code_audit/triage.py +0 -0
  52. {secure_code_agent-0.12.0 → secure_code_agent-0.12.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.12.0
3
+ Version: 0.12.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
@@ -489,9 +489,11 @@ secure-code-agent --sarif-import codeql-results.sarif \
489
489
  --sarif-import snyk-results.sarif
490
490
  ```
491
491
 
492
- `--changed-only` is reserved but not yet safely implemented. Passing it fails
493
- with exit code 2 so a caller cannot accidentally treat an unscoped audit as a
494
- changed-file audit.
492
+ `--changed-only REF` scopes the **report** to files changed since `REF`. The
493
+ whole tree is still scanned — scanners read trees, not diffs — and **no grade
494
+ is issued**, because a run that looks at less must not score better. A ref git
495
+ cannot resolve is an error rather than an empty diff, since "nothing changed"
496
+ and "your ref is wrong" otherwise produce the same finding count.
495
497
 
496
498
  The current orchestrator accepts one repository root per invocation. Multiple
497
499
  positional roots fail with exit code 2 instead of silently ignoring coverage.
@@ -509,7 +511,7 @@ For agents that support invokable skills, this repo ships a portable skill under
509
511
  ## GitHub Action
510
512
 
511
513
  ```yaml
512
- - uses: marshallguillory86/secure-code-agent@v0.12.0
514
+ - uses: marshallguillory86/secure-code-agent@v0.12.1
513
515
  with:
514
516
  config: secure-code-agent.json
515
517
  fail-on-gate: true
@@ -441,9 +441,11 @@ secure-code-agent --sarif-import codeql-results.sarif \
441
441
  --sarif-import snyk-results.sarif
442
442
  ```
443
443
 
444
- `--changed-only` is reserved but not yet safely implemented. Passing it fails
445
- with exit code 2 so a caller cannot accidentally treat an unscoped audit as a
446
- changed-file audit.
444
+ `--changed-only REF` scopes the **report** to files changed since `REF`. The
445
+ whole tree is still scanned — scanners read trees, not diffs — and **no grade
446
+ is issued**, because a run that looks at less must not score better. A ref git
447
+ cannot resolve is an error rather than an empty diff, since "nothing changed"
448
+ and "your ref is wrong" otherwise produce the same finding count.
447
449
 
448
450
  The current orchestrator accepts one repository root per invocation. Multiple
449
451
  positional roots fail with exit code 2 instead of silently ignoring coverage.
@@ -461,7 +463,7 @@ For agents that support invokable skills, this repo ships a portable skill under
461
463
  ## GitHub Action
462
464
 
463
465
  ```yaml
464
- - uses: marshallguillory86/secure-code-agent@v0.12.0
466
+ - uses: marshallguillory86/secure-code-agent@v0.12.1
465
467
  with:
466
468
  config: secure-code-agent.json
467
469
  fail-on-gate: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secure-code-agent
3
- Version: 0.12.0
3
+ Version: 0.12.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
@@ -489,9 +489,11 @@ secure-code-agent --sarif-import codeql-results.sarif \
489
489
  --sarif-import snyk-results.sarif
490
490
  ```
491
491
 
492
- `--changed-only` is reserved but not yet safely implemented. Passing it fails
493
- with exit code 2 so a caller cannot accidentally treat an unscoped audit as a
494
- changed-file audit.
492
+ `--changed-only REF` scopes the **report** to files changed since `REF`. The
493
+ whole tree is still scanned — scanners read trees, not diffs — and **no grade
494
+ is issued**, because a run that looks at less must not score better. A ref git
495
+ cannot resolve is an error rather than an empty diff, since "nothing changed"
496
+ and "your ref is wrong" otherwise produce the same finding count.
495
497
 
496
498
  The current orchestrator accepts one repository root per invocation. Multiple
497
499
  positional roots fail with exit code 2 instead of silently ignoring coverage.
@@ -509,7 +511,7 @@ For agents that support invokable skills, this repo ships a portable skill under
509
511
  ## GitHub Action
510
512
 
511
513
  ```yaml
512
- - uses: marshallguillory86/secure-code-agent@v0.12.0
514
+ - uses: marshallguillory86/secure-code-agent@v0.12.1
513
515
  with:
514
516
  config: secure-code-agent.json
515
517
  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.0"
15
+ __version__ = "0.12.1"
@@ -297,7 +297,17 @@ def _summary_section(
297
297
  # No verdict means nobody decided this run could claim a grade, so it
298
298
  # cannot. Falling back to a locally-invented condition here is what put a
299
299
  # second decision rule in the codebase in the first place.
300
- if verdict is None or not verdict.is_verified:
300
+ if verdict is not None and verdict.untriaged:
301
+ # An untriaged run leads with the work, on every surface. The terminal
302
+ # did this from the day it shipped and the Markdown report did not, so
303
+ # the same audit said two different things depending on where it was
304
+ # read — and the report is the one a reviewer opens.
305
+ out.append(f"- **{verdict.headline()}**")
306
+ out.append(
307
+ " - The number is in the JSON and the trend. It is not the first "
308
+ "thing to say about a repository nobody has triaged yet."
309
+ )
310
+ elif verdict is None or not verdict.is_verified:
301
311
  if score.overall is None:
302
312
  out.append(
303
313
  "- **No score:** nothing measurable was scanned. This is not a "
@@ -541,11 +551,15 @@ def _pr_comment(
541
551
  # never caveat on its own terms.
542
552
  unverified = verdict is None or not verdict.is_verified
543
553
  score_label = "finding score, not a verified grade" if unverified else "verified grade"
544
- headline = (
545
- "no score — nothing measurable was scanned"
546
- if score.overall is None
547
- else f"{score_label} **{score.letter}** ({score.overall:.2f}/5.00)"
548
- )
554
+ if verdict is not None and verdict.untriaged:
555
+ # Same rule as the Markdown report and the terminal. A PR comment is
556
+ # the most widely read artifact this tool produces, so it is the worst
557
+ # place for a letter nobody has triaged to be the headline.
558
+ headline = verdict.headline()
559
+ elif score.overall is None:
560
+ headline = "no score — nothing measurable was scanned"
561
+ else:
562
+ headline = f"{score_label} **{score.letter}** ({score.overall:.2f}/5.00)"
549
563
  out = [
550
564
  f"### secure-code-agent {status} — {headline}",
551
565
  "",