plugin-scanner 2.0.141__tar.gz → 2.0.143__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 (434) hide show
  1. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/PKG-INFO +1 -1
  2. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/guard-types.ts +1 -0
  3. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/settings-workspace.tsx +60 -2
  4. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/release-notes.md +19 -0
  5. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/pyproject.toml +1 -1
  6. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/pyproject.toml.bak +1 -1
  7. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/approvals.py +2 -0
  8. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +37 -0
  9. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +5 -0
  10. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/store.py +13 -0
  11. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/version.py +1 -1
  12. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_daemon_perf.py +116 -0
  13. plugin_scanner-2.0.143/tests/test_guard_harness_smoke.py +351 -0
  14. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.clusterfuzzlite/Dockerfile +0 -0
  15. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.clusterfuzzlite/build.sh +0 -0
  16. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.clusterfuzzlite/project.yaml +0 -0
  17. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.clusterfuzzlite/requirements-atheris.txt +0 -0
  18. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.dockerignore +0 -0
  19. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/CODEOWNERS +0 -0
  20. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  21. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  22. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  23. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/dependabot.yml +0 -0
  24. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/ci.yml +0 -0
  25. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/codeql.yml +0 -0
  26. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/dependabot-uv-lock.yml +0 -0
  27. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/fuzz.yml +0 -0
  28. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/harness-smoke.yml +0 -0
  29. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/publish.yml +0 -0
  30. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.github/workflows/scorecard.yml +0 -0
  31. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.gitignore +0 -0
  32. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/.pre-commit-hooks.yaml +0 -0
  33. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/CONTRIBUTING.md +0 -0
  34. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/Dockerfile +0 -0
  35. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/LICENSE +0 -0
  36. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/README.md +0 -0
  37. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/SECURITY.md +0 -0
  38. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/index.html +0 -0
  39. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/package.json +0 -0
  40. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/pnpm-lock.yaml +0 -0
  41. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/public/apple-touch-icon.png +0 -0
  42. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
  43. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/public/brand/Logo_Whole.png +0 -0
  44. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/public/favicon-16x16.png +0 -0
  45. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/public/favicon-32x32.png +0 -0
  46. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/public/favicon.ico +0 -0
  47. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/app.tsx +0 -0
  48. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/approval-center-layout.test.ts +0 -0
  49. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/approval-center-layout.tsx +0 -0
  50. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/approval-center-primitives.tsx +0 -0
  51. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/approval-center-review-cards.tsx +0 -0
  52. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/approval-center-utils.ts +0 -0
  53. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/data-flow-evidence-card.tsx +0 -0
  54. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/fleet-workspace.tsx +0 -0
  55. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/guard-api.test.ts +0 -0
  56. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/guard-api.ts +0 -0
  57. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/guard-demo.ts +0 -0
  58. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/main.tsx +0 -0
  59. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/receipts-workspace.test.ts +0 -0
  60. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/receipts-workspace.tsx +0 -0
  61. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/risk-signal-cards.test.ts +0 -0
  62. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/risk-signal-cards.tsx +0 -0
  63. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/runtime-overview.test.ts +0 -0
  64. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/runtime-overview.tsx +0 -0
  65. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/settings-workspace.test.ts +0 -0
  66. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/styles.css +0 -0
  67. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/src/vite-env.d.ts +0 -0
  68. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/tsconfig.json +0 -0
  69. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/dashboard/vite.config.ts +0 -0
  70. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docker-requirements.txt +0 -0
  71. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/approval-audit.md +0 -0
  72. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/architecture.md +0 -0
  73. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/get-started.md +0 -0
  74. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/harness-support.md +0 -0
  75. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/local-vs-cloud.md +0 -0
  76. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/release-checklist.md +0 -0
  77. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/smoke-tests.md +0 -0
  78. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/guard/testing-matrix.md +0 -0
  79. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/trust/mcp-trust-draft.md +0 -0
  80. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/trust/plugin-trust-draft.md +0 -0
  81. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/docs/trust/skill-trust-local.md +0 -0
  82. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/fuzzers/manifest_fuzzer.py +0 -0
  83. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/requirements.txt +0 -0
  84. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/schemas/plugin-quality.v1.json +0 -0
  85. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/schemas/scan-result.v1.json +0 -0
  86. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/schemas/verify-result.v1.json +0 -0
  87. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/__init__.py +0 -0
  88. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/action_runner.py +0 -0
  89. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/argparse_utils.py +0 -0
  90. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/__init__.py +0 -0
  91. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
  92. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/claude.py +0 -0
  93. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
  94. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
  95. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/gemini.py +0 -0
  96. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/manifest.py +0 -0
  97. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
  98. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
  99. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
  100. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/opencode.py +0 -0
  101. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
  102. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/security.py +0 -0
  103. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
  104. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/cli.py +0 -0
  105. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/cli_ui.py +0 -0
  106. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/config.py +0 -0
  107. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
  108. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
  109. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
  110. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
  111. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
  112. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
  113. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
  114. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
  115. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
  116. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/github_reporting.py +0 -0
  117. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/__init__.py +0 -0
  118. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/access_graph_events.py +0 -0
  119. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
  120. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
  121. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
  122. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
  123. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/cloud_identity.py +0 -0
  124. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
  125. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/contracts.py +0 -0
  126. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
  127. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
  128. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
  129. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
  130. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
  131. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/openclaw.py +0 -0
  132. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/openclaw_config.py +0 -0
  133. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/openclaw_support.py +0 -0
  134. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
  135. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
  136. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
  137. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
  138. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
  139. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
  140. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
  141. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
  142. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/commands.py +0 -0
  143. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
  144. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
  145. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
  146. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
  147. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
  148. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
  149. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
  150. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/config.py +0 -0
  151. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
  152. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/consumer/service.py +0 -0
  153. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
  154. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
  155. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
  156. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
  157. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
  158. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
  159. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
  160. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
  161. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
  162. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
  163. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
  164. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/edge_events.py +0 -0
  165. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/incident.py +0 -0
  166. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/launcher.py +0 -0
  167. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
  168. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/models.py +0 -0
  169. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
  170. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
  171. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/protect.py +0 -0
  172. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
  173. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
  174. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
  175. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
  176. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
  177. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
  178. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/redaction.py +0 -0
  179. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/risk.py +0 -0
  180. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
  181. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/action_identity.py +0 -0
  182. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/actions.py +0 -0
  183. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/advisory_escalation.py +0 -0
  184. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/advisory_matchers.py +0 -0
  185. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/data_flow.py +0 -0
  186. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/data_flow_rules.py +0 -0
  187. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/data_flow_variables.py +0 -0
  188. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/decisions.py +0 -0
  189. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/detectors.py +0 -0
  190. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/mcp_protection.py +0 -0
  191. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/prompt_injection.py +0 -0
  192. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/runner.py +0 -0
  193. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/safe_decode.py +0 -0
  194. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/sandbox.py +0 -0
  195. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +0 -0
  196. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/secret_sensitivity.py +0 -0
  197. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/secret_sources.py +0 -0
  198. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/shell_commands.py +0 -0
  199. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/signals.py +0 -0
  200. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/skill_protection.py +0 -0
  201. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/supply_chain.py +0 -0
  202. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
  203. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/temp_files.py +0 -0
  204. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/runtime/threat_intel.py +0 -0
  205. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
  206. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
  207. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +0 -0
  208. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
  209. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/shims.py +0 -0
  210. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
  211. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
  212. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/store_evidence.py +0 -0
  213. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/store_threat_intel.py +0 -0
  214. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/guard/types.py +0 -0
  215. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
  216. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
  217. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
  218. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/lint_fixes.py +0 -0
  219. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/marketplace_support.py +0 -0
  220. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/models.py +0 -0
  221. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/path_support.py +0 -0
  222. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/policy.py +0 -0
  223. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/quality_artifact.py +0 -0
  224. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/repo_detect.py +0 -0
  225. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/reporting.py +0 -0
  226. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/rules/__init__.py +0 -0
  227. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/rules/registry.py +0 -0
  228. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/rules/specs.py +0 -0
  229. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/scanner.py +0 -0
  230. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/submission.py +0 -0
  231. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/suppressions.py +0 -0
  232. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
  233. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_helpers.py +0 -0
  234. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
  235. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_models.py +0 -0
  236. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
  237. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_scoring.py +0 -0
  238. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
  239. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/trust_specs.py +0 -0
  240. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/src/codex_plugin_scanner/verification.py +0 -0
  241. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/__init__.py +0 -0
  242. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/conftest.py +0 -0
  243. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/__init__.py +0 -0
  244. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
  245. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/bad-plugin/.mcp.json +0 -0
  246. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/bad-plugin/secrets.js +0 -0
  247. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
  248. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
  249. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/claude-plugin-good/README.md +0 -0
  250. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
  251. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
  252. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
  253. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/code-quality-bad/evil.js +0 -0
  254. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/code-quality-bad/inject.js +0 -0
  255. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
  256. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
  257. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/gemini-extension-good/README.md +0 -0
  258. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
  259. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
  260. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
  261. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
  262. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/.codexignore +0 -0
  263. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/LICENSE +0 -0
  264. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/README.md +0 -0
  265. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/SECURITY.md +0 -0
  266. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
  267. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
  268. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
  269. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
  270. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
  271. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/README.md +0 -0
  272. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/benign-docs-fake-token.py +0 -0
  273. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/benign-health-endpoint.py +0 -0
  274. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/benign-nvmrc-fake-creds.py +0 -0
  275. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/benign-source-search.py +0 -0
  276. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/canary-exfil-encoded.py +0 -0
  277. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/canary-exfil.py +0 -0
  278. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/expected-decisions.json +0 -0
  279. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-dockerfile.txt +0 -0
  280. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-encoded-shell-exfil.py +0 -0
  281. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-github-action.yml +0 -0
  282. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-mcp-delete.md +0 -0
  283. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-mcp-secret-read.md +0 -0
  284. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-mcp-skill-exfil.md +0 -0
  285. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-npm-postinstall.js +0 -0
  286. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-prompt-env-read.md +0 -0
  287. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-prompt-guard-bypass.md +0 -0
  288. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-prompt-npmrc-read.md +0 -0
  289. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/malicious-python-setup.py +0 -0
  290. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/guard-red-team/smoke-evidence-template.json +0 -0
  291. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
  292. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
  293. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
  294. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
  295. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
  296. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
  297. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
  298. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
  299. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
  300. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
  301. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
  302. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
  303. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
  304. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
  305. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/mcp-canary-server.py +0 -0
  306. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
  307. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
  308. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/mit-license/LICENSE +0 -0
  309. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
  310. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
  311. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
  312. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
  313. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
  314. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
  315. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
  316. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
  317. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
  318. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
  319. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
  320. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
  321. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
  322. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
  323. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
  324. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
  325. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
  326. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
  327. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/opencode-good/LICENSE +0 -0
  328. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/opencode-good/README.md +0 -0
  329. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/opencode-good/SECURITY.md +0 -0
  330. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
  331. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
  332. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
  333. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
  334. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/benign-npm-package.json +0 -0
  335. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/benign-pnpm-package.json +0 -0
  336. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/benign-pyproject.toml +0 -0
  337. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/malicious-Dockerfile +0 -0
  338. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/malicious-action.yml +0 -0
  339. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/malicious-npm-package.json +0 -0
  340. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/supply-chain/malicious-setup.py +0 -0
  341. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
  342. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
  343. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/fixtures/with-marketplace/marketplace.json +0 -0
  344. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test-trust-scoring.py +0 -0
  345. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test-trust-specs.py +0 -0
  346. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_action_runner.py +0 -0
  347. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_best_practices.py +0 -0
  348. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_cisco_install_surfaces.py +0 -0
  349. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_cli.py +0 -0
  350. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_code_quality.py +0 -0
  351. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_config.py +0 -0
  352. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_coverage_remaining.py +0 -0
  353. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_ecosystems.py +0 -0
  354. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_edge_cases.py +0 -0
  355. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_final_coverage.py +0 -0
  356. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_access_graph.py +0 -0
  357. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_action_identity.py +0 -0
  358. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_advisory_escalation.py +0 -0
  359. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_approval_continuity.py +0 -0
  360. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_approval_copy_commands.py +0 -0
  361. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_approval_store_dedup.py +0 -0
  362. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_approval_store_scale.py +0 -0
  363. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_approvals.py +0 -0
  364. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_bootstrap.py +0 -0
  365. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_canary_fixtures.py +0 -0
  366. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_capabilities.py +0 -0
  367. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_claude_adapter.py +0 -0
  368. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_cli.py +0 -0
  369. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_cloud_local_sync.py +0 -0
  370. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_codex_e2e.py +0 -0
  371. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_codex_install.py +0 -0
  372. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_codex_proxy.py +0 -0
  373. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_config_paths.py +0 -0
  374. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_connect_flow.py +0 -0
  375. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_consumer_mode.py +0 -0
  376. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_copilot_adapter.py +0 -0
  377. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_copilot_proxy.py +0 -0
  378. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_daemon_manager.py +0 -0
  379. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_daemon_repair_perf.py +0 -0
  380. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_data_flow.py +0 -0
  381. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_decision_propagation.py +0 -0
  382. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_event_schema_v1.py +0 -0
  383. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_events.py +0 -0
  384. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_evidence_store.py +0 -0
  385. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_harness_contracts.py +0 -0
  386. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_launch_env.py +0 -0
  387. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_mcp_protection.py +0 -0
  388. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_opencode_proxy.py +0 -0
  389. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_policy_dedup.py +0 -0
  390. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_product_flow.py +0 -0
  391. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_prompt_injection.py +0 -0
  392. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_protect.py +0 -0
  393. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_red_team.py +0 -0
  394. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_render.py +0 -0
  395. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_resolution_copy.py +0 -0
  396. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_risk.py +0 -0
  397. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_runtime.py +0 -0
  398. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_runtime_action_harnesses.py +0 -0
  399. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_runtime_actions.py +0 -0
  400. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_runtime_decisions.py +0 -0
  401. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_runtime_detectors.py +0 -0
  402. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_runtime_signals.py +0 -0
  403. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_safe_decode.py +0 -0
  404. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_sandbox.py +0 -0
  405. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_skill_protection.py +0 -0
  406. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_store_migrations.py +0 -0
  407. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_supply_chain.py +0 -0
  408. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_surface_server.py +0 -0
  409. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_threat_intel.py +0 -0
  410. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_verdicts.py +0 -0
  411. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_guard_web_recovery.py +0 -0
  412. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_hermes_adapter.py +0 -0
  413. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_integration.py +0 -0
  414. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_lint_fixes.py +0 -0
  415. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_live_cisco_smoke.py +0 -0
  416. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_manifest.py +0 -0
  417. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_marketplace.py +0 -0
  418. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_mcp_security.py +0 -0
  419. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_openclaw_adapter.py +0 -0
  420. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_operational_security.py +0 -0
  421. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_policy.py +0 -0
  422. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_quality_artifact.py +0 -0
  423. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_rule_registry.py +0 -0
  424. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_scanner.py +0 -0
  425. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_schema_contracts.py +0 -0
  426. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_security.py +0 -0
  427. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_security_ops.py +0 -0
  428. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_skill_security.py +0 -0
  429. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_submission.py +0 -0
  430. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_trust_scoring.py +0 -0
  431. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_trust_specs.py +0 -0
  432. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_verification.py +0 -0
  433. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/tests/test_versioning.py +0 -0
  434. {plugin_scanner-2.0.141 → plugin_scanner-2.0.143}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plugin-scanner
