phase-barrier 1.0.0.post1.dev0__tar.gz → 1.1.0.post1.dev0__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 (412) hide show
  1. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/ci.yml +2 -1
  2. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/learning-loop.yml +296 -296
  3. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/red-team.yml +119 -2
  4. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/CHANGELOG.md +16 -1
  5. {phase_barrier-1.0.0.post1.dev0/phase_barrier.egg-info → phase_barrier-1.1.0.post1.dev0}/PKG-INFO +16 -2
  6. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/README.md +9 -1
  7. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/__main__.py +18 -5
  8. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/__init__.py +5 -0
  9. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/cli.py +70 -0
  10. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/diff.py +88 -0
  11. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/events.py +54 -0
  12. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/permissions.py +206 -0
  13. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/scheduler.py +137 -0
  14. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/service.py +303 -0
  15. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/storage.py +63 -0
  16. phase_barrier-1.1.0.post1.dev0/anti_shortcut/control/tui.py +177 -0
  17. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/human_review.py +15 -15
  18. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/grpc_service.py +22 -0
  19. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/proxy.py +12 -12
  20. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/proxy_client.py +21 -4
  21. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/sdk.py +4 -0
  22. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/sidecar.py +58 -5
  23. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/skill.py +84 -20
  24. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/state.py +24 -0
  25. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/__init__.py +4 -0
  26. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/base.py +138 -0
  27. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/known_residual.yaml +2 -0
  28. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/results/2026-10-20/README.md +17 -0
  29. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/results/2026-10-20/red-team.json +1161 -0
  30. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/results/2026-10-20/verification.json +1000 -0
  31. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/run_control_red_team.py +20 -0
  32. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/techniques/__init__.py +8 -0
  33. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/techniques/break_glass_reuse.py +44 -0
  34. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/techniques/control_bypass.py +59 -0
  35. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/techniques/goal_binding_escape.py +60 -0
  36. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/techniques/policy_fail_open.py +45 -0
  37. phase_barrier-1.1.0.post1.dev0/benchmarks/control_red_team/techniques/task_state_skip.py +52 -0
  38. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/agent.py +3 -0
  39. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/run_red_team.py +8 -0
  40. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/__init__.py +2 -1
  41. phase_barrier-1.1.0.post1.dev0/benchmarks/swebench/manifests/scale50-lite-2026-10-20.json +324 -0
  42. phase_barrier-1.1.0.post1.dev0/benchmarks/swebench/manifests/scale50-lite-2026-10-20.md +24 -0
  43. phase_barrier-1.1.0.post1.dev0/docs/control-plane.md +215 -0
  44. phase_barrier-1.1.0.post1.dev0/docs/control-security.md +82 -0
  45. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/release.md +6 -0
  46. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/mkdocs.yml +2 -0
  47. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0/phase_barrier.egg-info}/PKG-INFO +16 -2
  48. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/SOURCES.txt +30 -0
  49. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/requires.txt +9 -0
  50. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/scm_file_list.json +30 -0
  51. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/scm_version.json +2 -2
  52. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/pyproject.toml +1 -0
  53. phase_barrier-1.1.0.post1.dev0/scripts/check_control_coverage.py +53 -0
  54. phase_barrier-1.1.0.post1.dev0/tests/test_control_plane.py +644 -0
  55. phase_barrier-1.1.0.post1.dev0/tests/test_control_security.py +256 -0
  56. phase_barrier-1.1.0.post1.dev0/tests/test_control_security_gates.py +63 -0
  57. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_red_team_techniques.py +8 -3
  58. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_sidecar_v21.py +2 -1
  59. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.gitattributes +0 -0
  60. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  61. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  62. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  63. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/ISSUE_TEMPLATE/plugin_submission.yml +0 -0
  64. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/actions/plugin-test/action.yml +0 -0
  65. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/docs.yml +0 -0
  66. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/plugin-check.yml +0 -0
  67. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/plugin-test.yml +0 -0
  68. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/plugin-verification.yml +0 -0
  69. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/release.yml +0 -0
  70. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.github/workflows/security.yml +0 -0
  71. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/.gitignore +0 -0
  72. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/CNAME +0 -0
  73. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/CONTRIBUTING.md +0 -0
  74. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/LICENSE +0 -0
  75. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/MANIFEST.in +0 -0
  76. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/action.yml +0 -0
  77. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/__init__.py +0 -0
  78. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/audit.py +0 -0
  79. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/config.py +0 -0
  80. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/__init__.py +0 -0
  81. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/_base.py +0 -0
  82. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/_common.py +0 -0
  83. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/behavior_audit.py +0 -0
  84. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/case_analysis.py +0 -0
  85. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/case_library.py +0 -0
  86. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/dual_review.py +0 -0
  87. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/formal_check.py +0 -0
  88. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/learned_rules.yaml +0 -0
  89. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/prompts/coverage_check.txt +0 -0
  90. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/prompts/tamper_check.txt +0 -0
  91. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/defense/requirement_template.py +0 -0
  92. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/evidence.py +0 -0
  93. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/formal/PhaseBarrier.cfg +0 -0
  94. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/formal/PhaseBarrier.tla +0 -0
  95. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/formal/__init__.py +0 -0
  96. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/init.py +0 -0
  97. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/integration.py +0 -0
  98. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/interceptors.py +0 -0
  99. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/__init__.py +0 -0
  100. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/base.py +0 -0
  101. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/cpp.py +0 -0
  102. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/csharp.py +0 -0
  103. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/dart.py +0 -0
  104. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/dotnet.py +0 -0
  105. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/go.py +0 -0
  106. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/java.py +0 -0
  107. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/javascript.py +0 -0
  108. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/js_count_tests.cjs +0 -0
  109. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/kotlin.py +0 -0
  110. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/php.py +0 -0
  111. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/python.py +0 -0
  112. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/ruby.py +0 -0
  113. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/rust.py +0 -0
  114. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/scala.py +0 -0
  115. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/languages/swift.py +0 -0
  116. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/paths.py +0 -0
  117. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/plugins.py +0 -0
  118. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/proto/__init__.py +0 -0
  119. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/proto/sidecar.proto +0 -0
  120. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/proto/sidecar_pb2.py +0 -0
  121. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/proto/sidecar_pb2_grpc.py +0 -0
  122. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/remote_audit.py +0 -0
  123. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/rules/__init__.py +0 -0
  124. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/semantic.py +0 -0
  125. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/validators.py +0 -0
  126. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/anti_shortcut/write_audit.py +0 -0
  127. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/bench.py +0 -0
  128. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/fuzz_parsers.py +0 -0
  129. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/fuzz_sidecar.py +0 -0
  130. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/__init__.py +0 -0
  131. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/known_residual.yaml +0 -0
  132. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/payloads.py +0 -0
  133. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/residuals.py +0 -0
  134. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/after/report.json +0 -0
  135. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/after/report.md +0 -0
  136. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/analysis_report.json +0 -0
  137. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/analysis_report.md +0 -0
  138. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/before/report.json +0 -0
  139. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/before/report.md +0 -0
  140. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/case_library.jsonl +0 -0
  141. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop/suggestions.json +0 -0
  142. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/README.md +0 -0
  143. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/after.json +0 -0
  144. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/analysis_report.json +0 -0
  145. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/analysis_report.md +0 -0
  146. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/apply.json +0 -0
  147. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/case_library.jsonl +0 -0
  148. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/promote.json +0 -0
  149. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/learning_loop_p1/suggestions.json +0 -0
  150. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/report.json +0 -0
  151. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/results/report.md +0 -0
  152. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/base.py +0 -0
  153. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/chains.py +0 -0
  154. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/compact_syntax.py +0 -0
  155. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/constraint_replace.py +0 -0
  156. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/constraint_weaken.py +0 -0
  157. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/coverage_disguise.py +0 -0
  158. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/equivalent_op.py +0 -0
  159. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/formal_evade.py +0 -0
  160. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/misc_attacks.py +0 -0
  161. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/obfuscated.py +0 -0
  162. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/risk_camouflage.py +0 -0
  163. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/session_attacks.py +0 -0
  164. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/template_filler.py +0 -0
  165. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/timing_evade.py +0 -0
  166. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/red_team/techniques/tool_chains.py +0 -0
  167. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swe_bench_gate.py +0 -0
  168. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/README.md +0 -0
  169. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/analyze_results.py +0 -0
  170. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/gold_check.py +0 -0
  171. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/grade.py +0 -0
  172. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/prepare_dataset.py +0 -0
  173. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/regrade_cross_shard.py +0 -0
  174. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/results/README.md +0 -0
  175. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/results/scale20_lite_container.csv +0 -0
  176. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/results/verified_regrade.csv +0 -0
  177. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench/run_agent.py +0 -0
  178. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/benchmarks/swebench_runner.py +0 -0
  179. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/Dockerfile +0 -0
  180. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/README.md +0 -0
  181. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/docker-compose.yml +0 -0
  182. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/Chart.yaml +0 -0
  183. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/README.md +0 -0
  184. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/NOTES.txt +0 -0
  185. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/_helpers.tpl +0 -0
  186. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/configmap.yaml +0 -0
  187. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/deployment.yaml +0 -0
  188. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/job-gatekeeper.yaml +0 -0
  189. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/pvc.yaml +0 -0
  190. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/secret.yaml +0 -0
  191. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/templates/service.yaml +0 -0
  192. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/helm/phase-barrier/values.yaml +0 -0
  193. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/README.md +0 -0
  194. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/e2e-values.yaml +0 -0
  195. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/e2e.Dockerfile +0 -0
  196. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/e2e_agent.py +0 -0
  197. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/gate-keeper.yaml +0 -0
  198. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/gate-sidecar.yaml +0 -0
  199. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/kind-e2e-test.sh +0 -0
  200. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/k8s/pvc.yaml +0 -0
  201. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/probe.py +0 -0
  202. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/deploy/seed_gate.py +0 -0
  203. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docker/demo/Dockerfile +0 -0
  204. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docker/demo/README.md +0 -0
  205. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docker/demo/agent_demo.py +0 -0
  206. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docker/demo/entrypoint.sh +0 -0
  207. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/CNAME +0 -0
  208. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/api.md +0 -0
  209. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/architecture.md +0 -0
  210. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/audit-logging.md +0 -0
  211. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/benchmarks/swe-bench-scale20.md +0 -0
  212. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/best-practices.md +0 -0
  213. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/blog/2026-08-29-phase-barrier-intro.md +0 -0
  214. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/blog/2026-09-12-swe-bench-scale20-en.md +0 -0
  215. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/blog/2026-09-12-swe-bench-scale20-zh.md +0 -0
  216. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/changelog.md +0 -0
  217. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/configuration.md +0 -0
  218. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/contributing.md +0 -0
  219. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/custom-domain.md +0 -0
  220. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/faq.md +0 -0
  221. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/five-lines.md +0 -0
  222. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/formal-invariants.md +0 -0
  223. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/github-action.md +0 -0
  224. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/index.md +0 -0
  225. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/integrations.md +0 -0
  226. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/k8s.md +0 -0
  227. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/languages.md +0 -0
  228. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/learning-defense.md +0 -0
  229. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/media/phase-barrier-demo.mp4 +0 -0
  230. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/orchestrator-hooks.md +0 -0
  231. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/plugin-status.md +0 -0
  232. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/plugins.md +0 -0
  233. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/promotion/README.md +0 -0
  234. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/promotion/outreach.md +0 -0
  235. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/publish-to-marketplace.md +0 -0
  236. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/quickstart.md +0 -0
  237. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/red-team.md +0 -0
  238. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/roadmap.md +0 -0
  239. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/security-rules.md +0 -0
  240. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/semantic-validation.md +0 -0
  241. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/tutorials/ci-incremental-gate.md +0 -0
  242. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/tutorials/k8s-sidecar-grpc.md +0 -0
  243. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/tutorials/swe-bench-gate.md +0 -0
  244. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/tutorials/swe-bench-real.md +0 -0
  245. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/usage.md +0 -0
  246. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/docs/video-tutorial-template.md +0 -0
  247. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/anti_shortcut_config.yaml +0 -0
  248. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/anti_shortcut_go_config.yaml +0 -0
  249. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/anti_shortcut_js_config.yaml +0 -0
  250. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/anti_shortcut_rust_config.yaml +0 -0
  251. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/autogpt_integration/README.md +0 -0
  252. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/autogpt_integration/gate_command_wrapper.py +0 -0
  253. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/custom_adapter/demo.py +0 -0
  254. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/custom_adapter/foo_config.yaml +0 -0
  255. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/custom_adapter/foo_language.py +0 -0
  256. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/custom_adapter/pyproject.toml +0 -0
  257. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/demo.py +0 -0
  258. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/github-action/evidence-gate.yml +0 -0
  259. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/github-action/gate-go.yml +0 -0
  260. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/github-action/gate-pr.yml +0 -0
  261. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/github-action/gate-rust.yml +0 -0
  262. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/github-action/gate.yml +0 -0
  263. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/k8s_proxy/README.md +0 -0
  264. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/k8s_proxy/demo.py +0 -0
  265. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/langchain_integration/README.md +0 -0
  266. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/langchain_integration/demo.py +0 -0
  267. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/langchain_integration/gate_tools.py +0 -0
  268. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/langchain_integration/phase_barrier_tool.py +0 -0
  269. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/minimal_agent.py +0 -0
  270. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_audit/README.md +0 -0
  271. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_audit/anti_shortcut_mtls.yaml +0 -0
  272. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_audit/demo.py +0 -0
  273. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_audit/generate_certs.py +0 -0
  274. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_audit/server.py +0 -0
  275. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_sidecar/README.md +0 -0
  276. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_sidecar/demo.py +0 -0
  277. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/mtls_sidecar/generate_certs.py +0 -0
  278. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/orchestrator_hooks/README.md +0 -0
  279. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/orchestrator_hooks/demo.py +0 -0
  280. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/orchestrator_hooks/multi_agent.py +0 -0
  281. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/plugin_rules/README.md +0 -0
  282. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/plugin_rules/demo.py +0 -0
  283. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/plugin_rules/phase_barrier_plugin/__init__.py +0 -0
  284. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/plugin_rules/pyproject.toml +0 -0
  285. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/semantic_llm_check/demo.py +0 -0
  286. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/semantic_llm_check/llm_semantic_check/__init__.py +0 -0
  287. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/semantic_llm_check/pyproject.toml +0 -0
  288. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/swe_agent_integration/README.md +0 -0
  289. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/swe_agent_integration/gate_tool.py +0 -0
  290. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/examples/swe_agent_integration/swe_agent_example.yaml +0 -0
  291. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/dependency_links.txt +0 -0
  292. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/entry_points.txt +0 -0
  293. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/phase_barrier.egg-info/top_level.txt +0 -0
  294. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/plugins.json +0 -0
  295. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/analyze_cases.py +0 -0
  296. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/auto_discover_plugins.py +0 -0
  297. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/check_custom_domain.py +0 -0
  298. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/cleanup_bench_dirs.py +0 -0
  299. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/cleanup_pytest_tmp.py +0 -0
  300. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/gen_grpc.sh +0 -0
  301. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/make_demo_video.py +0 -0
  302. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/pull_swebench_images.py +0 -0
  303. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/run_swebench_batch.py +0 -0
  304. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/run_swebench_batch_container.py +0 -0
  305. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/select_swe_tasks.py +0 -0
  306. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/update_rules.py +0 -0
  307. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/scripts/verify_plugins.py +0 -0
  308. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/setup.cfg +0 -0
  309. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/conftest.py +0 -0
  310. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/gradle-junit5-fail.txt +0 -0
  311. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/gradle-junit5-pass.txt +0 -0
  312. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/gradle-testng-fail.txt +0 -0
  313. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/junit-console-fail.txt +0 -0
  314. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/junit-console-pass.txt +0 -0
  315. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/surefire-junit5-errors-fail.txt +0 -0
  316. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/surefire-junit5-pass.txt +0 -0
  317. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/surefire-testng-skipped-variant.txt +0 -0
  318. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/testng-maven-fail.txt +0 -0
  319. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/java_outputs/testng-maven-pass.txt +0 -0
  320. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/README.md +0 -0
  321. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/plugin_alpha/__init__.py +0 -0
  322. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/plugin_alpha/integration.py +0 -0
  323. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/plugin_alpha/language.py +0 -0
  324. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/plugin_alpha/rules.py +0 -0
  325. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/plugin_alpha/validators.py +0 -0
  326. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/fixtures/plugin_alpha/pyproject.toml +0 -0
  327. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_action_meta.py +0 -0
  328. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_auto_discover.py +0 -0
  329. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_auto_discover_e2e.py +0 -0
  330. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_behavior_chain_audit.py +0 -0
  331. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_benchmarks.py +0 -0
  332. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_builtin_rules.py +0 -0
  333. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_check_custom_domain.py +0 -0
  334. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_cli.py +0 -0
  335. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_cli_extra_commands.py +0 -0
  336. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_cli_gate_commands.py +0 -0
  337. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_config.py +0 -0
  338. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_config_boundaries.py +0 -0
  339. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_cov_gate.py +0 -0
  340. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_cpp_adapter.py +0 -0
  341. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_csharp_adapter.py +0 -0
  342. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_dart_adapter.py +0 -0
  343. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_defense_edge_cases.py +0 -0
  344. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_defense_hardening.py +0 -0
  345. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_defense_lines.py +0 -0
  346. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_delivery_final_green.py +0 -0
  347. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_docker_demo.py +0 -0
  348. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_docs_consistency.py +0 -0
  349. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_docs_site.py +0 -0
  350. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_dotnet_adapter.py +0 -0
  351. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_evidence_manifest.py +0 -0
  352. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_formal_alignment.py +0 -0
  353. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_fuzz.py +0 -0
  354. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_fuzz_sidecar.py +0 -0
  355. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_gate_regressions.py +0 -0
  356. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_git_evidence_gate.py +0 -0
  357. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_go_adapter.py +0 -0
  358. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_grpc_service.py +0 -0
  359. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_grpc_service_direct.py +0 -0
  360. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_init.py +0 -0
  361. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_integration.py +0 -0
  362. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_integration_examples.py +0 -0
  363. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_interceptor_rules.py +0 -0
  364. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_interceptors.py +0 -0
  365. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_interceptors_redirection.py +0 -0
  366. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_java_adapter.py +0 -0
  367. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_java_output_parsing_matrix.py +0 -0
  368. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_javascript_adapter.py +0 -0
  369. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_key_rotation.py +0 -0
  370. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_kotlin_adapter.py +0 -0
  371. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_languages.py +0 -0
  372. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_learning_defense.py +0 -0
  373. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_make_demo_video.py +0 -0
  374. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_mtls_e2e.py +0 -0
  375. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_php_adapter.py +0 -0
  376. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_plugin_validators.py +0 -0
  377. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_plugin_verify.py +0 -0
  378. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_proxy_audit.py +0 -0
  379. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_red_team_agent.py +0 -0
  380. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_red_team_residuals.py +0 -0
  381. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_remote_audit.py +0 -0
  382. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_repo_hygiene.py +0 -0
  383. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_ruby_adapter.py +0 -0
  384. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_rust_adapter.py +0 -0
  385. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_scala_adapter.py +0 -0
  386. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_sdk.py +0 -0
  387. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_semantic.py +0 -0
  388. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_semantic_depth.py +0 -0
  389. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_semantic_naming.py +0 -0
  390. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_semantic_trace.py +0 -0
  391. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_sidecar.py +0 -0
  392. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_sidecar_audit_api.py +0 -0
  393. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_sidecar_proxy.py +0 -0
  394. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_skill.py +0 -0
  395. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_stage2_scope.py +0 -0
  396. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_state.py +0 -0
  397. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_state_concurrency.py +0 -0
  398. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_state_signing.py +0 -0
  399. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_subprocess_locale_hygiene.py +0 -0
  400. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_swe_bench_gate.py +0 -0
  401. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_swe_scripts.py +0 -0
  402. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_swebench_analysis.py +0 -0
  403. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_swebench_harness.py +0 -0
  404. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_swebench_runner.py +0 -0
  405. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_swift_adapter.py +0 -0
  406. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_v0130_edge_cases.py +0 -0
  407. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_v0140_edge_cases.py +0 -0
  408. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_v0160_edge_cases.py +0 -0
  409. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_validators.py +0 -0
  410. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_verify_plugins_index.py +0 -0
  411. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_workflows.py +0 -0
  412. {phase_barrier-1.0.0.post1.dev0 → phase_barrier-1.1.0.post1.dev0}/tests/test_write_audit.py +0 -0
