plugin-scanner 2.0.117__tar.gz → 2.0.118__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 (362) hide show
  1. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/PKG-INFO +1 -1
  2. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/guard-api.test.ts +24 -0
  3. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/guard-api.ts +8 -0
  4. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/guard-types.ts +10 -0
  5. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/runtime-overview.tsx +32 -1
  6. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/pyproject.toml +1 -1
  7. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/pyproject.toml.bak +1 -1
  8. plugin_scanner-2.0.118/src/codex_plugin_scanner/guard/access_graph_events.py +223 -0
  9. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/approvals.py +99 -1
  10. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/commands.py +10 -1
  11. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/consumer/service.py +8 -0
  12. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/assets/guard-dashboard.js +6 -6
  13. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/edge_events.py +93 -0
  14. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/redaction.py +15 -1
  15. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/detectors.py +79 -2
  16. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/runner.py +115 -4
  17. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/secret_file_requests.py +32 -0
  18. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/schemas/guard_event_v1.py +25 -3
  19. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/store.py +131 -24
  20. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/version.py +1 -1
  21. plugin_scanner-2.0.118/tests/test_guard_cloud_local_sync.py +451 -0
  22. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_connect_flow.py +4 -0
  23. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_event_schema_v1.py +66 -2
  24. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_launch_env.py +81 -0
  25. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_risk.py +37 -0
  26. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_runtime.py +33 -0
  27. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_runtime_detectors.py +90 -0
  28. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_surface_server.py +64 -0
  29. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.clusterfuzzlite/Dockerfile +0 -0
  30. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.clusterfuzzlite/build.sh +0 -0
  31. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.clusterfuzzlite/project.yaml +0 -0
  32. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.clusterfuzzlite/requirements-atheris.txt +0 -0
  33. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.dockerignore +0 -0
  34. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/CODEOWNERS +0 -0
  35. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  36. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  37. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  38. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/dependabot.yml +0 -0
  39. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/ci.yml +0 -0
  40. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/codeql.yml +0 -0
  41. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/dependabot-uv-lock.yml +0 -0
  42. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/fuzz.yml +0 -0
  43. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/harness-smoke.yml +0 -0
  44. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/publish.yml +0 -0
  45. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.github/workflows/scorecard.yml +0 -0
  46. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.gitignore +0 -0
  47. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/.pre-commit-hooks.yaml +0 -0
  48. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/CONTRIBUTING.md +0 -0
  49. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/Dockerfile +0 -0
  50. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/LICENSE +0 -0
  51. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/README.md +0 -0
  52. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/SECURITY.md +0 -0
  53. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/index.html +0 -0
  54. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/package.json +0 -0
  55. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/pnpm-lock.yaml +0 -0
  56. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/public/apple-touch-icon.png +0 -0
  57. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/public/brand/Logo_Icon_Dark.png +0 -0
  58. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/public/brand/Logo_Whole.png +0 -0
  59. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/public/favicon-16x16.png +0 -0
  60. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/public/favicon-32x32.png +0 -0
  61. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/public/favicon.ico +0 -0
  62. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/app.tsx +0 -0
  63. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/approval-center-layout.tsx +0 -0
  64. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/approval-center-primitives.tsx +0 -0
  65. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/approval-center-utils.ts +0 -0
  66. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/data-flow-evidence-card.tsx +0 -0
  67. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/fleet-workspace.tsx +0 -0
  68. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/guard-demo.ts +0 -0
  69. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/main.tsx +0 -0
  70. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/receipts-workspace.tsx +0 -0
  71. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/settings-workspace.tsx +0 -0
  72. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/styles.css +0 -0
  73. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/src/vite-env.d.ts +0 -0
  74. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/tsconfig.json +0 -0
  75. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/dashboard/vite.config.ts +0 -0
  76. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docker-requirements.txt +0 -0
  77. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/guard/approval-audit.md +0 -0
  78. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/guard/architecture.md +0 -0
  79. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/guard/get-started.md +0 -0
  80. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/guard/harness-support.md +0 -0
  81. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/guard/local-vs-cloud.md +0 -0
  82. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/guard/testing-matrix.md +0 -0
  83. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/trust/mcp-trust-draft.md +0 -0
  84. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/trust/plugin-trust-draft.md +0 -0
  85. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/docs/trust/skill-trust-local.md +0 -0
  86. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/fuzzers/manifest_fuzzer.py +0 -0
  87. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/requirements.txt +0 -0
  88. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/schemas/plugin-quality.v1.json +0 -0
  89. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/schemas/scan-result.v1.json +0 -0
  90. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/schemas/verify-result.v1.json +0 -0
  91. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/__init__.py +0 -0
  92. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/action_runner.py +0 -0
  93. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/argparse_utils.py +0 -0
  94. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/__init__.py +0 -0
  95. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/best_practices.py +0 -0
  96. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/claude.py +0 -0
  97. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/code_quality.py +0 -0
  98. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/ecosystem_common.py +0 -0
  99. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/gemini.py +0 -0
  100. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/manifest.py +0 -0
  101. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/manifest_support.py +0 -0
  102. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/marketplace.py +0 -0
  103. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/mcp_security.py +0 -0
  104. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/opencode.py +0 -0
  105. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/operational_security.py +0 -0
  106. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/security.py +0 -0
  107. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/checks/skill_security.py +0 -0
  108. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/cli.py +0 -0
  109. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/cli_ui.py +0 -0
  110. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/config.py +0 -0
  111. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/__init__.py +0 -0
  112. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/base.py +0 -0
  113. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/claude.py +0 -0
  114. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/codex.py +0 -0
  115. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/detect.py +0 -0
  116. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/gemini.py +0 -0
  117. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/opencode.py +0 -0
  118. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/registry.py +0 -0
  119. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/ecosystems/types.py +0 -0
  120. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/github_reporting.py +0 -0
  121. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/__init__.py +0 -0
  122. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/__init__.py +0 -0
  123. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/antigravity.py +0 -0
  124. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/base.py +0 -0
  125. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/claude_code.py +0 -0
  126. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/cloud_identity.py +0 -0
  127. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/codex.py +0 -0
  128. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/copilot.py +0 -0
  129. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/cursor.py +0 -0
  130. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/gemini.py +0 -0
  131. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/hermes.py +0 -0
  132. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/mcp_servers.py +0 -0
  133. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/openclaw.py +0 -0
  134. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/openclaw_config.py +0 -0
  135. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/openclaw_support.py +0 -0
  136. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/opencode.py +0 -0
  137. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/adapters/opencode_artifacts.py +0 -0
  138. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/advisory_model.py +0 -0
  139. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/bridge/__init__.py +0 -0
  140. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/capabilities.py +0 -0
  141. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/__init__.py +0 -0
  142. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/approval_commands.py +0 -0
  143. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/bootstrap.py +0 -0
  144. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/connect_flow.py +0 -0
  145. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/install_commands.py +0 -0
  146. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/product.py +0 -0
  147. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/prompt.py +0 -0
  148. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/render.py +0 -0
  149. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/cli/update_commands.py +0 -0
  150. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/codex_config.py +0 -0
  151. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/config.py +0 -0
  152. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/consumer/__init__.py +0 -0
  153. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/__init__.py +0 -0
  154. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/client.py +0 -0
  155. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/manager.py +0 -0
  156. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/server.py +0 -0
  157. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/apple-touch-icon.png +0 -0
  158. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/assets/index.css +0 -0
  159. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Icon_Dark.png +0 -0
  160. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/brand/Logo_Whole.png +0 -0
  161. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/favicon-16x16.png +0 -0
  162. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/favicon-32x32.png +0 -0
  163. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/favicon.ico +0 -0
  164. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/daemon/static/index.html +0 -0
  165. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/incident.py +0 -0
  166. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/launcher.py +0 -0
  167. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/mcp_tool_calls.py +0 -0
  168. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/models.py +0 -0
  169. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/policy/__init__.py +0 -0
  170. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/policy/engine.py +0 -0
  171. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/protect.py +0 -0
  172. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/proxy/__init__.py +0 -0
  173. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/proxy/remote.py +0 -0
  174. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/proxy/runtime_mcp.py +0 -0
  175. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/proxy/stdio.py +0 -0
  176. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/receipts/__init__.py +0 -0
  177. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/receipts/manager.py +0 -0
  178. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/risk.py +0 -0
  179. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/__init__.py +0 -0
  180. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/actions.py +0 -0
  181. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/data_flow.py +0 -0
  182. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/data_flow_rules.py +0 -0
  183. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/data_flow_variables.py +0 -0
  184. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/decisions.py +0 -0
  185. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/prompt_injection.py +0 -0
  186. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/secret_sensitivity.py +0 -0
  187. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/secret_sources.py +0 -0
  188. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/shell_commands.py +0 -0
  189. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/signals.py +0 -0
  190. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/surface_server.py +0 -0
  191. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/runtime/temp_files.py +0 -0
  192. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/schemas/__init__.py +0 -0
  193. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/schemas/consumer_mode.py +0 -0
  194. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/schemas/surface_server.py +0 -0
  195. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/shims.py +0 -0
  196. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/store_approvals.py +0 -0
  197. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/store_connect.py +0 -0
  198. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/guard/types.py +0 -0
  199. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/integrations/__init__.py +0 -0
  200. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/integrations/cisco_mcp_scanner.py +0 -0
  201. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/integrations/cisco_skill_scanner.py +0 -0
  202. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/lint_fixes.py +0 -0
  203. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/marketplace_support.py +0 -0
  204. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/models.py +0 -0
  205. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/path_support.py +0 -0
  206. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/policy.py +0 -0
  207. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/quality_artifact.py +0 -0
  208. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/repo_detect.py +0 -0
  209. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/reporting.py +0 -0
  210. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/rules/__init__.py +0 -0
  211. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/rules/registry.py +0 -0
  212. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/rules/specs.py +0 -0
  213. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/scanner.py +0 -0
  214. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/submission.py +0 -0
  215. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/suppressions.py +0 -0
  216. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_domain_scoring.py +0 -0
  217. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_helpers.py +0 -0
  218. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_mcp_scoring.py +0 -0
  219. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_models.py +0 -0
  220. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_plugin_scoring.py +0 -0
  221. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_scoring.py +0 -0
  222. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_skill_scoring.py +0 -0
  223. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/trust_specs.py +0 -0
  224. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/src/codex_plugin_scanner/verification.py +0 -0
  225. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/__init__.py +0 -0
  226. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/conftest.py +0 -0
  227. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/__init__.py +0 -0
  228. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/bad-plugin/.codex-plugin/plugin.json +0 -0
  229. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/bad-plugin/.mcp.json +0 -0
  230. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/bad-plugin/secrets.js +0 -0
  231. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/claude-plugin-good/.claude-plugin/plugin.json +0 -0
  232. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/claude-plugin-good/LICENSE +0 -0
  233. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/claude-plugin-good/README.md +0 -0
  234. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/claude-plugin-good/SECURITY.md +0 -0
  235. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/claude-plugin-good/hooks/hooks.json +0 -0
  236. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/claude-plugin-good/skills/example/SKILL.md +0 -0
  237. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/code-quality-bad/evil.js +0 -0
  238. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/code-quality-bad/inject.js +0 -0
  239. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/gemini-extension-good/GEMINI.md +0 -0
  240. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/gemini-extension-good/LICENSE +0 -0
  241. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/gemini-extension-good/README.md +0 -0
  242. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/gemini-extension-good/SECURITY.md +0 -0
  243. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/gemini-extension-good/commands/hello.toml +0 -0
  244. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/gemini-extension-good/gemini-extension.json +0 -0
  245. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/.codex-plugin/plugin.json +0 -0
  246. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/.codexignore +0 -0
  247. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/LICENSE +0 -0
  248. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/README.md +0 -0
  249. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/SECURITY.md +0 -0
  250. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/assets/icon.svg +0 -0
  251. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/assets/logo.svg +0 -0
  252. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/assets/screenshot.svg +0 -0
  253. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/good-plugin/skills/example/SKILL.md +0 -0
  254. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/guard-codex-malicious-mcp/.codex/config.toml +0 -0
  255. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/config.yaml +0 -0
  256. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/mcp_servers.json +0 -0
  257. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/skills/security/malicious/SKILL.md +0 -0
  258. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/SKILL.md +0 -0
  259. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/references/api-setup.md +0 -0
  260. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/skills/stealth/sneaky/scripts/deploy.sh +0 -0
  261. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/hermes-plugin-evil/skills/utils/benign/SKILL.md +0 -0
  262. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malformed-json/.codex-plugin/plugin.json +0 -0
  263. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malicious-skill-plugin/.codex-plugin/plugin.json +0 -0
  264. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malicious-skill-plugin/.codexignore +0 -0
  265. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malicious-skill-plugin/LICENSE +0 -0
  266. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malicious-skill-plugin/README.md +0 -0
  267. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malicious-skill-plugin/SECURITY.md +0 -0
  268. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/malicious-skill-plugin/skills/leaky-skill/SKILL.md +0 -0
  269. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/mcp-canary-server.py +0 -0
  270. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/minimal-plugin/.codex-plugin/plugin.json +0 -0
  271. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/missing-fields/.codex-plugin/plugin.json +0 -0
  272. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/mit-license/LICENSE +0 -0
  273. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-ecosystem-repo/codex-plugin/.codex-plugin/plugin.json +0 -0
  274. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-ecosystem-repo/codex-plugin/LICENSE +0 -0
  275. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-ecosystem-repo/codex-plugin/README.md +0 -0
  276. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-ecosystem-repo/codex-plugin/SECURITY.md +0 -0
  277. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-ecosystem-repo/gemini-ext/README.md +0 -0
  278. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-ecosystem-repo/gemini-ext/gemini-extension.json +0 -0
  279. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/.agents/plugins/marketplace.json +0 -0
  280. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codex-plugin/plugin.json +0 -0
  281. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/.codexignore +0 -0
  282. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/LICENSE +0 -0
  283. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/README.md +0 -0
  284. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/SECURITY.md +0 -0
  285. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/alpha-plugin/skills/example/SKILL.md +0 -0
  286. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/.codex-plugin/plugin.json +0 -0
  287. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/multi-plugin-repo/plugins/beta-plugin/skills/example/SKILL.md +0 -0
  288. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/no-version/.codex-plugin/plugin.json +0 -0
  289. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/opencode-good/.opencode/commands/hello.md +0 -0
  290. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/opencode-good/.opencode/plugins/example.ts +0 -0
  291. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/opencode-good/LICENSE +0 -0
  292. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/opencode-good/README.md +0 -0
  293. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/opencode-good/SECURITY.md +0 -0
  294. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/opencode-good/opencode.jsonc +0 -0
  295. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/skills-missing-dir/.codex-plugin/plugin.json +0 -0
  296. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/skills-no-frontmatter/.codex-plugin/plugin.json +0 -0
  297. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/skills-no-frontmatter/skills/bad-skill/SKILL.md +0 -0
  298. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/with-marketplace/.codex-plugin/plugin.json +0 -0
  299. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/with-marketplace/marketplace-broken.json +0 -0
  300. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/fixtures/with-marketplace/marketplace.json +0 -0
  301. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test-trust-scoring.py +0 -0
  302. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test-trust-specs.py +0 -0
  303. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_action_runner.py +0 -0
  304. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_best_practices.py +0 -0
  305. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_cisco_install_surfaces.py +0 -0
  306. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_cli.py +0 -0
  307. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_code_quality.py +0 -0
  308. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_config.py +0 -0
  309. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_coverage_remaining.py +0 -0
  310. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_ecosystems.py +0 -0
  311. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_edge_cases.py +0 -0
  312. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_final_coverage.py +0 -0
  313. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_access_graph.py +0 -0
  314. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_approvals.py +0 -0
  315. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_bootstrap.py +0 -0
  316. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_capabilities.py +0 -0
  317. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_claude_adapter.py +0 -0
  318. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_cli.py +0 -0
  319. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_codex_e2e.py +0 -0
  320. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_codex_install.py +0 -0
  321. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_codex_proxy.py +0 -0
  322. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_config_paths.py +0 -0
  323. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_consumer_mode.py +0 -0
  324. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_copilot_adapter.py +0 -0
  325. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_copilot_proxy.py +0 -0
  326. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_daemon_manager.py +0 -0
  327. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_data_flow.py +0 -0
  328. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_events.py +0 -0
  329. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_opencode_proxy.py +0 -0
  330. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_product_flow.py +0 -0
  331. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_prompt_injection.py +0 -0
  332. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_protect.py +0 -0
  333. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_render.py +0 -0
  334. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_runtime_action_harnesses.py +0 -0
  335. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_runtime_actions.py +0 -0
  336. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_runtime_decisions.py +0 -0
  337. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_runtime_signals.py +0 -0
  338. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_store_migrations.py +0 -0
  339. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_guard_verdicts.py +0 -0
  340. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_hermes_adapter.py +0 -0
  341. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_integration.py +0 -0
  342. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_lint_fixes.py +0 -0
  343. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_live_cisco_smoke.py +0 -0
  344. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_manifest.py +0 -0
  345. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_marketplace.py +0 -0
  346. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_mcp_security.py +0 -0
  347. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_openclaw_adapter.py +0 -0
  348. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_operational_security.py +0 -0
  349. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_policy.py +0 -0
  350. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_quality_artifact.py +0 -0
  351. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_rule_registry.py +0 -0
  352. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_scanner.py +0 -0
  353. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_schema_contracts.py +0 -0
  354. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_security.py +0 -0
  355. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_security_ops.py +0 -0
  356. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_skill_security.py +0 -0
  357. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_submission.py +0 -0
  358. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_trust_scoring.py +0 -0
  359. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_trust_specs.py +0 -0
  360. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_verification.py +0 -0
  361. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/tests/test_versioning.py +0 -0
  362. {plugin_scanner-2.0.117 → plugin_scanner-2.0.118}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plugin-scanner