3
- Version: 2.0.141
3
+ Version: 2.0.143
4
4
  Summary: Lint, verify, and gate plugin ecosystems for maintainers, CI, and publish workflows.
5
5
  Project-URL: Homepage, https://github.com/hashgraph-online/ai-plugin-scanner
6
6
  Project-URL: Repository, https://github.com/hashgraph-online/ai-plugin-scanner
@@ -171,6 +171,7 @@ export type GuardRuntimeSnapshot = {
171
171
  headline_state: GuardHeadlineState;
172
172
  headline_label: string;
173
173
  headline_detail: string;
174
+ thread_count?: number;
174
175
  sync_configured: boolean;
175
176
  cloud_state: "local_only" | "paired_waiting" | "paired_active";
176
177
  cloud_state_label: string;
@@ -13,9 +13,9 @@ import {
13
13
  SectionLabel,
14
14
  Tag
15
15
  } from "./approval-center-primitives";
16
- import { clearEvidence, exportDiagnostics, fetchSettings, updateSettings, clearPolicy, repairApprovalCenter } from "./guard-api";
16
+ import { clearEvidence, exportDiagnostics, fetchRuntimeSnapshot, fetchSettings, updateSettings, clearPolicy, repairApprovalCenter } from "./guard-api";
17
17
  import { resolveProtectionLevelCopy } from "./runtime-overview";
18
- import type { GuardSettings, GuardSettingsPayload } from "./guard-types";
18
+ import type { GuardRuntimeSnapshot, GuardSettings, GuardSettingsPayload } from "./guard-types";
19
19
 
20
20
  type SettingsState =
21
21
  | { kind: "loading" }
@@ -165,6 +165,7 @@ export function SettingsWorkspace() {
165
165
  const [exporting, setExporting] = useState(false);
166
166
  const [repairing, setRepairing] = useState(false);
167
167
  const [actionMessage, setActionMessage] = useState<string | null>(null);
168
+ const [perfSnapshot, setPerfSnapshot] = useState<GuardRuntimeSnapshot | null>(null);
168
169
  const saveSuccessTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
169
170
 
170
171
  useEffect(() => {
@@ -190,6 +191,20 @@ export function SettingsWorkspace() {
190
191
  };
191
192
  }, []);
192
193
 
194
+ useEffect(() => {
195
+ let cancelled = false;
196
+ fetchRuntimeSnapshot()
197
+ .then((snapshot) => {
198
+ if (!cancelled) setPerfSnapshot(snapshot);
199
+ })
200
+ .catch((error: unknown) => {
201
+ console.error("Failed to fetch runtime snapshot:", error);
202
+ });
203
+ return () => {
204
+ cancelled = true;
205
+ };
206
+ }, []);
207
+
193
208
  useEffect(() => {
194
209
  return () => {
195
210
  if (saveSuccessTimerRef.current !== null) {
@@ -610,6 +625,14 @@ export function SettingsWorkspace() {
610
625
  <SettingToggle label="Billing features" checked={draft.billing} onChange={handleBooleanChange("billing")} />
611
626
  </div>
612
627
  </div>
628
+ {perfSnapshot !== null ? (
629
+ <div className="rounded-[1.75rem] border border-slate-200/70 bg-white/80 p-5 shadow-sm">
630
+ <SectionLabel>Runtime diagnostics</SectionLabel>
631
+ <div className="mt-4">
632
+ <DiagnosticsPerfCard snapshot={perfSnapshot} />
633
+ </div>
634
+ </div>
635
+ ) : null}
613
636
  <div className="rounded-[1.75rem] border border-red-100 bg-red-50/50 p-5 shadow-sm">
614
637
  <SectionLabel>Data management</SectionLabel>
615
638
  <div className="mt-4 space-y-3">
@@ -682,6 +705,41 @@ export function SettingsWorkspace() {
682
705
  );
683
706
  }
684
707
 
708
+ function DiagnosticsPerfCard(props: { snapshot: GuardRuntimeSnapshot }) {
709
+ const { snapshot } = props;
710
+ const threadCount = snapshot.thread_count;
711
+ const daemonPort = snapshot.runtime_state?.daemon_port ?? null;
712
+ const startedAt = snapshot.runtime_state?.started_at ?? null;
713
+ return (
714
+ <div>
715
+ <h3 className="text-sm font-semibold text-brand-dark">Runtime performance</h3>
716
+ <p className="mt-1 text-xs leading-relaxed text-muted-foreground">
717
+ Live process metrics for this Guard daemon session.
718
+ </p>
719
+ <dl className="mt-3 grid grid-cols-2 gap-2">
720
+ {threadCount !== undefined ? (
721
+ <PerfMetric label="Total interpreter threads" value={String(threadCount)} />
722
+ ) : null}
723
+ {daemonPort !== null ? (
724
+ <PerfMetric label="Daemon port" value={String(daemonPort)} />
725
+ ) : null}
726
+ {startedAt !== null ? (
727
+ <PerfMetric label="Started" value={new Date(startedAt).toLocaleTimeString()} />
728
+ ) : null}
729
+ </dl>
730
+ </div>
731
+ );
732
+ }
733
+
734
+ function PerfMetric(props: { label: string; value: string }) {
735
+ return (
736
+ <div className="rounded-xl bg-surface-1 px-3 py-2">
737
+ <dt className="text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground">{props.label}</dt>
738
+ <dd className="mt-0.5 font-mono text-sm font-semibold text-brand-dark">{props.value}</dd>
739
+ </div>
740
+ );
741
+ }
742
+
685
743
  function SettingSelect(props: {
686
744
  label: string;
687
745
  value: string;
@@ -35,3 +35,22 @@ profile. Custom overrides survive a preset switch unless explicitly cleared.
35
35
 
36
36
  The approval center and evidence log now paginate at 50 items per page. Large workspaces
37
37
  with thousands of receipts will no longer cause the dashboard to stall on load.
38
+
39
+ ---
40
+
41
+ ## Release checklist (T608)
42
+
43
+ Before tagging a release, complete the following items for every harness integration
44
+ path that was touched in this release cycle.
45
+
46
+ 1. Run `pytest -m "not slow" -q` — all non-`slow` tests must pass.
47
+ 2. Run `ruff check src/ tests/` — zero violations.
48
+ 3. Run `cd dashboard && pnpm test && pnpm build` — dashboard bundle updated.
49
+ 4. Build wheel: `uv build` — wheel must build without errors.
50
+ 5. Install in temp venv: `pip install dist/*.whl && hol-guard doctor` — doctor shows no fatal errors.
51
+ 6. Fill in `tests/fixtures/guard-red-team/smoke-evidence-template.json` for each harness
52
+ integration touched. Mark each test entry `pass`, `fail`, or `skip` with notes.
53
+ 7. Confirm no `.env` file was read during the release build.
54
+ 8. Confirm no real secrets appear in committed fixtures or tests.
55
+ 9. Confirm no full local paths appear in any committed file.
56
+ 10. Merge only after all PR review threads are resolved.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "plugin-scanner"
7
- version = "2.0.141"
7
+ version = "2.0.143"
8
8
  description = "Lint, verify, and gate plugin ecosystems for maintainers, CI, and publish workflows."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "hol-guard"
7
- version = "2.0.141"
7
+ version = "2.0.143"
8
8
  description = "Protect local AI harnesses with HOL Guard and run scanner checks for Codex, Claude, Cursor, Gemini, and OpenCode."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import threading
5
6
  import time
6
7
  import uuid
7
8
  from collections.abc import Mapping
@@ -215,6 +216,7 @@ def build_runtime_snapshot(
215
216
  "headline_state": headline_state,
216
217
  "headline_label": _runtime_headline_label(headline_state),
217
218
  "headline_detail": _runtime_headline_detail(headline_state),
219
+ "thread_count": threading.active_count(),
218
220
  "items": pending_requests,
219
221
  "latest_receipts": latest_receipts,
220
222
  "managed_installs": store.list_managed_installs(),
@@ -15562,6 +15562,7 @@ function SettingsWorkspace() {
15562
15562
  const [exporting, setExporting] = reactExports.useState(false);
15563
15563
  const [repairing, setRepairing] = reactExports.useState(false);
15564
15564
  const [actionMessage, setActionMessage] = reactExports.useState(null);
15565
+ const [perfSnapshot, setPerfSnapshot] = reactExports.useState(null);
15565
15566
  const saveSuccessTimerRef = reactExports.useRef(null);
15566
15567
  reactExports.useEffect(() => {
15567
15568
  let cancelled = false;
@@ -15583,6 +15584,17 @@ function SettingsWorkspace() {
15583
15584
  cancelled = true;
15584
15585
  };
15585
15586
  }, []);
15587
+ reactExports.useEffect(() => {
15588
+ let cancelled = false;
15589
+ fetchRuntimeSnapshot().then((snapshot) => {
15590
+ if (!cancelled) setPerfSnapshot(snapshot);
15591
+ }).catch((error) => {
15592
+ console.error("Failed to fetch runtime snapshot:", error);
15593
+ });
15594
+ return () => {
15595
+ cancelled = true;
15596
+ };
15597
+ }, []);
15586
15598
  reactExports.useEffect(() => {
15587
15599
  return () => {
15588
15600
  if (saveSuccessTimerRef.current !== null) {
@@ -15942,6 +15954,10 @@ function SettingsWorkspace() {
15942
15954
  /* @__PURE__ */ jsxRuntimeExports.jsx(SettingToggle, { label: "Billing features", checked: draft.billing, onChange: handleBooleanChange("billing") })
15943
15955
  ] })
15944
15956
  ] }),
15957
+ perfSnapshot !== null ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-[1.75rem] border border-slate-200/70 bg-white/80 p-5 shadow-sm", children: [
15958
+ /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { children: "Runtime diagnostics" }),
15959
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(DiagnosticsPerfCard, { snapshot: perfSnapshot }) })
15960
+ ] }) : null,
15945
15961
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-[1.75rem] border border-red-100 bg-red-50/50 p-5 shadow-sm", children: [
15946
15962
  /* @__PURE__ */ jsxRuntimeExports.jsx(SectionLabel, { children: "Data management" }),
15947
15963
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 space-y-3", children: [
@@ -15976,6 +15992,27 @@ function SettingsWorkspace() {
15976
15992
  ] })
15977
15993
  ] });