@@ -1,8 +1,9 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
+ workflow_dispatch:
4
5
  push:
5
- branches: [main, master, codex/release-v1.0.0]
6
+ branches: [main, master]
6
7
  pull_request:
7
8
 
8
9
  concurrency:
@@ -1,298 +1,298 @@
1
- name: Learning loop
2
-
3
- # 路径 4 的半自动闭环(P1,v0.60.0):
4
- # 红队逃逸 -> 自动分析 -> 生成 PR(含来源案例 / 规则 diff / 复测结果)-> 人工审核合并
5
- #
6
- # 红线保持不变:**自动只到「建议 + PR」为止**,合入由人工在 PR 上完成。
7
- # 复测发现真实漏洞时不提 PR,改为建 issue(说明候选规则不够,需要人判断)。
8
- on:
9
- workflow_dispatch:
10
- schedule:
11
- - cron: '23 4 * * 1' # 每周一 04:23 UTC(排在红队全量 03:17 之后)
12
-
13
- permissions:
14
- contents: write
15
- pull-requests: write
16
- issues: write
17
-
18
- concurrency:
19
- group: learning-loop
20
- cancel-in-progress: false
21
-
22
- jobs:
23
- learning-loop:
24
- name: 案例 -> 建议 -> PR(人工审核)
25
- runs-on: ubuntu-latest
26
- steps:
27
- - uses: actions/checkout@v7
28
- with:
29
- fetch-depth: 0
30
- token: ${{ secrets.GITHUB_TOKEN }}
31
-
32
- - uses: actions/setup-python@v7
33
- with:
34
- python-version: '3.12'
35
- cache: pip
36
- cache-dependency-path: pyproject.toml
37
-
38
- - name: Install package and dev deps
39
- run: |
40
- python -m pip install --upgrade pip
41
- pip install -e ".[dev]"
42
-
43
- - name: Collect cases from red team (before)
44
- id: collect
45
- run: |
46
- # 注意:$RUNNER_TEMP 在 workspace 之外,hashFiles() 不稳定(拿不到就返回空串,
47
- # 后续步骤会被静默跳过、job 依旧全绿)。这里改用 step output 显式传递。
48
- python benchmarks/red_team/run_red_team.py \
49
- --workspace "$RUNNER_TEMP/rt-before" \
50
- --output "$RUNNER_TEMP/rt-before" \
51
- --case-library "$RUNNER_TEMP/case_library.jsonl" \
52
- --json > "$RUNNER_TEMP/before.json" \
53
- || echo "::warning::红队采集步骤非 0 退出(仍尝试用已产出的案例继续)"
54
- if [ -s "$RUNNER_TEMP/case_library.jsonl" ]; then
55
- count="$(grep -c . "$RUNNER_TEMP/case_library.jsonl" || echo 0)"
56
- echo "has_cases=true" >> "$GITHUB_OUTPUT"
57
- echo "case_count=$count" >> "$GITHUB_OUTPUT"
58
- echo "采集到 $count 条案例"
59
- else
60
- echo "has_cases=false" >> "$GITHUB_OUTPUT"
61
- echo "::warning::本次红队未采集到任何案例,学习闭环无输入,跳过后续步骤"
62
- fi
63
-
64
- - name: Analyze cases and build suggestions
65
- if: ${{ steps.collect.outputs.has_cases == 'true' }}
66
- run: |
67
- python scripts/analyze_cases.py \
68
- --cases "$RUNNER_TEMP/case_library.jsonl" \
69
- --report "$RUNNER_TEMP/analysis.json" \
70
- --markdown "$RUNNER_TEMP/analysis.md" \
71
- --suggestions "$RUNNER_TEMP/suggestions.json" --json \
72
- > "$RUNNER_TEMP/analyze.json"
73
-
74
- - name: Apply verified suggestions (dry-run first)
75
- if: ${{ steps.collect.outputs.has_cases == 'true' }}
76
- run: |
77
- python scripts/update_rules.py \
78
- --suggestions "$RUNNER_TEMP/suggestions.json" \
79
- --dest anti_shortcut/defense/learned_rules.yaml \
80
- --verify-cases "$RUNNER_TEMP/case_library.jsonl" --json \
81
- > "$RUNNER_TEMP/apply_dry.json"
82
- python scripts/update_rules.py \
83
- --suggestions "$RUNNER_TEMP/suggestions.json" \
84
- --dest anti_shortcut/defense/learned_rules.yaml \
85
- --verify-cases "$RUNNER_TEMP/case_library.jsonl" --apply --json \
86
- > "$RUNNER_TEMP/apply.json"
87
-
88
- - name: Re-run red team with the candidate rules
89
- if: ${{ steps.collect.outputs.has_cases == 'true' }}
90
- id: retest
91
- run: |
92
- # --fail-on-vulnerability 是这条判定的唯一依据:不加它时脚本无论是否
93
- # 发现真实漏洞都返回 0,clean 会恒为 true,issue 分支永远不会走到。
94
- if python benchmarks/red_team/run_red_team.py \
95
- --workspace "$RUNNER_TEMP/rt-after" \
96
- --output "$RUNNER_TEMP/rt-after" \
97
- --fail-on-vulnerability \
98
- --json > "$RUNNER_TEMP/after.json"; then
99
- echo "clean=true" >> "$GITHUB_OUTPUT"
100
- else
101
- echo "clean=false" >> "$GITHUB_OUTPUT"
102
- # 非 0 退出也会先把 JSON 打到 stdout(main() 先输出后返回 1),
103
- # 所以这里只能补空文件,不能直接覆盖 —— 覆盖等于把失败证据(漏洞明细)删掉。
104
- [ -s "$RUNNER_TEMP/after.json" ] || echo '{}' > "$RUNNER_TEMP/after.json"
105
- fi
106
-
107
- - name: Promote confirmed rules
108
- if: ${{ steps.retest.outputs.clean == 'true' }}
109
- run: |
110
- python scripts/update_rules.py --dest anti_shortcut/defense/learned_rules.yaml \
111
- --promote --confirmations-required 3 --apply --json \
112
- > "$RUNNER_TEMP/promote.json"
113
-
114
- - name: Build PR body
115
- if: ${{ steps.collect.outputs.has_cases == 'true' }}
116
- run: |
117
- {
118
- echo "## 学习闭环自动产物(需要人工审核)"
119
- echo
120
- echo "本 PR 由 `.github/workflows/learning-loop.yml` 生成:红队案例 -> 模式提取 -> 候选规则。"
121
- echo "**规则不会自动上线**,合并前请核对来源案例与复测结果。"
122
- echo
123
- echo "### 1. 规则 diff"
124
- echo '```diff'
125
- git diff -- anti_shortcut/defense/learned_rules.yaml || true
126
- echo '```'
127
- echo
128
- echo "### 2. 来源案例与提取报告"
129
- cat "$RUNNER_TEMP/analysis.md" 2>/dev/null || echo "(无分析报告)"
130
- echo
131
- echo "### 3. 预期拦截效果与复测结果"
132
- echo "- 候选规则的反查:必须命中它来自的案例原文(`--verify-cases`),否则已被丢弃。"
133
- echo "- 复测(加载候选规则后重跑红队全量):**${{ steps.retest.outputs.clean == 'true' && '通过(真实漏洞 0)' || '失败(仍有漏洞,见 issue)' }}**"
134
- echo '```json'
135
- head -c 4000 "$RUNNER_TEMP/after.json" 2>/dev/null || echo '{}'
136
- echo '```'
137
- echo
138
- echo "### 4. 人工审核清单"
139
- echo "- [ ] 规则是否真的对应「被禁止的语义」,而不是误伤正常写法?"
140
- echo "- [ ] 来源案例是否属于同类攻击(而不是巧合命中)?"
141
- echo "- [ ] 复测是否在**加载本 PR 规则**的前提下通过?"
142
- echo "- [ ] 是否需要补充回归测试(`tests/test_behavior_chain_audit.py` 风格)?"
143
- echo
144
- echo "_自动化只到建议为止;合入后规则会进入 `observation`,经 N 次红队复测无误后由 `--promote` 升级为 `active`。_"
145
- } > "$RUNNER_TEMP/pr_body.md"
146
-
147
- - name: Open PR (or issue when the re-test still finds holes)
148
- if: ${{ steps.collect.outputs.has_cases == 'true' }}
149
- env:
150
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151
- run: |
152
- if git diff --quiet -- anti_shortcut/defense/learned_rules.yaml; then
153
- echo "候选规则与现有规则一致,无 PR 需要创建"
154
- exit 0
155
- fi
156
- run_date="$(date -u +%Y%m%d)"
157
- # 标签不存在时 `gh pr create --label` 会直接报错、PR 根本不会创建;
158
- # 这里按需创建(存在则不动),而不是用 `|| true` 把失败吞掉。
159
- ensure_label() {
160
- gh label list --limit 200 --json name --jq '.[].name' | grep -qx "$1" || \
161
- gh label create "$1" --color "$2" --description "$3"
162
- }
163
- ensure_label defense 1D76DB "防御门禁/防线相关"
164
- ensure_label learning-loop FBCA04 "学习闭环自动产物(需人工审核)"
165
- if [ "${{ steps.retest.outputs.clean }}" != "true" ]; then
166
- gh issue create \
167
- --title "学习闭环复测未通过:$run_date" \
168
- --body-file "$RUNNER_TEMP/pr_body.md" \
169
- --label "defense,learning-loop"
170
- exit 0
171
- fi
172
- branch="learning-loop/$run_date-${{ github.run_id }}"
173
- base="${{ github.event.repository.default_branch }}"
174
- # 提交身份使用维护者(GitHub noreply 邮箱),避免 github-actions[bot]
175
- # 被计入仓库贡献者侧边栏;PR 仍由 GITHUB_TOKEN 创建,不影响审核流程。
176
- git config user.name "Xuqing0415"
177
- git config user.email "248270291+Xuqing0415@users.noreply.github.com"
178
- git checkout -b "$branch"
179
- git add anti_shortcut/defense/learned_rules.yaml
180
- git commit -m "feat(defense): 学习闭环候选规则($run_date,人工审核后合入)"
181
- git push -u origin "$branch"
182
- # 仓库若没开 Settings -> Actions -> General 里的
183
- # 「Allow GitHub Actions to create and approve pull requests」,
184
- # GITHUB_TOKEN 建 PR 会被拒(GraphQL: not permitted to create or approve
185
- # pull requests),分支却已经推上去了。这里降级为「issue + 一键建 PR 链接」,
186
- # 既保留人工审核环节,也不把「环境开关没开」误报成代码缺陷。
187
- if pr_error="$(gh pr create \
188
- --base "$base" \
189
- --head "$branch" \
190
- --title "学习闭环候选规则($run_date)" \
191
- --body-file "$RUNNER_TEMP/pr_body.md" \
192
- --label "defense,learning-loop" 2>&1)"; then
193
- echo "$pr_error"
194
- exit 0
195
- fi
196
- echo "::warning::自动建 PR 失败,降级为 issue(分支 $branch 已推送):$pr_error"
197
- compare="https://github.com/${GITHUB_REPOSITORY}/compare/${base}...${branch}?expand=1"
198
- {
199
- echo
200
- echo "---"
201
- echo "### ⚠️ 自动建 PR 失败,需要人工一键创建"
202
- echo '```'
203
- echo "$pr_error"
204
- echo '```'
205
- echo "候选规则分支 \`${branch}\` 已推送。若报的是 createPullRequest 权限问题,"
206
- echo "可在 **Settings → Actions → General → Workflow permissions** 勾选 "
207
- echo "**Allow GitHub Actions to create and approve pull requests** 后重跑本 workflow。"
208
- echo
209
- echo "👉 [点击创建 PR](${compare})"
210
- } >> "$RUNNER_TEMP/pr_body.md"
211
- gh issue create \
212
- --title "学习闭环候选规则($run_date,需人工开 PR)" \
213
- --body-file "$RUNNER_TEMP/pr_body.md" \
214
- --label "defense,learning-loop"
215
-
216
- - name: Run summary
217
- if: always()
218
- env:
219
- CASE_COUNT: ${{ steps.collect.outputs.case_count }}
220
- RETEST_CLEAN: ${{ steps.retest.outputs.clean }}
221
- EVENT_NAME: ${{ github.event_name }}
222
- run: |
223
- # 每次运行都留一份人可读摘要,避免「配了但没跑 / 跑了没产出」无从察觉。
224
- if git diff --quiet -- anti_shortcut/defense/learned_rules.yaml; then
225
- rules_state="无候选变更"
226
- else
227
- rules_state="有候选变更(已开 PR 或 issue)"
228
- fi
229
- {
230
- echo "## 学习闭环运行摘要"
231
- echo
232
- echo "| 项 | 值 |"
233
- echo "|---|---|"
234
- echo "| 触发方式 | ${EVENT_NAME} |"
235
- echo "| 采集到案例 | ${CASE_COUNT:-0} 条 |"
236
- echo "| 复测结果 | ${RETEST_CLEAN:-未执行} |"
237
- echo "| 候选规则 | ${rules_state} |"
238
- echo "| run | [${GITHUB_RUN_ID}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) |"
239
- } >> "$GITHUB_STEP_SUMMARY"
240
-
241
- output-healthcheck:
242
- name: 产出健康检查(连续 2 周无候选则告警)
243
- runs-on: ubuntu-latest
244
- permissions:
245
- actions: read
246
- issues: write
247
- pull-requests: read
248
- contents: read
249
- steps:
250
- - uses: actions/checkout@v7
1
+ name: Learning loop
2
+
3
+ # 路径 4 的半自动闭环(P1,v0.60.0):
4
+ # 红队逃逸 -> 自动分析 -> 生成 PR(含来源案例 / 规则 diff / 复测结果)-> 人工审核合并
5
+ #
6
+ # 红线保持不变:**自动只到「建议 + PR」为止**,合入由人工在 PR 上完成。
7
+ # 复测发现真实漏洞时不提 PR,改为建 issue(说明候选规则不够,需要人判断)。
8
+ on:
9
+ workflow_dispatch:
10
+ schedule:
11
+ - cron: '23 4 * * 1' # 每周一 04:23 UTC(排在红队全量 03:17 之后)
12
+
13
+ permissions:
14
+ contents: write
15
+ pull-requests: write
16
+ issues: write
17
+
18
+ concurrency:
19
+ group: learning-loop
20
+ cancel-in-progress: false
21
+
22
+ jobs:
23
+ learning-loop:
24
+ name: 案例 -> 建议 -> PR(人工审核)
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v7
28
+ with:
29
+ fetch-depth: 0
30
+ token: ${{ secrets.GITHUB_TOKEN }}
31
+
32
+ - uses: actions/setup-python@v7
33
+ with:
34
+ python-version: '3.12'
35
+ cache: pip
36
+ cache-dependency-path: pyproject.toml
37
+
38
+ - name: Install package and dev deps
39
+ run: |
40
+ python -m pip install --upgrade pip
41
+ pip install -e ".[dev]"
42
+
43
+ - name: Collect cases from red team (before)
44
+ id: collect
45
+ run: |
46
+ # 注意:$RUNNER_TEMP 在 workspace 之外,hashFiles() 不稳定(拿不到就返回空串,
47
+ # 后续步骤会被静默跳过、job 依旧全绿)。这里改用 step output 显式传递。
48
+ python benchmarks/red_team/run_red_team.py \
49
+ --workspace "$RUNNER_TEMP/rt-before" \
50
+ --output "$RUNNER_TEMP/rt-before" \
51
+ --case-library "$RUNNER_TEMP/case_library.jsonl" \
52
+ --json > "$RUNNER_TEMP/before.json" \
53
+ || echo "::warning::红队采集步骤非 0 退出(仍尝试用已产出的案例继续)"
54
+ if [ -s "$RUNNER_TEMP/case_library.jsonl" ]; then
55
+ count="$(grep -c . "$RUNNER_TEMP/case_library.jsonl" || echo 0)"
56
+ echo "has_cases=true" >> "$GITHUB_OUTPUT"
57
+ echo "case_count=$count" >> "$GITHUB_OUTPUT"
58
+ echo "采集到 $count 条案例"
59
+ else
60
+ echo "has_cases=false" >> "$GITHUB_OUTPUT"
61
+ echo "::warning::本次红队未采集到任何案例,学习闭环无输入,跳过后续步骤"
62
+ fi
63
+
64
+ - name: Analyze cases and build suggestions
65
+ if: ${{ steps.collect.outputs.has_cases == 'true' }}
66
+ run: |
67
+ python scripts/analyze_cases.py \
68
+ --cases "$RUNNER_TEMP/case_library.jsonl" \
69
+ --report "$RUNNER_TEMP/analysis.json" \
70
+ --markdown "$RUNNER_TEMP/analysis.md" \
71
+ --suggestions "$RUNNER_TEMP/suggestions.json" --json \
72
+ > "$RUNNER_TEMP/analyze.json"
73
+
74
+ - name: Apply verified suggestions (dry-run first)
75
+ if: ${{ steps.collect.outputs.has_cases == 'true' }}
76
+ run: |
77
+ python scripts/update_rules.py \
78
+ --suggestions "$RUNNER_TEMP/suggestions.json" \
79
+ --dest anti_shortcut/defense/learned_rules.yaml \
80
+ --verify-cases "$RUNNER_TEMP/case_library.jsonl" --json \
81
+ > "$RUNNER_TEMP/apply_dry.json"
82
+ python scripts/update_rules.py \
83
+ --suggestions "$RUNNER_TEMP/suggestions.json" \
84
+ --dest anti_shortcut/defense/learned_rules.yaml \
85
+ --verify-cases "$RUNNER_TEMP/case_library.jsonl" --apply --json \
86
+ > "$RUNNER_TEMP/apply.json"
87
+
88
+ - name: Re-run red team with the candidate rules
89
+ if: ${{ steps.collect.outputs.has_cases == 'true' }}
90
+ id: retest
91
+ run: |
92
+ # --fail-on-vulnerability 是这条判定的唯一依据:不加它时脚本无论是否
93
+ # 发现真实漏洞都返回 0,clean 会恒为 true,issue 分支永远不会走到。
94
+ if python benchmarks/red_team/run_red_team.py \
95
+ --workspace "$RUNNER_TEMP/rt-after" \
96
+ --output "$RUNNER_TEMP/rt-after" \
97
+ --fail-on-vulnerability \
98
+ --json > "$RUNNER_TEMP/after.json"; then
99
+ echo "clean=true" >> "$GITHUB_OUTPUT"
100
+ else
101
+ echo "clean=false" >> "$GITHUB_OUTPUT"
102
+ # 非 0 退出也会先把 JSON 打到 stdout(main() 先输出后返回 1),
103
+ # 所以这里只能补空文件,不能直接覆盖 —— 覆盖等于把失败证据(漏洞明细)删掉。
104
+ [ -s "$RUNNER_TEMP/after.json" ] || echo '{}' > "$RUNNER_TEMP/after.json"
105
+ fi
106
+
107
+ - name: Promote confirmed rules
108
+ if: ${{ steps.retest.outputs.clean == 'true' }}
109
+ run: |
110
+ python scripts/update_rules.py --dest anti_shortcut/defense/learned_rules.yaml \
111
+ --promote --confirmations-required 3 --apply --json \
112
+ > "$RUNNER_TEMP/promote.json"
113
+
114
+ - name: Build PR body
115
+ if: ${{ steps.collect.outputs.has_cases == 'true' }}
116
+ run: |
117
+ {
118
+ echo "## 学习闭环自动产物(需要人工审核)"
119
+ echo
120
+ echo "本 PR 由 `.github/workflows/learning-loop.yml` 生成:红队案例 -> 模式提取 -> 候选规则。"
121
+ echo "**规则不会自动上线**,合并前请核对来源案例与复测结果。"
122
+ echo
123
+ echo "### 1. 规则 diff"
124
+ echo '```diff'
125
+ git diff -- anti_shortcut/defense/learned_rules.yaml || true
126
+ echo '```'
127
+ echo
128
+ echo "### 2. 来源案例与提取报告"
129
+ cat "$RUNNER_TEMP/analysis.md" 2>/dev/null || echo "(无分析报告)"
130
+ echo
131
+ echo "### 3. 预期拦截效果与复测结果"
132
+ echo "- 候选规则的反查:必须命中它来自的案例原文(`--verify-cases`),否则已被丢弃。"
133
+ echo "- 复测(加载候选规则后重跑红队全量):**${{ steps.retest.outputs.clean == 'true' && '通过(真实漏洞 0)' || '失败(仍有漏洞,见 issue)' }}**"
134
+ echo '```json'
135
+ head -c 4000 "$RUNNER_TEMP/after.json" 2>/dev/null || echo '{}'
136
+ echo '```'
137
+ echo
138
+ echo "### 4. 人工审核清单"
139
+ echo "- [ ] 规则是否真的对应「被禁止的语义」,而不是误伤正常写法?"
140
+ echo "- [ ] 来源案例是否属于同类攻击(而不是巧合命中)?"
141
+ echo "- [ ] 复测是否在**加载本 PR 规则**的前提下通过?"
142
+ echo "- [ ] 是否需要补充回归测试(`tests/test_behavior_chain_audit.py` 风格)?"
143
+ echo
144
+ echo "_自动化只到建议为止;合入后规则会进入 `observation`,经 N 次红队复测无误后由 `--promote` 升级为 `active`。_"
145
+ } > "$RUNNER_TEMP/pr_body.md"
146
+
147
+ - name: Open PR (or issue when the re-test still finds holes)
148
+ if: ${{ steps.collect.outputs.has_cases == 'true' }}
149
+ env:
150
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151
+ run: |
152
+ if git diff --quiet -- anti_shortcut/defense/learned_rules.yaml; then
153
+ echo "候选规则与现有规则一致,无 PR 需要创建"
154
+ exit 0
155
+ fi
156
+ run_date="$(date -u +%Y%m%d)"
157
+ # 标签不存在时 `gh pr create --label` 会直接报错、PR 根本不会创建;
158
+ # 这里按需创建(存在则不动),而不是用 `|| true` 把失败吞掉。
159
+ ensure_label() {
160
+ gh label list --limit 200 --json name --jq '.[].name' | grep -qx "$1" || \
161
+ gh label create "$1" --color "$2" --description "$3"
162
+ }
163
+ ensure_label defense 1D76DB "防御门禁/防线相关"
164
+ ensure_label learning-loop FBCA04 "学习闭环自动产物(需人工审核)"
165
+ if [ "${{ steps.retest.outputs.clean }}" != "true" ]; then
166
+ gh issue create \
167
+ --title "学习闭环复测未通过:$run_date" \
168
+ --body-file "$RUNNER_TEMP/pr_body.md" \
169
+ --label "defense,learning-loop"
170
+ exit 0
171
+ fi
172
+ branch="learning-loop/$run_date-${{ github.run_id }}"
173
+ base="${{ github.event.repository.default_branch }}"
174
+ # 提交身份使用维护者(GitHub noreply 邮箱),避免 github-actions[bot]
175
+ # 被计入仓库贡献者侧边栏;PR 仍由 GITHUB_TOKEN 创建,不影响审核流程。
176
+ git config user.name "Xuqing0415"
177
+ git config user.email "248270291+Xuqing0415@users.noreply.github.com"
178
+ git checkout -b "$branch"
179
+ git add anti_shortcut/defense/learned_rules.yaml
180
+ git commit -m "feat(defense): 学习闭环候选规则($run_date,人工审核后合入)"
181
+ git push -u origin "$branch"
182
+ # 仓库若没开 Settings -> Actions -> General 里的
183
+ # 「Allow GitHub Actions to create and approve pull requests」,
184
+ # GITHUB_TOKEN 建 PR 会被拒(GraphQL: not permitted to create or approve
185
+ # pull requests),分支却已经推上去了。这里降级为「issue + 一键建 PR 链接」,
186
+ # 既保留人工审核环节,也不把「环境开关没开」误报成代码缺陷。
187
+ if pr_error="$(gh pr create \
188
+ --base "$base" \
189
+ --head "$branch" \
190
+ --title "学习闭环候选规则($run_date)" \
191
+ --body-file "$RUNNER_TEMP/pr_body.md" \
192
+ --label "defense,learning-loop" 2>&1)"; then
193
+ echo "$pr_error"
194
+ exit 0
195
+ fi
196
+ echo "::warning::自动建 PR 失败,降级为 issue(分支 $branch 已推送):$pr_error"
197
+ compare="https://github.com/${GITHUB_REPOSITORY}/compare/${base}...${branch}?expand=1"
198
+ {
199
+ echo
200
+ echo "---"
201
+ echo "### ⚠️ 自动建 PR 失败,需要人工一键创建"
202
+ echo '```'
203
+ echo "$pr_error"
204
+ echo '```'
205
+ echo "候选规则分支 \`${branch}\` 已推送。若报的是 createPullRequest 权限问题,"
206
+ echo "可在 **Settings → Actions → General → Workflow permissions** 勾选 "
207
+ echo "**Allow GitHub Actions to create and approve pull requests** 后重跑本 workflow。"
208
+ echo
209
+ echo "👉 [点击创建 PR](${compare})"
210
+ } >> "$RUNNER_TEMP/pr_body.md"
211
+ gh issue create \
212
+ --title "学习闭环候选规则($run_date,需人工开 PR)" \
213
+ --body-file "$RUNNER_TEMP/pr_body.md" \
214
+ --label "defense,learning-loop"
215
+
216
+ - name: Run summary
217
+ if: always()
218
+ env:
219
+ CASE_COUNT: ${{ steps.collect.outputs.case_count }}
220
+ RETEST_CLEAN: ${{ steps.retest.outputs.clean }}
221
+ EVENT_NAME: ${{ github.event_name }}
222
+ run: |
223
+ # 每次运行都留一份人可读摘要,避免「配了但没跑 / 跑了没产出」无从察觉。
224
+ if git diff --quiet -- anti_shortcut/defense/learned_rules.yaml; then
225
+ rules_state="无候选变更"
226
+ else
227
+ rules_state="有候选变更(已开 PR 或 issue)"
228
+ fi
229
+ {
230
+ echo "## 学习闭环运行摘要"
231
+ echo
232
+ echo "| 项 | 值 |"
233
+ echo "|---|---|"
234
+ echo "| 触发方式 | ${EVENT_NAME} |"
235
+ echo "| 采集到案例 | ${CASE_COUNT:-0} 条 |"
236
+ echo "| 复测结果 | ${RETEST_CLEAN:-未执行} |"
237
+ echo "| 候选规则 | ${rules_state} |"
238
+ echo "| run | [${GITHUB_RUN_ID}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) |"
239
+ } >> "$GITHUB_STEP_SUMMARY"
240
+
241
+ output-healthcheck:
242
+ name: 产出健康检查(连续 2 周无候选则告警)
243
+ runs-on: ubuntu-latest
244
+ permissions:
245
+ actions: read
246
+ issues: write
247
+ pull-requests: read
248
+ contents: read
249
+ steps:
250
+ - uses: actions/checkout@v7
251
251
  with:
252
252
  fetch-depth: 1
253
- - name: Alert when the loop produced nothing for 2 weeks
254
- env:
255
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
256
- run: |
257
- # 学习闭环的价值在于「持续产出候选规则」。若连续 14 天没有任何带
258
- # learning-loop 标签的 PR/issue,说明它要么没跑、要么跑了没产出,
259
- # 这时自动开 issue 提醒维护者,而不是让 job 静默全绿。
260
- set -euo pipefail
261
- gh label list --limit 200 --json name --jq '.[].name' | grep -qx "defense" || \
262
- gh label create "defense" --color 1D76DB --description "防御门禁/防线相关"
263
- gh label list --limit 200 --json name --jq '.[].name' | grep -qx "learning-loop" || \
264
- gh label create "learning-loop" --color FBCA04 --description "学习闭环自动产物(需人工审核)"
265
- latest="$(gh api "repos/${GITHUB_REPOSITORY}/issues?labels=learning-loop&state=all&sort=created&direction=desc&per_page=1" --jq '.[0].created_at // ""')"
266
- now="$(date -u +%s)"
267
- if [ -n "$latest" ]; then
268
- age_days=$(( (now - $(date -u -d "$latest" +%s)) / 86400 ))
269
- else
270
- age_days=999
271
- fi
272
- echo "最近一次学习闭环产出:${latest:-无}(${age_days} 天前)"
273
- if [ "$age_days" -lt 14 ]; then
274
- echo "未超过 14 天,无需告警"
275
- exit 0
276
- fi
277
- open_alerts="$(gh issue list --state open --label learning-loop --json title \
278
- --jq '[.[] | select(.title | startswith("学习闭环连续 2 周无产出"))] | length')"
279
- if [ "$open_alerts" != "0" ]; then
280
- echo "已有未关闭的同类告警,跳过"
281
- exit 0
282
- fi
283
- gh issue create \
284
- --title "学习闭环连续 2 周无产出(截至 $(date -u +%Y-%m-%d))" \
285
- --label "defense,learning-loop" \
286
- --body "$(cat <<'BODY'
287
- 学习闭环(`.github/workflows/learning-loop.yml`)已连续 14 天没有产出任何候选规则 PR/issue。
288
-
289
- 请按顺序排查:
290
-
291
- 1. 该 workflow 近期是否真的在跑(Actions -> Learning loop;schedule 为每周一 04:23 UTC)。
292
- 2. 运行摘要(job summary)里「采集到案例」是否为 0——红队没采到案例则闭环无输入。
293
- 3. 若采集正常但没有候选,说明现有规则已覆盖当前逃逸技术(属于正常稳态),
294
- 可关闭本 issue 或考虑扩充红队逃逸技术库。
295
- 4. 若是权限问题(自动建 PR 被拒),确认 Settings -> Actions -> General 已勾选
296
- 「Allow GitHub Actions to create and approve pull requests」。
297
- BODY
298
- )"
253
+ - name: Alert when the loop produced nothing for 2 weeks
254
+ env:
255
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
256
+ run: |
257
+ # 学习闭环的价值在于「持续产出候选规则」。若连续 14 天没有任何带
258
+ # learning-loop 标签的 PR/issue,说明它要么没跑、要么跑了没产出,
259
+ # 这时自动开 issue 提醒维护者,而不是让 job 静默全绿。
260
+ set -euo pipefail
261
+ gh label list --limit 200 --json name --jq '.[].name' | grep -qx "defense" || \
262
+ gh label create "defense" --color 1D76DB --description "防御门禁/防线相关"
263
+ gh label list --limit 200 --json name --jq '.[].name' | grep -qx "learning-loop" || \
264
+ gh label create "learning-loop" --color FBCA04 --description "学习闭环自动产物(需人工审核)"
265
+ latest="$(gh api "repos/${GITHUB_REPOSITORY}/issues?labels=learning-loop&state=all&sort=created&direction=desc&per_page=1" --jq '.[0].created_at // ""')"
266
+ now="$(date -u +%s)"
267
+ if [ -n "$latest" ]; then
268
+ age_days=$(( (now - $(date -u -d "$latest" +%s)) / 86400 ))
269
+ else
270
+ age_days=999
271
+ fi
272
+ echo "最近一次学习闭环产出:${latest:-无}(${age_days} 天前)"
273
+ if [ "$age_days" -lt 14 ]; then
274
+ echo "未超过 14 天,无需告警"
275
+ exit 0
276
+ fi
277
+ open_alerts="$(gh issue list --state open --label learning-loop --json title \
278
+ --jq '[.[] | select(.title | startswith("学习闭环连续 2 周无产出"))] | length')"
279
+ if [ "$open_alerts" != "0" ]; then
280
+ echo "已有未关闭的同类告警,跳过"
281
+ exit 0
282
+ fi
283
+ gh issue create \
284
+ --title "学习闭环连续 2 周无产出(截至 $(date -u +%Y-%m-%d))" \
285
+ --label "defense,learning-loop" \
286
+ --body "$(cat <<'BODY'
287
+ 学习闭环(`.github/workflows/learning-loop.yml`)已连续 14 天没有产出任何候选规则 PR/issue。
288
+
289
+ 请按顺序排查:
290
+
291
+ 1. 该 workflow 近期是否真的在跑(Actions -> Learning loop;schedule 为每周一 04:23 UTC)。
292
+ 2. 运行摘要(job summary)里「采集到案例」是否为 0——红队没采到案例则闭环无输入。
293
+ 3. 若采集正常但没有候选,说明现有规则已覆盖当前逃逸技术(属于正常稳态),
294
+ 可关闭本 issue 或考虑扩充红队逃逸技术库。
295
+ 4. 若是权限问题(自动建 PR 被拒),确认 Settings -> Actions -> General 已勾选
296
+ 「Allow GitHub Actions to create and approve pull requests」。
297
+ BODY
298
+ )"