3
- Version: 2.0.117
3
+ Version: 2.0.118
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
@@ -4,6 +4,7 @@ import {
4
4
  parseActionEnvelope,
5
5
  parseDecisionV2
6
6
  } from "./guard-api";
7
+ import { resolveCloudSyncHealthCopy } from "./runtime-overview";
7
8
  import {
8
9
  resolveDecisionV2Detail,
9
10
  resolveDecisionV2Title,
@@ -29,6 +30,29 @@ assert(snapshot.cloud_pairing_state.dashboard_url === snapshot.dashboard_url, "d
29
30
  assert(snapshot.cloud_pairing_state.inbox_url === snapshot.inbox_url, "demo inbox URL is preserved");
30
31
  assert(snapshot.cloud_pairing_state.fleet_url === snapshot.fleet_url, "demo fleet URL is preserved");
31
32
  assert(snapshot.cloud_pairing_state.connect_url === snapshot.connect_url, "demo connect URL is preserved");
33
+ assert(snapshot.cloud_sync_health.state === "pending", "demo snapshot exposes pending Cloud sync health");
34
+
35
+ const expectedSyncHealthLabels = {
36
+ healthy: "Cloud sync healthy",
37
+ pending: "Cloud sync pending",
38
+ failed: "Cloud sync needs attention",
39
+ degraded: "Cloud sync degraded",
40
+ disabled: "Cloud sync disabled",
41
+ stale: "Cloud sync stale"
42
+ };
43
+
44
+ for (const [state, label] of Object.entries(expectedSyncHealthLabels)) {
45
+ const copy = resolveCloudSyncHealthCopy({
46
+ state: state as keyof typeof expectedSyncHealthLabels,
47
+ label,
48
+ detail: `${label} detail`,
49
+ pending_events: state === "pending" ? 2 : 0,
50
+ last_synced_at: state === "disabled" ? null : "2026-04-24T00:00:00+00:00",
51
+ next_retry_after: state === "failed" ? "2026-04-24T00:02:00+00:00" : null
52
+ });
53
+ assert(copy.label === label, `T370: ${state} sync health label is preserved`);
54
+ assert(copy.detail.includes("detail"), `T370: ${state} sync health detail is preserved`);
55
+ }
32
56
 
33
57
  const BASE_ENVELOPE: GuardActionEnvelope = {
34
58
  schema_version: 1,
@@ -411,6 +411,14 @@ export function buildDemoRuntimeSnapshot(): GuardRuntimeSnapshot {
411
411
  fleet_url: fleetUrl,
412
412
  connect_url: connectUrl
413
413
  },
414
+ cloud_sync_health: {
415
+ state: "pending",
416
+ label: "Cloud sync pending",
417
+ detail: "Waiting for the first shared Cloud proof from this machine.",
418
+ pending_events: 1,
419
+ last_synced_at: null,
420
+ next_retry_after: null
421
+ },
414
422
  dashboard_url: dashboardUrl,
415
423
  inbox_url: inboxUrl,
416
424
  fleet_url: fleetUrl,
@@ -153,6 +153,15 @@ export type GuardCloudPairingState = {
153
153
  connect_url: string;
154
154
  };
155
155
 
156
+ export type GuardCloudSyncHealth = {
157
+ state: "healthy" | "pending" | "failed" | "degraded" | "disabled" | "stale";
158
+ label: string;
159
+ detail: string;
160
+ pending_events: number;
161
+ last_synced_at: string | null;
162
+ next_retry_after: string | null;
163
+ };
164
+
156
165
  export type GuardRuntimeSnapshot = {
157
166
  generated_at: string;
158
167
  approval_center_url: string | null;
@@ -167,6 +176,7 @@ export type GuardRuntimeSnapshot = {
167
176
  cloud_state_label: string;
168
177
  cloud_state_detail: string;
169
178
  cloud_pairing_state: GuardCloudPairingState;
179
+ cloud_sync_health: GuardCloudSyncHealth;
170
180
  dashboard_url: string;
171
181
  inbox_url: string;
172
182
  fleet_url: string;
@@ -1,5 +1,5 @@
1
1
  import { ActionButton, Badge, KeyValueGrid, SectionLabel, Surface, Tag } from "./approval-center-primitives";
2
- import type { GuardRuntimeSnapshot } from "./guard-types";
2
+ import type { GuardCloudSyncHealth, GuardRuntimeSnapshot } from "./guard-types";
3
3
 
4
4
  type RuntimeOverviewProps = {
5
5
  snapshot: GuardRuntimeSnapshot;
@@ -34,6 +34,35 @@ function remediationLine(snapshot: GuardRuntimeSnapshot): string {
34
34
  return "Open Guard Cloud for shared proof, Watched Apps for local coverage, or the review queue when something needs your choice.";
35
35
  }
36
36
 
37
+ export function resolveCloudSyncHealthCopy(health: GuardCloudSyncHealth): { label: string; detail: string } {
38
+ return {
39
+ label: health.label,
40
+ detail: health.detail
41
+ };
42
+ }
43
+
44
+ function cloudSyncHealthTone(state: GuardCloudSyncHealth["state"]): "blue" | "slate" {
45
+ if (state === "disabled" || state === "failed" || state === "stale") {
46
+ return "slate";
47
+ }
48
+ return "blue";
49
+ }
50
+
51
+ function CloudSyncHealthCard(props: { health: GuardCloudSyncHealth }) {
52
+ const copy = resolveCloudSyncHealthCopy(props.health);
53
+ return (
54
+ <div className="rounded-xl border border-border bg-white px-5 py-4">
55
+ <div className="flex flex-wrap items-center justify-between gap-2">
56
+ <p className="text-xs font-semibold uppercase tracking-[0.18em] text-brand-blue">
57
+ Cloud sync health
58
+ </p>
59
+ <Tag tone={cloudSyncHealthTone(props.health.state)}>{copy.label}</Tag>
60
+ </div>
61
+ <p className="mt-2 text-sm leading-relaxed text-brand-dark/80">{copy.detail}</p>
62
+ </div>
63
+ );
64
+ }
65
+
37
66
  export function RuntimeOverview(props: RuntimeOverviewProps) {
38
67
  const { snapshot } = props;
39
68
 
@@ -72,6 +101,8 @@ export function RuntimeOverview(props: RuntimeOverviewProps) {
72
101
  />
73
102
  </div>
74
103
 
104
+ <CloudSyncHealthCard health={snapshot.cloud_sync_health} />
105
+
75
106
  <div className="rounded-xl border border-border bg-white px-5 py-4">
76
107
  <p className="text-xs font-semibold uppercase tracking-[0.18em] text-brand-blue">
77
108
  Recommended next step
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "plugin-scanner"
7
- version = "2.0.117"
7
+ version = "2.0.118"
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.117"
7
+ version = "2.0.118"
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"
@@ -0,0 +1,223 @@
1
+ """Local access graph snapshot event queueing for Guard Cloud."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+
8
+ from .edge_events import build_access_graph_snapshot_event
9
+ from .models import HarnessDetection
10
+ from .redaction import redact_sensitive_text
11
+ from .store import GuardStore
12
+
13
+
14
+ def queue_access_graph_snapshot(
15
+ *,
16
+ store: GuardStore,
17
+ detection: HarnessDetection,
18
+ artifacts: list[dict[str, object]],
19
+ now: str,
20
+ ) -> None:
21
+ workspace_id = store.get_cloud_workspace_id()
22
+ device_id = store.get_or_create_installation_id()
23
+ device_fingerprint = f"device:{device_id}"
24
+ harness_fingerprint = f"harness:{detection.harness}"
25
+ agent_id = f"{detection.harness}:local-agent"
26
+ agent_fingerprint = f"agent:{agent_id}"
27
+ entities: list[dict[str, object]] = []
28
+ edges: list[dict[str, object]] = []
29
+ seen_fingerprints: set[str] = set()
30
+
31
+ def add_entity(entity: dict[str, object]) -> None:
32
+ fingerprint = entity.get("fingerprint")
33
+ if not isinstance(fingerprint, str) or fingerprint in seen_fingerprints:
34
+ return
35
+ seen_fingerprints.add(fingerprint)
36
+ entities.append(entity)
37
+
38
+ _add_device_harness_and_agent(
39
+ add_entity=add_entity,
40
+ edges=edges,
41
+ device_id=device_id,
42
+ device_fingerprint=device_fingerprint,
43
+ detection=detection,
44
+ harness_fingerprint=harness_fingerprint,
45
+ agent_id=agent_id,
46
+ agent_fingerprint=agent_fingerprint,
47
+ now=now,
48
+ )
49
+ _add_artifact_entities(
50
+ add_entity=add_entity,
51
+ edges=edges,
52
+ artifacts=artifacts,
53
+ agent_fingerprint=agent_fingerprint,
54
+ now=now,
55
+ )
56
+ snapshot_seed = {
57
+ "workspace": workspace_id,
58
+ "device": device_id,
59
+ "harness": detection.harness,
60
+ "generatedAt": now,
61
+ }
62
+ snapshot_hash = hashlib.sha256(json.dumps(snapshot_seed, sort_keys=True).encode("utf-8")).hexdigest()[:24]
63
+ snapshot_id = f"access-graph-{snapshot_hash}"
64
+ payload = {
65
+ "snapshotId": snapshot_id,
66
+ "generatedAt": now,
67
+ "entities": entities,
68
+ "edges": edges,
69
+ }
70
+ try:
71
+ store.add_guard_event_v1(
72
+ build_access_graph_snapshot_event(
73
+ snapshot_id=snapshot_id,
74
+ occurred_at=now,
75
+ payload=payload,
76
+ workspace_id=workspace_id,
77
+ device_id=device_id,
78
+ )
79
+ )
80
+ except Exception as error:
81
+ store.add_event(
82
+ "access_graph_snapshot_queue_failed",
83
+ {
84
+ "error_type": type(error).__name__,
85
+ "message": redact_sensitive_text(str(error)),
86
+ },
87
+ now,
88
+ )
89
+
90
+
91
+ def _add_device_harness_and_agent(
92
+ *,
93
+ add_entity,
94
+ edges: list[dict[str, object]],
95
+ device_id: str,
96
+ device_fingerprint: str,
97
+ detection: HarnessDetection,
98
+ harness_fingerprint: str,
99
+ agent_id: str,
100
+ agent_fingerprint: str,
101
+ now: str,
102
+ ) -> None:
103
+ add_entity(
104
+ {
105
+ "entityType": "device",
106
+ "entityId": device_id,
107
+ "displayName": "Local machine",
108
+ "fingerprint": device_fingerprint,
109
+ "metadata": {},
110
+ "firstSeenAt": now,
111
+ "lastSeenAt": now,
112
+ }
113
+ )
114
+ add_entity(
115
+ {
116
+ "entityType": "harness",
117
+ "entityId": detection.harness,
118
+ "displayName": detection.harness,
119
+ "fingerprint": harness_fingerprint,
120
+ "metadata": {"installed": detection.installed, "commandAvailable": detection.command_available},
121
+ "firstSeenAt": now,
122
+ "lastSeenAt": now,
123
+ }
124
+ )
125
+ edges.append(
126
+ {
127
+ "sourceFingerprint": device_fingerprint,
128
+ "targetFingerprint": harness_fingerprint,
129
+ "edgeType": "device_runs_harness",
130
+ "confidence": 100,
131
+ "metadata": {},
132
+ "firstSeenAt": now,
133
+ "lastSeenAt": now,
134
+ }
135
+ )
136
+ add_entity(
137
+ {
138
+ "entityType": "agent",
139
+ "entityId": agent_id,
140
+ "displayName": f"{detection.harness} local agent",
141
+ "fingerprint": agent_fingerprint,
142
+ "metadata": {"harness": detection.harness},
143
+ "firstSeenAt": now,
144
+ "lastSeenAt": now,
145
+ }
146
+ )
147
+ edges.append(
148
+ {
149
+ "sourceFingerprint": harness_fingerprint,
150
+ "targetFingerprint": agent_fingerprint,
151
+ "edgeType": "harness_runs_agent",
152
+ "confidence": 90,
153
+ "metadata": {},
154
+ "firstSeenAt": now,
155
+ "lastSeenAt": now,
156
+ }
157
+ )
158
+
159
+
160
+ def _add_artifact_entities(
161
+ *,
162
+ add_entity,
163
+ edges: list[dict[str, object]],
164
+ artifacts: list[dict[str, object]],
165
+ agent_fingerprint: str,
166
+ now: str,
167
+ ) -> None:
168
+ for artifact in artifacts:
169
+ artifact_id = _non_empty_string(artifact.get("artifact_id"))
170
+ if artifact_id is None:
171
+ continue
172
+ artifact_type = _non_empty_string(artifact.get("artifact_type")) or "tool"
173
+ entity_type = _access_graph_entity_type(artifact_type)
174
+ fingerprint = f"{entity_type}:{artifact_id}"
175
+ add_entity(
176
+ {
177
+ "entityType": entity_type,
178
+ "entityId": artifact_id,
179
+ "displayName": _non_empty_string(artifact.get("artifact_name")) or artifact_id,
180
+ "fingerprint": fingerprint,
181
+ "metadata": {
182
+ "artifactType": artifact_type,
183
+ "sourceScope": _non_empty_string(artifact.get("source_scope")),
184
+ "policyAction": _non_empty_string(artifact.get("policy_action")),
185
+ "present": artifact.get("removed") is not True,
186
+ },
187
+ "firstSeenAt": now,
188
+ "lastSeenAt": now,
189
+ }
190
+ )
191
+ edge_type = _access_graph_artifact_edge_type(entity_type)
192
+ if edge_type is not None:
193
+ edges.append(
194
+ {
195
+ "sourceFingerprint": agent_fingerprint,
196
+ "targetFingerprint": fingerprint,
197
+ "edgeType": edge_type,
198
+ "confidence": 80,
199
+ "metadata": {},
200
+ "firstSeenAt": now,
201
+ "lastSeenAt": now,
202
+ }
203
+ )
204
+
205
+
206
+ def _access_graph_entity_type(artifact_type: str) -> str:
207
+ if artifact_type in {"skill", "mcp_server", "tool", "repository", "agent", "policy", "integration"}:
208
+ return artifact_type
209
+ return "tool"
210
+
211
+
212
+ def _access_graph_artifact_edge_type(entity_type: str) -> str | None:
213
+ if entity_type == "skill":
214
+ return "agent_uses_skill"
215
+ if entity_type == "mcp_server":
216
+ return "agent_uses_mcp_server"
217
+ return None
218
+
219
+
220
+ def _non_empty_string(value: object) -> str | None:
221
+ if isinstance(value, str) and value.strip():
222
+ return value
223
+ return None
@@ -6,7 +6,7 @@ import time
6
6
  import uuid
7
7
  from collections.abc import Mapping
8
8
  from dataclasses import replace
9
- from datetime import datetime, timezone
9
+ from datetime import datetime, timedelta, timezone
10
10
  from pathlib import Path
11
11
  from urllib.parse import urlparse
12
12
 
@@ -374,11 +374,13 @@ def _build_runtime_cloud_context(store: GuardStore) -> dict[str, object]:
374
374
  remote_payload_active=remote_payload_active,
375
375
  )
376
376
  dashboard_url, inbox_url, fleet_url, connect_url = _resolve_guard_urls(sync_url)
377
+ sync_health = _build_cloud_sync_health(store, credentials is not None, cloud_state)
377
378
  return {
378
379
  "sync_configured": credentials is not None,
379
380
  "cloud_state": cloud_state,
380
381
  "cloud_state_label": _runtime_cloud_state_label(cloud_state),
381
382
  "cloud_state_detail": _runtime_cloud_state_detail(cloud_state),
383
+ "cloud_sync_health": sync_health,
382
384
  "cloud_pairing_state": {
383
385
  "state": cloud_state,
384
386
  "label": _runtime_cloud_state_label(cloud_state),
@@ -396,6 +398,102 @@ def _build_runtime_cloud_context(store: GuardStore) -> dict[str, object]:
396
398
  }
397
399
 
398
400
 
401
+ def _build_cloud_sync_health(store: GuardStore, sync_configured: bool, cloud_state: str) -> dict[str, object]:
402
+ pending_events = store.count_guard_events_v1(uploaded=False)
403
+ event_summary = store.get_sync_payload("guard_events_v1_summary") or {}
404
+ sync_summary = store.get_sync_payload("sync_summary") or {}
405
+ runtime_summary = store.get_sync_payload("runtime_session_summary") or {}
406
+ last_synced_at = _latest_sync_timestamp(
407
+ event_summary.get("synced_at"),
408
+ sync_summary.get("synced_at"),
409
+ runtime_summary.get("synced_at"),
410
+ )
411
+ if not sync_configured:
412
+ state = "disabled"
413
+ elif isinstance(event_summary, dict) and event_summary.get("status") == "failed":
414
+ state = "failed"
415
+ elif (
416
+ isinstance(event_summary, dict)
417
+ and event_summary.get("sync_skipped") is True
418
+ and event_summary.get("sync_reason") == "guard_events_endpoint_unavailable"
419
+ ):
420
+ state = "degraded"
421
+ elif last_synced_at is not None and _timestamp_is_stale(last_synced_at):
422
+ state = "stale"
423
+ elif pending_events > 0 or cloud_state == "paired_waiting":
424
+ state = "pending"
425
+ else:
426
+ state = "healthy"
427
+ return {
428
+ "state": state,
429
+ "label": _cloud_sync_health_label(state),
430
+ "detail": _cloud_sync_health_detail(state, pending_events=pending_events),
431
+ "pending_events": pending_events,
432
+ "last_synced_at": last_synced_at,
433
+ "next_retry_after": event_summary.get("next_retry_after") if isinstance(event_summary, dict) else None,
434
+ }
435
+
436
+
437
+ def _latest_sync_timestamp(*values: object) -> str | None:
438
+ parsed_values: list[tuple[datetime, str]] = []
439
+ for value in values:
440
+ if not isinstance(value, str) or not value.strip():
441
+ continue
442
+ parsed = _parse_timestamp(value)
443
+ if parsed is not None:
444
+ parsed_values.append((parsed, value))
445
+ if not parsed_values:
446
+ return None
447
+ return max(parsed_values, key=lambda item: item[0])[1]
448
+
449
+
450
+ def _parse_timestamp(value: str) -> datetime | None:
451
+ try:
452
+ parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
453
+ except ValueError:
454
+ return None
455
+ if parsed.tzinfo is None:
456
+ return parsed.replace(tzinfo=timezone.utc)
457
+ return parsed
458
+
459
+
460
+ def _timestamp_is_stale(value: str) -> bool:
461
+ parsed = _parse_timestamp(value)
462
+ if parsed is None:
463
+ return False
464
+ return datetime.now(timezone.utc) - parsed > timedelta(hours=24)
465
+
466
+
467
+ def _cloud_sync_health_label(state: str) -> str:
468
+ labels = {
469
+ "healthy": "Cloud sync healthy",
470
+ "pending": "Cloud sync pending",
471
+ "failed": "Cloud sync needs attention",
472
+ "degraded": "Cloud sync degraded",
473
+ "disabled": "Cloud sync disabled",
474
+ "stale": "Cloud sync stale",
475
+ }
476
+ return labels.get(state, "Cloud sync pending")
477
+
478
+
479
+ def _cloud_sync_health_detail(state: str, *, pending_events: int) -> str:
480
+ if state == "healthy":
481
+ return "Guard Cloud has the latest local proof from this machine."
482
+ if state == "failed":
483
+ return "The latest Cloud upload failed. HOL Guard kept local protection active and will retry."
484
+ if state == "degraded":
485
+ return "Cloud accepted legacy sync, but v1 Guard event ingest is unavailable. Local protection stayed active."
486
+ if state == "disabled":
487
+ return "Local protection is active. Connect Cloud when you want shared team proof."
488
+ if state == "stale":
489
+ return "Cloud has not seen fresh local proof recently. Keep this runtime open or run sync again."
490
+ if pending_events == 1:
491
+ return "One local proof event is queued for the next Cloud sync."
492
+ if pending_events > 1:
493
+ return f"{pending_events} local proof events are queued for the next Cloud sync."
494
+ return "Waiting for the first shared Cloud proof from this machine."
495
+
496
+
399
497
  def _resolve_runtime_cloud_state(*, sync_configured: bool, sync_completed: bool, remote_payload_active: bool) -> str:
400
498
  if not sync_configured:
401
499
  return "local_only"
@@ -95,6 +95,7 @@ from ..runtime.secret_file_requests import (
95
95
  build_file_read_request_artifact,
96
96
  build_tool_action_request_artifact,
97
97
  extract_sensitive_file_read_request,
98
+ extract_sensitive_file_read_request_from_action,
98
99
  extract_sensitive_tool_action_request,
99
100
  is_explicitly_benign_tool_action_request,
100
101
  )
@@ -1455,6 +1456,7 @@ def run_guard_command(
1455
1456
  runtime_artifact = _hook_runtime_artifact(
1456
1457
  harness=args.harness,
1457
1458
  payload=payload,
1459
+ action_envelope=action_envelope,
1458
1460
  home_dir=context.home_dir,
1459
1461
  guard_home=context.guard_home,
1460
1462
  workspace=runtime_workspace,
@@ -4019,6 +4021,7 @@ def _hook_runtime_artifact(
4019
4021
  *,
4020
4022
  harness: str,
4021
4023
  payload: dict[str, object],
4024
+ action_envelope: GuardActionEnvelope | None,
4022
4025
  home_dir: Path,
4023
4026
  guard_home: Path,
4024
4027
  workspace: Path | None,
@@ -4079,6 +4082,12 @@ def _hook_runtime_artifact(
4079
4082
  cwd=workspace,
4080
4083
  home_dir=home_dir,
4081
4084
  )
4085
+ if request is None:
4086
+ request = (
4087
+ extract_sensitive_file_read_request_from_action(action_envelope, cwd=workspace, home_dir=home_dir)
4088
+ if action_envelope is not None
4089
+ else None
4090
+ )
4082
4091
  source_scope = _coalesce_string(payload.get("source_scope"), "project")
4083
4092
  config_path = str(_runtime_policy_path(harness, home_dir, workspace))
4084
4093
  if request is not None:
@@ -5916,7 +5925,7 @@ def _guard_service_login_payload(
5916
5925
  "client_title": label,
5917
5926
  "client_version": _GUARD_CLIENT_VERSION,
5918
5927
  }
5919
- store.set_sync_credentials(sync_url, token, now)
5928
+ store.set_sync_credentials(sync_url, token, now, workspace_id=workspace or None)
5920
5929
  store.set_sync_payload(_SERVICE_RUNTIME_PROFILE_STATE_KEY, service_profile, now)
5921
5930
  device = store.set_device_label(label, now)
5922
5931
  store.add_event(
@@ -9,6 +9,7 @@ from pathlib import Path
9
9
  from typing import Any
10
10
 
11
11
  from ...models import ScanOptions
12
+ from ..access_graph_events import queue_access_graph_snapshot
12
13
  from ..adapters import get_adapter, list_adapters
13
14
  from ..adapters.base import HarnessContext
14
15
  from ..capabilities import compute_capability_delta, normalize_artifact_capabilities, severity_from_deltas
@@ -658,6 +659,13 @@ def evaluate_detection(
658
659
  },
659
660
  now,
660
661
  )
662
+ if persist:
663
+ queue_access_graph_snapshot(
664
+ store=store,
665
+ detection=detection,
666
+ artifacts=results,
667
+ now=now,
668
+ )
661
669
  return {
662
670
  "harness": detection.harness,
663
671
  "artifacts": results,