15978
15994
  }
15995
+ function DiagnosticsPerfCard(props) {
15996
+ const { snapshot } = props;
15997
+ const threadCount = snapshot.thread_count;
15998
+ const daemonPort = snapshot.runtime_state?.daemon_port ?? null;
15999
+ const startedAt = snapshot.runtime_state?.started_at ?? null;
16000
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
16001
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-brand-dark", children: "Runtime performance" }),
16002
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: "Live process metrics for this Guard daemon session." }),
16003
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("dl", { className: "mt-3 grid grid-cols-2 gap-2", children: [
16004
+ threadCount !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(PerfMetric, { label: "Total interpreter threads", value: String(threadCount) }) : null,
16005
+ daemonPort !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(PerfMetric, { label: "Daemon port", value: String(daemonPort) }) : null,
16006
+ startedAt !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx(PerfMetric, { label: "Started", value: new Date(startedAt).toLocaleTimeString() }) : null
16007
+ ] })
16008
+ ] });
16009
+ }
16010
+ function PerfMetric(props) {
16011
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-xl bg-surface-1 px-3 py-2", children: [
16012
+ /* @__PURE__ */ jsxRuntimeExports.jsx("dt", { className: "text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: props.label }),
16013
+ /* @__PURE__ */ jsxRuntimeExports.jsx("dd", { className: "mt-0.5 font-mono text-sm font-semibold text-brand-dark", children: props.value })
16014
+ ] });
16015
+ }
15979
16016
  function SettingSelect(props) {
15980
16017
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block", children: [
15981
16018
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: props.label }),
@@ -2164,6 +2164,11 @@
2164
2164
  letter-spacing: .2em;
2165
2165
  }
2166
2166
 
2167
+ .tracking-\[0\.14em\] {
2168
+ --tw-tracking: .14em;
2169
+ letter-spacing: .14em;
2170
+ }
2171
+
2167
2172
  .tracking-\[0\.18em\] {
2168
2173
  --tw-tracking: .18em;
2169
2174
  letter-spacing: .18em;
@@ -4,9 +4,11 @@ from __future__ import annotations
4
4
 
5
5
  import base64
6
6
  import json
7
+ import logging
7
8
  import os
8
9
  import sqlite3
9
10
  import subprocess
11
+ import time
10
12
  from collections.abc import Iterator
11
13
  from contextlib import contextmanager
12
14
  from datetime import datetime, timedelta, timezone
@@ -353,6 +355,10 @@ def _build_secret_store(guard_home: Path) -> SecretStore:
353
355
  return fallback_store
354
356
 
355
357
 
358
+ _SLOW_QUERY_THRESHOLD_MS: int = 200
359
+ _store_logger = logging.getLogger(__name__)
360
+
361
+
356
362
  class GuardStore:
357
363
  """Local SQLite store for Guard state."""
358
364
 
@@ -403,11 +409,18 @@ class GuardStore:
403
409
  def _connect(self) -> Iterator[sqlite3.Connection]:
404
410
  connection = sqlite3.connect(self.path)
405
411
  connection.row_factory = sqlite3.Row
412
+ start = time.monotonic()
406
413
  try:
407
414
  yield connection
408
415
  connection.commit()
409
416
  finally:
410
417
  connection.close()
418
+ elapsed_ms = (time.monotonic() - start) * 1000
419
+ if elapsed_ms >= _SLOW_QUERY_THRESHOLD_MS:
420
+ _store_logger.warning(
421
+ "Guard store slow transaction (%.0fms); consider indexing hot query paths.",
422
+ elapsed_ms,
423
+ )
411
424
 
412
425
  def _initialize(self) -> None:
413
426
  statements = (
@@ -1,3 +1,3 @@
1
1
  """Single source of truth for tool version."""
2
2
 
3
- __version__ = "2.0.141"
3
+ __version__ = "2.0.143"
@@ -2,6 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import threading
6
+ import time
5
7
  from pathlib import Path
6
8
 
7
9
  import pytest
@@ -176,3 +178,117 @@ class TestDoctorPerfPayload:
176
178
  for item in perf:
177
179
  expected_slow = int(item["elapsed_ms"]) >= _SLOW_DETECTOR_THRESHOLD_MS
178
180
  assert item["slow"] == expected_slow
181
+
182
+
183
+ class TestProcessCountBound:
184
+ """T620 — 100 safe hook evaluations must not spawn persistent threads."""
185
+
186
+ @pytest.mark.slow
187
+ def test_100_harness_start_evaluations_do_not_spawn_threads(self, tmp_path: Path) -> None:
188
+ action = _make_harness_start_action()
189
+ context = _make_detector_context(tmp_path)
190
+ registry = _get_default_detector_registry()
191
+ baseline_threads = threading.active_count()
192
+ for _ in range(100):
193
+ registry.run(action, context, timeout_ms=500)
194
+ after_threads = threading.active_count()
195
+ assert after_threads - baseline_threads <= 5, (
196
+ f"Thread count grew by {after_threads - baseline_threads} after 100 evaluations; "
197
+ "detectors must not leak persistent threads."
198
+ )
199
+
200
+ def test_100_harness_start_evaluations_complete_without_error(self, tmp_path: Path) -> None:
201
+ action = _make_harness_start_action()
202
+ context = _make_detector_context(tmp_path)
203
+ registry = _get_default_detector_registry()
204
+ results = [registry.run(action, context, timeout_ms=500) for _ in range(100)]
205
+ assert all(isinstance(r, DetectorRunResult) for r in results)
206
+
207
+
208
+ @pytest.mark.slow
209
+ class TestCPUBenchmark:
210
+ """T622 — 100 safe hook evaluations must complete in under 10 seconds."""
211
+
212
+ def test_100_safe_hook_calls_complete_within_budget(self, tmp_path: Path) -> None:
213
+ action = _make_harness_start_action()
214
+ context = _make_detector_context(tmp_path)
215
+ registry = _get_default_detector_registry()
216
+ start = time.monotonic()
217
+ for _ in range(100):
218
+ registry.run(action, context, timeout_ms=500)
219
+ elapsed_s = time.monotonic() - start
220
+ assert elapsed_s < 10.0, f"100 safe hook evaluations took {elapsed_s:.2f}s; budget is 10s."
221
+
222
+
223
+ class TestMemoryBenchmark:
224
+ """T621 — Guard module import stays under 50 MB RSS budget."""
225
+
226
+ def test_guard_config_import_does_not_import_heavy_deps(self) -> None:
227
+ import subprocess
228
+ import sys
229
+
230
+ result = subprocess.run(
231
+ [
232
+ sys.executable,
233
+ "-c",
234
+ (
235
+ "import codex_plugin_scanner.guard.config as _c;"
236
+ " import sys;"
237
+ " heavy = {'matplotlib', 'numpy', 'pandas', 'scipy', 'torch', 'tensorflow'};"
238
+ " leaked = heavy & set(sys.modules);"
239
+ " print(repr(leaked))"
240
+ ),
241
+ ],
242
+ capture_output=True,
243
+ text=True,
244
+ timeout=30,
245
+ )
246
+ assert result.returncode == 0, f"Subprocess failed: {result.stderr}"
247
+ import ast
248
+ leaked = ast.literal_eval(result.stdout.strip())
249
+ assert not leaked, f"Guard import leaked heavy dependencies: {leaked}"
250
+
251
+
252
+ class TestSlowSQLiteTelemetry:
253
+ """T624 — Slow store transactions emit a warning via the logging module."""
254
+
255
+ def test_slow_query_threshold_is_200ms(self) -> None:
256
+ from codex_plugin_scanner.guard.store import _SLOW_QUERY_THRESHOLD_MS
257
+
258
+ assert _SLOW_QUERY_THRESHOLD_MS == 200
259
+
260
+ def test_fast_transaction_does_not_warn(
261
+ self, tmp_path: Path, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch
262
+ ) -> None:
263
+ import logging
264
+
265
+ import codex_plugin_scanner.guard.store as store_module
266
+ from codex_plugin_scanner.guard.store import GuardStore
267
+
268
+ monkeypatch.setattr(store_module, "_SLOW_QUERY_THRESHOLD_MS", 10_000)
269
+ store = GuardStore(guard_home=tmp_path / "guard-home")
270
+ with caplog.at_level(logging.WARNING, logger="codex_plugin_scanner.guard.store"):
271
+ _ = store.list_approval_requests()
272
+ slow_warnings = [r for r in caplog.records if "slow transaction" in r.getMessage().lower()]
273
+ assert len(slow_warnings) == 0, "Fast transaction must not emit slow transaction warning"
274
+
275
+ def test_slow_transaction_emits_warning(
276
+ self, tmp_path: Path, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch
277
+ ) -> None:
278
+ import logging
279
+
280
+ import codex_plugin_scanner.guard.store as store_module
281
+ from codex_plugin_scanner.guard.store import GuardStore
282
+
283
+ monkeypatch.setattr(store_module, "_SLOW_QUERY_THRESHOLD_MS", 0)
284
+ store = GuardStore(guard_home=tmp_path / "guard-home")
285
+ with caplog.at_level(logging.WARNING, logger="codex_plugin_scanner.guard.store"):
286
+ _ = store.list_approval_requests()
287
+ slow_warnings = [r for r in caplog.records if "slow transaction" in r.getMessage().lower()]
288
+ assert len(slow_warnings) > 0, "Slow transaction (threshold=0ms) must emit a slow transaction warning"
289
+
290
+ def test_store_has_slow_query_threshold_constant(self) -> None:
291
+ from codex_plugin_scanner.guard.store import _SLOW_QUERY_THRESHOLD_MS
292
+
293
+ assert isinstance(_SLOW_QUERY_THRESHOLD_MS, int)
294
+ assert _SLOW_QUERY_THRESHOLD_MS > 0