agentguard-linter 0.1.0__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 (418) hide show
  1. agentguard_linter-0.1.0/.dockerignore +15 -0
  2. agentguard_linter-0.1.0/.env.example +6 -0
  3. agentguard_linter-0.1.0/.gitattributes +1 -0
  4. agentguard_linter-0.1.0/.github/actions/agentguard/action.yml +53 -0
  5. agentguard_linter-0.1.0/.github/workflows/ci.yml +82 -0
  6. agentguard_linter-0.1.0/.gitignore +30 -0
  7. agentguard_linter-0.1.0/.nvmrc +1 -0
  8. agentguard_linter-0.1.0/.pre-commit-hooks.yaml +7 -0
  9. agentguard_linter-0.1.0/AGENTS.md +128 -0
  10. agentguard_linter-0.1.0/Dockerfile +22 -0
  11. agentguard_linter-0.1.0/LICENSE +21 -0
  12. agentguard_linter-0.1.0/Makefile +28 -0
  13. agentguard_linter-0.1.0/PKG-INFO +403 -0
  14. agentguard_linter-0.1.0/README.md +361 -0
  15. agentguard_linter-0.1.0/SPEC.md +469 -0
  16. agentguard_linter-0.1.0/STATUS.md +661 -0
  17. agentguard_linter-0.1.0/benchmarks/__init__.py +1 -0
  18. agentguard_linter-0.1.0/benchmarks/corpus_gate.py +76 -0
  19. agentguard_linter-0.1.0/benchmarks/scan_10k.py +161 -0
  20. agentguard_linter-0.1.0/docker-compose.yml +38 -0
  21. agentguard_linter-0.1.0/docs/ROADMAP_AND_ISSUES.md +560 -0
  22. agentguard_linter-0.1.0/docs/architecture.md +79 -0
  23. agentguard_linter-0.1.0/docs/autofix.md +44 -0
  24. agentguard_linter-0.1.0/docs/benchmarks.md +94 -0
  25. agentguard_linter-0.1.0/docs/ci.md +79 -0
  26. agentguard_linter-0.1.0/docs/distribution.md +61 -0
  27. agentguard_linter-0.1.0/docs/rules/AG001.md +70 -0
  28. agentguard_linter-0.1.0/docs/rules/AG002.md +81 -0
  29. agentguard_linter-0.1.0/docs/rules/AG003.md +65 -0
  30. agentguard_linter-0.1.0/docs/rules/AG004.md +35 -0
  31. agentguard_linter-0.1.0/docs/rules/AG005.md +33 -0
  32. agentguard_linter-0.1.0/docs/rules/AG006.md +31 -0
  33. agentguard_linter-0.1.0/docs/rules/AG007.md +32 -0
  34. agentguard_linter-0.1.0/docs/rules/AG008.md +37 -0
  35. agentguard_linter-0.1.0/docs/rules/AG009.md +32 -0
  36. agentguard_linter-0.1.0/docs/rules/AG010.md +32 -0
  37. agentguard_linter-0.1.0/docs/rules/AG011.md +33 -0
  38. agentguard_linter-0.1.0/docs/rules/AG020.md +33 -0
  39. agentguard_linter-0.1.0/docs/rules/AG021.md +31 -0
  40. agentguard_linter-0.1.0/docs/rules/AG022.md +33 -0
  41. agentguard_linter-0.1.0/docs/rules/AG023.md +31 -0
  42. agentguard_linter-0.1.0/docs/server.md +105 -0
  43. agentguard_linter-0.1.0/examples/clean_agent/clean_agent.py +22 -0
  44. agentguard_linter-0.1.0/examples/langgraph_support_bot/support_bot.py +47 -0
  45. agentguard_linter-0.1.0/examples/plain_python_agent/plain_agent.py +28 -0
  46. agentguard_linter-0.1.0/packages/agentguard-core/README.md +7 -0
  47. agentguard_linter-0.1.0/packages/agentguard-core/pyproject.toml +19 -0
  48. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/__init__.py +3 -0
  49. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/__main__.py +6 -0
  50. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/__init__.py +13 -0
  51. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/autogen.py +60 -0
  52. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/base.py +24 -0
  53. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/crewai.py +60 -0
  54. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/generic.py +735 -0
  55. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/baseline.py +63 -0
  56. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/__init__.py +48 -0
  57. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/baseline.py +32 -0
  58. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/plugins.py +162 -0
  59. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/rules.py +45 -0
  60. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/scan.py +360 -0
  61. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/config.py +134 -0
  62. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/__init__.py +1 -0
  63. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/discovery.py +165 -0
  64. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/fingerprint.py +20 -0
  65. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/parser.py +81 -0
  66. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/runner.py +99 -0
  67. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/suppression.py +97 -0
  68. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/findings.py +83 -0
  69. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/__init__.py +15 -0
  70. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/ag003_timeout.py +68 -0
  71. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/ag004_recursion_limit.py +104 -0
  72. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/ag010_model_pin.py +73 -0
  73. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/engine.py +66 -0
  74. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/__init__.py +41 -0
  75. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/builder.py +38 -0
  76. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/calls.py +75 -0
  77. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/models.py +232 -0
  78. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/taint.py +208 -0
  79. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/taint_interprocedural.py +792 -0
  80. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/__init__.py +6 -0
  81. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/builtin.py +69 -0
  82. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/manager.py +183 -0
  83. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/spec.py +47 -0
  84. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/__init__.py +8 -0
  85. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/base.py +17 -0
  86. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/json_reporter.py +54 -0
  87. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/sarif.py +111 -0
  88. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/text.py +34 -0
  89. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/__init__.py +12 -0
  90. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag001_unbounded_retries.py +72 -0
  91. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag002_shared_mutable_fanout.py +122 -0
  92. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag003_missing_timeout.py +54 -0
  93. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag004_unbounded_agent_loop.py +30 -0
  94. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag005_no_cost_budget.py +34 -0
  95. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag006_unreachable_graph_node.py +30 -0
  96. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag007_conditional_edge_unmapped_key.py +34 -0
  97. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag008_exception_swallowed_in_tool.py +40 -0
  98. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag009_non_idempotent_tool_with_retry.py +36 -0
  99. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag010_unpinned_model_alias.py +34 -0
  100. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag011_unbounded_state_growth.py +27 -0
  101. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag020_prompt_injection_sink.py +35 -0
  102. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag021_dangerous_tool_no_approval.py +34 -0
  103. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag022_llm_output_to_sink.py +39 -0
  104. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag023_hardcoded_secret.py +30 -0
  105. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/base.py +100 -0
  106. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/builtins.py +9 -0
  107. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/phase3_common.py +50 -0
  108. agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/registry.py +95 -0
  109. agentguard_linter-0.1.0/packages/agentguard-graph/README.md +27 -0
  110. agentguard_linter-0.1.0/packages/agentguard-graph/pyproject.toml +15 -0
  111. agentguard_linter-0.1.0/packages/agentguard-graph/src/agentguard_graph/__init__.py +314 -0
  112. agentguard_linter-0.1.0/packages/agentguard-langgraph/README.md +4 -0
  113. agentguard_linter-0.1.0/packages/agentguard-langgraph/pyproject.toml +16 -0
  114. agentguard_linter-0.1.0/packages/agentguard-langgraph/src/agentguard_langgraph/__init__.py +14 -0
  115. agentguard_linter-0.1.0/packages/agentguard-langgraph/src/agentguard_langgraph/adapter.py +475 -0
  116. agentguard_linter-0.1.0/packages/agentguard-llm-triage/README.md +73 -0
  117. agentguard_linter-0.1.0/packages/agentguard-llm-triage/pyproject.toml +15 -0
  118. agentguard_linter-0.1.0/packages/agentguard-llm-triage/src/agentguard_llm_triage/__init__.py +638 -0
  119. agentguard_linter-0.1.0/packages/agentguard-owasp/README.md +22 -0
  120. agentguard_linter-0.1.0/packages/agentguard-owasp/pyproject.toml +15 -0
  121. agentguard_linter-0.1.0/packages/agentguard-owasp/src/agentguard_owasp/__init__.py +52 -0
  122. agentguard_linter-0.1.0/packages/agentguard-server/README.md +69 -0
  123. agentguard_linter-0.1.0/packages/agentguard-server/alembic/env.py +56 -0
  124. agentguard_linter-0.1.0/packages/agentguard-server/alembic/script.py.mako +24 -0
  125. agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0001_initial.py +170 -0
  126. agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0002_webhook_deliveries.py +33 -0
  127. agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0003_badge_visibility.py +25 -0
  128. agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0004_audit_records.py +35 -0
  129. agentguard_linter-0.1.0/packages/agentguard-server/alembic.ini +38 -0
  130. agentguard_linter-0.1.0/packages/agentguard-server/pyproject.toml +35 -0
  131. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/__init__.py +7 -0
  132. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/api.py +634 -0
  133. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/app.py +138 -0
  134. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/audit.py +108 -0
  135. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/badges.py +326 -0
  136. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/config.py +103 -0
  137. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/db.py +33 -0
  138. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/github.py +307 -0
  139. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/main.py +21 -0
  140. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/models.py +295 -0
  141. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/platform_api.py +194 -0
  142. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/retention.py +48 -0
  143. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/schemas.py +216 -0
  144. agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/security.py +197 -0
  145. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_api.py +197 -0
  146. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_audit.py +33 -0
  147. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_badges.py +163 -0
  148. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_config.py +34 -0
  149. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_github.py +168 -0
  150. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_http_platform.py +193 -0
  151. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_models.py +36 -0
  152. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_postgres.py +54 -0
  153. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_retention.py +45 -0
  154. agentguard_linter-0.1.0/packages/agentguard-server/tests/test_security.py +51 -0
  155. agentguard_linter-0.1.0/packages/agentguard-trace/README.md +44 -0
  156. agentguard_linter-0.1.0/packages/agentguard-trace/pyproject.toml +15 -0
  157. agentguard_linter-0.1.0/packages/agentguard-trace/src/agentguard_trace/__init__.py +807 -0
  158. agentguard_linter-0.1.0/pyproject.toml +107 -0
  159. agentguard_linter-0.1.0/tests/__init__.py +1 -0
  160. agentguard_linter-0.1.0/tests/fixture_support.py +57 -0
  161. agentguard_linter-0.1.0/tests/fixtures/ag001/bad_backoff.py +7 -0
  162. agentguard_linter-0.1.0/tests/fixtures/ag001/bad_max_retries.py +3 -0
  163. agentguard_linter-0.1.0/tests/fixtures/ag001/bad_recursion.py +10 -0
  164. agentguard_linter-0.1.0/tests/fixtures/ag001/bad_tenacity.py +9 -0
  165. agentguard_linter-0.1.0/tests/fixtures/ag001/bad_while.py +9 -0
  166. agentguard_linter-0.1.0/tests/fixtures/ag001/edge_dynamic_max.py +4 -0
  167. agentguard_linter-0.1.0/tests/fixtures/ag001/edge_unknown_bound.py +13 -0
  168. agentguard_linter-0.1.0/tests/fixtures/ag001/edge_wait_only.py +9 -0
  169. agentguard_linter-0.1.0/tests/fixtures/ag001/good_backoff.py +7 -0
  170. agentguard_linter-0.1.0/tests/fixtures/ag001/good_bounded_for.py +6 -0
  171. agentguard_linter-0.1.0/tests/fixtures/ag001/good_deadline.py +8 -0
  172. agentguard_linter-0.1.0/tests/fixtures/ag001/good_event_loop.py +3 -0
  173. agentguard_linter-0.1.0/tests/fixtures/ag001/good_tenacity.py +6 -0
  174. agentguard_linter-0.1.0/tests/fixtures/ag002/bad_asyncio.py +11 -0
  175. agentguard_linter-0.1.0/tests/fixtures/ag002/bad_langgraph_send.py +20 -0
  176. agentguard_linter-0.1.0/tests/fixtures/ag002/bad_langgraph_static.py +23 -0
  177. agentguard_linter-0.1.0/tests/fixtures/ag002/bad_mutable_default.py +9 -0
  178. agentguard_linter-0.1.0/tests/fixtures/ag002/bad_thread_pool.py +11 -0
  179. agentguard_linter-0.1.0/tests/fixtures/ag002/edge_dynamic_fanout.py +9 -0
  180. agentguard_linter-0.1.0/tests/fixtures/ag002/edge_single_writer.py +11 -0
  181. agentguard_linter-0.1.0/tests/fixtures/ag002/edge_state_reducer_custom.py +27 -0
  182. agentguard_linter-0.1.0/tests/fixtures/ag002/good_default_none.py +10 -0
  183. agentguard_linter-0.1.0/tests/fixtures/ag002/good_langgraph_reducer.py +24 -0
  184. agentguard_linter-0.1.0/tests/fixtures/ag002/good_local.py +11 -0
  185. agentguard_linter-0.1.0/tests/fixtures/ag002/good_lock.py +14 -0
  186. agentguard_linter-0.1.0/tests/fixtures/ag002/good_read_only.py +11 -0
  187. agentguard_linter-0.1.0/tests/fixtures/ag002/good_sequential.py +8 -0
  188. agentguard_linter-0.1.0/tests/fixtures/ag003/bad_httpx_none.py +3 -0
  189. agentguard_linter-0.1.0/tests/fixtures/ag003/bad_langchain.py +3 -0
  190. agentguard_linter-0.1.0/tests/fixtures/ag003/bad_loop.py +4 -0
  191. agentguard_linter-0.1.0/tests/fixtures/ag003/bad_openai.py +4 -0
  192. agentguard_linter-0.1.0/tests/fixtures/ag003/bad_requests.py +3 -0
  193. agentguard_linter-0.1.0/tests/fixtures/ag003/edge_aiohttp.py +3 -0
  194. agentguard_linter-0.1.0/tests/fixtures/ag003/edge_alias.py +3 -0
  195. agentguard_linter-0.1.0/tests/fixtures/ag003/edge_dynamic_timeout.py +4 -0
  196. agentguard_linter-0.1.0/tests/fixtures/ag003/good_httpx_default.py +3 -0
  197. agentguard_linter-0.1.0/tests/fixtures/ag003/good_kwargs.py +4 -0
  198. agentguard_linter-0.1.0/tests/fixtures/ag003/good_openai.py +4 -0
  199. agentguard_linter-0.1.0/tests/fixtures/ag003/good_requests.py +3 -0
  200. agentguard_linter-0.1.0/tests/fixtures/ag003/good_subprocess.py +3 -0
  201. agentguard_linter-0.1.0/tests/fixtures/ag004/bad_cycle.py +18 -0
  202. agentguard_linter-0.1.0/tests/fixtures/ag004/bad_five.py +17 -0
  203. agentguard_linter-0.1.0/tests/fixtures/ag004/bad_four.py +17 -0
  204. agentguard_linter-0.1.0/tests/fixtures/ag004/bad_three.py +17 -0
  205. agentguard_linter-0.1.0/tests/fixtures/ag004/bad_two.py +17 -0
  206. agentguard_linter-0.1.0/tests/fixtures/ag004/edge_no_cycle.py +11 -0
  207. agentguard_linter-0.1.0/tests/fixtures/ag004/edge_three.py +3 -0
  208. agentguard_linter-0.1.0/tests/fixtures/ag004/edge_two.py +10 -0
  209. agentguard_linter-0.1.0/tests/fixtures/ag004/good_five.py +18 -0
  210. agentguard_linter-0.1.0/tests/fixtures/ag004/good_four.py +18 -0
  211. agentguard_linter-0.1.0/tests/fixtures/ag004/good_limit.py +19 -0
  212. agentguard_linter-0.1.0/tests/fixtures/ag004/good_three.py +18 -0
  213. agentguard_linter-0.1.0/tests/fixtures/ag004/good_two.py +18 -0
  214. agentguard_linter-0.1.0/tests/fixtures/ag005/bad_five.py +5 -0
  215. agentguard_linter-0.1.0/tests/fixtures/ag005/bad_four.py +10 -0
  216. agentguard_linter-0.1.0/tests/fixtures/ag005/bad_loop_budget.py +5 -0
  217. agentguard_linter-0.1.0/tests/fixtures/ag005/bad_three.py +10 -0
  218. agentguard_linter-0.1.0/tests/fixtures/ag005/bad_two.py +5 -0
  219. agentguard_linter-0.1.0/tests/fixtures/ag005/edge_dynamic_budget.py +11 -0
  220. agentguard_linter-0.1.0/tests/fixtures/ag005/edge_three.py +7 -0
  221. agentguard_linter-0.1.0/tests/fixtures/ag005/edge_two.py +11 -0
  222. agentguard_linter-0.1.0/tests/fixtures/ag005/good_five.py +10 -0
  223. agentguard_linter-0.1.0/tests/fixtures/ag005/good_four.py +5 -0
  224. agentguard_linter-0.1.0/tests/fixtures/ag005/good_loop_budget.py +5 -0
  225. agentguard_linter-0.1.0/tests/fixtures/ag005/good_three.py +5 -0
  226. agentguard_linter-0.1.0/tests/fixtures/ag005/good_two.py +5 -0
  227. agentguard_linter-0.1.0/tests/fixtures/ag006/bad_five.py +15 -0
  228. agentguard_linter-0.1.0/tests/fixtures/ag006/bad_four.py +15 -0
  229. agentguard_linter-0.1.0/tests/fixtures/ag006/bad_orphan.py +16 -0
  230. agentguard_linter-0.1.0/tests/fixtures/ag006/bad_three.py +15 -0
  231. agentguard_linter-0.1.0/tests/fixtures/ag006/bad_two.py +15 -0
  232. agentguard_linter-0.1.0/tests/fixtures/ag006/edge_missing_entry.py +10 -0
  233. agentguard_linter-0.1.0/tests/fixtures/ag006/edge_three.py +10 -0
  234. agentguard_linter-0.1.0/tests/fixtures/ag006/edge_two.py +3 -0
  235. agentguard_linter-0.1.0/tests/fixtures/ag006/good_connected.py +17 -0
  236. agentguard_linter-0.1.0/tests/fixtures/ag006/good_five.py +16 -0
  237. agentguard_linter-0.1.0/tests/fixtures/ag006/good_four.py +16 -0
  238. agentguard_linter-0.1.0/tests/fixtures/ag006/good_three.py +16 -0
  239. agentguard_linter-0.1.0/tests/fixtures/ag006/good_two.py +16 -0
  240. agentguard_linter-0.1.0/tests/fixtures/ag007/bad_five.py +10 -0
  241. agentguard_linter-0.1.0/tests/fixtures/ag007/bad_four.py +10 -0
  242. agentguard_linter-0.1.0/tests/fixtures/ag007/bad_route.py +10 -0
  243. agentguard_linter-0.1.0/tests/fixtures/ag007/bad_three.py +10 -0
  244. agentguard_linter-0.1.0/tests/fixtures/ag007/bad_two.py +10 -0
  245. agentguard_linter-0.1.0/tests/fixtures/ag007/edge_terminal_route.py +10 -0
  246. agentguard_linter-0.1.0/tests/fixtures/ag007/edge_three.py +14 -0
  247. agentguard_linter-0.1.0/tests/fixtures/ag007/edge_two.py +10 -0
  248. agentguard_linter-0.1.0/tests/fixtures/ag007/good_five.py +10 -0
  249. agentguard_linter-0.1.0/tests/fixtures/ag007/good_four.py +10 -0
  250. agentguard_linter-0.1.0/tests/fixtures/ag007/good_route.py +11 -0
  251. agentguard_linter-0.1.0/tests/fixtures/ag007/good_three.py +10 -0
  252. agentguard_linter-0.1.0/tests/fixtures/ag007/good_two.py +10 -0
  253. agentguard_linter-0.1.0/tests/fixtures/ag008/bad_five.py +9 -0
  254. agentguard_linter-0.1.0/tests/fixtures/ag008/bad_four.py +9 -0
  255. agentguard_linter-0.1.0/tests/fixtures/ag008/bad_three.py +9 -0
  256. agentguard_linter-0.1.0/tests/fixtures/ag008/bad_tool_exception.py +13 -0
  257. agentguard_linter-0.1.0/tests/fixtures/ag008/bad_two.py +9 -0
  258. agentguard_linter-0.1.0/tests/fixtures/ag008/edge_fallback.py +13 -0
  259. agentguard_linter-0.1.0/tests/fixtures/ag008/edge_three.py +9 -0
  260. agentguard_linter-0.1.0/tests/fixtures/ag008/edge_two.py +9 -0
  261. agentguard_linter-0.1.0/tests/fixtures/ag008/good_five.py +9 -0
  262. agentguard_linter-0.1.0/tests/fixtures/ag008/good_four.py +9 -0
  263. agentguard_linter-0.1.0/tests/fixtures/ag008/good_three.py +15 -0
  264. agentguard_linter-0.1.0/tests/fixtures/ag008/good_tool_exception.py +19 -0
  265. agentguard_linter-0.1.0/tests/fixtures/ag008/good_two.py +15 -0
  266. agentguard_linter-0.1.0/tests/fixtures/ag009/bad_five.py +6 -0
  267. agentguard_linter-0.1.0/tests/fixtures/ag009/bad_four.py +10 -0
  268. agentguard_linter-0.1.0/tests/fixtures/ag009/bad_retry_tool.py +6 -0
  269. agentguard_linter-0.1.0/tests/fixtures/ag009/bad_three.py +6 -0
  270. agentguard_linter-0.1.0/tests/fixtures/ag009/bad_two.py +6 -0
  271. agentguard_linter-0.1.0/tests/fixtures/ag009/edge_bounded.py +6 -0
  272. agentguard_linter-0.1.0/tests/fixtures/ag009/edge_three.py +10 -0
  273. agentguard_linter-0.1.0/tests/fixtures/ag009/edge_two.py +6 -0
  274. agentguard_linter-0.1.0/tests/fixtures/ag009/good_five.py +6 -0
  275. agentguard_linter-0.1.0/tests/fixtures/ag009/good_four.py +6 -0
  276. agentguard_linter-0.1.0/tests/fixtures/ag009/good_no_retry.py +5 -0
  277. agentguard_linter-0.1.0/tests/fixtures/ag009/good_three.py +6 -0
  278. agentguard_linter-0.1.0/tests/fixtures/ag009/good_two.py +5 -0
  279. agentguard_linter-0.1.0/tests/fixtures/ag010/bad_alias.py +4 -0
  280. agentguard_linter-0.1.0/tests/fixtures/ag010/bad_five.py +4 -0
  281. agentguard_linter-0.1.0/tests/fixtures/ag010/bad_four.py +4 -0
  282. agentguard_linter-0.1.0/tests/fixtures/ag010/bad_three.py +4 -0
  283. agentguard_linter-0.1.0/tests/fixtures/ag010/bad_two.py +4 -0
  284. agentguard_linter-0.1.0/tests/fixtures/ag010/edge_dynamic.py +10 -0
  285. agentguard_linter-0.1.0/tests/fixtures/ag010/edge_three.py +4 -0
  286. agentguard_linter-0.1.0/tests/fixtures/ag010/edge_two.py +9 -0
  287. agentguard_linter-0.1.0/tests/fixtures/ag010/good_five.py +4 -0
  288. agentguard_linter-0.1.0/tests/fixtures/ag010/good_four.py +4 -0
  289. agentguard_linter-0.1.0/tests/fixtures/ag010/good_pinned.py +4 -0
  290. agentguard_linter-0.1.0/tests/fixtures/ag010/good_three.py +4 -0
  291. agentguard_linter-0.1.0/tests/fixtures/ag010/good_two.py +4 -0
  292. agentguard_linter-0.1.0/tests/fixtures/ag011/bad_five.py +6 -0
  293. agentguard_linter-0.1.0/tests/fixtures/ag011/bad_four.py +3 -0
  294. agentguard_linter-0.1.0/tests/fixtures/ag011/bad_growth.py +3 -0
  295. agentguard_linter-0.1.0/tests/fixtures/ag011/bad_three.py +6 -0
  296. agentguard_linter-0.1.0/tests/fixtures/ag011/bad_two.py +7 -0
  297. agentguard_linter-0.1.0/tests/fixtures/ag011/edge_other_collection.py +4 -0
  298. agentguard_linter-0.1.0/tests/fixtures/ag011/edge_three.py +10 -0
  299. agentguard_linter-0.1.0/tests/fixtures/ag011/edge_two.py +8 -0
  300. agentguard_linter-0.1.0/tests/fixtures/ag011/good_bounded.py +2 -0
  301. agentguard_linter-0.1.0/tests/fixtures/ag011/good_five.py +11 -0
  302. agentguard_linter-0.1.0/tests/fixtures/ag011/good_four.py +7 -0
  303. agentguard_linter-0.1.0/tests/fixtures/ag011/good_three.py +7 -0
  304. agentguard_linter-0.1.0/tests/fixtures/ag011/good_two.py +2 -0
  305. agentguard_linter-0.1.0/tests/fixtures/ag020/bad_five.py +6 -0
  306. agentguard_linter-0.1.0/tests/fixtures/ag020/bad_four.py +6 -0
  307. agentguard_linter-0.1.0/tests/fixtures/ag020/bad_system_prompt.py +7 -0
  308. agentguard_linter-0.1.0/tests/fixtures/ag020/bad_three.py +7 -0
  309. agentguard_linter-0.1.0/tests/fixtures/ag020/bad_two.py +7 -0
  310. agentguard_linter-0.1.0/tests/fixtures/ag020/edge_literal_prompt.py +6 -0
  311. agentguard_linter-0.1.0/tests/fixtures/ag020/edge_three.py +6 -0
  312. agentguard_linter-0.1.0/tests/fixtures/ag020/edge_two.py +10 -0
  313. agentguard_linter-0.1.0/tests/fixtures/ag020/good_five.py +11 -0
  314. agentguard_linter-0.1.0/tests/fixtures/ag020/good_four.py +6 -0
  315. agentguard_linter-0.1.0/tests/fixtures/ag020/good_three.py +11 -0
  316. agentguard_linter-0.1.0/tests/fixtures/ag020/good_two.py +12 -0
  317. agentguard_linter-0.1.0/tests/fixtures/ag020/good_user_message.py +12 -0
  318. agentguard_linter-0.1.0/tests/fixtures/ag021/bad_delete_tool.py +8 -0
  319. agentguard_linter-0.1.0/tests/fixtures/ag021/bad_five.py +8 -0
  320. agentguard_linter-0.1.0/tests/fixtures/ag021/bad_four.py +8 -0
  321. agentguard_linter-0.1.0/tests/fixtures/ag021/bad_three.py +8 -0
  322. agentguard_linter-0.1.0/tests/fixtures/ag021/bad_two.py +8 -0
  323. agentguard_linter-0.1.0/tests/fixtures/ag021/edge_three.py +9 -0
  324. agentguard_linter-0.1.0/tests/fixtures/ag021/edge_two.py +5 -0
  325. agentguard_linter-0.1.0/tests/fixtures/ag021/edge_unknown_tool.py +8 -0
  326. agentguard_linter-0.1.0/tests/fixtures/ag021/good_approval.py +14 -0
  327. agentguard_linter-0.1.0/tests/fixtures/ag021/good_five.py +13 -0
  328. agentguard_linter-0.1.0/tests/fixtures/ag021/good_four.py +13 -0
  329. agentguard_linter-0.1.0/tests/fixtures/ag021/good_three.py +13 -0
  330. agentguard_linter-0.1.0/tests/fixtures/ag021/good_two.py +13 -0
  331. agentguard_linter-0.1.0/tests/fixtures/ag022/bad_exec_output.py +7 -0
  332. agentguard_linter-0.1.0/tests/fixtures/ag022/bad_five.py +12 -0
  333. agentguard_linter-0.1.0/tests/fixtures/ag022/bad_four.py +5 -0
  334. agentguard_linter-0.1.0/tests/fixtures/ag022/bad_three.py +5 -0
  335. agentguard_linter-0.1.0/tests/fixtures/ag022/bad_two.py +7 -0
  336. agentguard_linter-0.1.0/tests/fixtures/ag022/edge_literal_command.py +3 -0
  337. agentguard_linter-0.1.0/tests/fixtures/ag022/edge_three.py +5 -0
  338. agentguard_linter-0.1.0/tests/fixtures/ag022/edge_two.py +3 -0
  339. agentguard_linter-0.1.0/tests/fixtures/ag022/good_five.py +14 -0
  340. agentguard_linter-0.1.0/tests/fixtures/ag022/good_four.py +9 -0
  341. agentguard_linter-0.1.0/tests/fixtures/ag022/good_three.py +4 -0
  342. agentguard_linter-0.1.0/tests/fixtures/ag022/good_two.py +14 -0
  343. agentguard_linter-0.1.0/tests/fixtures/ag022/good_typed_dispatch.py +15 -0
  344. agentguard_linter-0.1.0/tests/fixtures/ag023/bad_five.py +1 -0
  345. agentguard_linter-0.1.0/tests/fixtures/ag023/bad_four.py +1 -0
  346. agentguard_linter-0.1.0/tests/fixtures/ag023/bad_secret.py +1 -0
  347. agentguard_linter-0.1.0/tests/fixtures/ag023/bad_three.py +1 -0
  348. agentguard_linter-0.1.0/tests/fixtures/ag023/bad_two.py +1 -0
  349. agentguard_linter-0.1.0/tests/fixtures/ag023/edge_test_name.py +5 -0
  350. agentguard_linter-0.1.0/tests/fixtures/ag023/edge_three.py +1 -0
  351. agentguard_linter-0.1.0/tests/fixtures/ag023/edge_two.py +1 -0
  352. agentguard_linter-0.1.0/tests/fixtures/ag023/good_environment.py +3 -0
  353. agentguard_linter-0.1.0/tests/fixtures/ag023/good_five.py +1 -0
  354. agentguard_linter-0.1.0/tests/fixtures/ag023/good_four.py +5 -0
  355. agentguard_linter-0.1.0/tests/fixtures/ag023/good_three.py +3 -0
  356. agentguard_linter-0.1.0/tests/fixtures/ag023/good_two.py +3 -0
  357. agentguard_linter-0.1.0/tests/test_ag001.py +25 -0
  358. agentguard_linter-0.1.0/tests/test_ag002.py +27 -0
  359. agentguard_linter-0.1.0/tests/test_ag003.py +38 -0
  360. agentguard_linter-0.1.0/tests/test_baseline.py +52 -0
  361. agentguard_linter-0.1.0/tests/test_benchmarks.py +41 -0
  362. agentguard_linter-0.1.0/tests/test_bootstrap.py +15 -0
  363. agentguard_linter-0.1.0/tests/test_ci_assets.py +51 -0
  364. agentguard_linter-0.1.0/tests/test_cli.py +273 -0
  365. agentguard_linter-0.1.0/tests/test_cli_plugins.py +59 -0
  366. agentguard_linter-0.1.0/tests/test_config.py +111 -0
  367. agentguard_linter-0.1.0/tests/test_engine.py +96 -0
  368. agentguard_linter-0.1.0/tests/test_engine_edges.py +150 -0
  369. agentguard_linter-0.1.0/tests/test_findings.py +74 -0
  370. agentguard_linter-0.1.0/tests/test_fixes.py +154 -0
  371. agentguard_linter-0.1.0/tests/test_framework_adapters.py +37 -0
  372. agentguard_linter-0.1.0/tests/test_generic_adapter.py +76 -0
  373. agentguard_linter-0.1.0/tests/test_graph_acceptance.py +296 -0
  374. agentguard_linter-0.1.0/tests/test_graph_plugin.py +80 -0
  375. agentguard_linter-0.1.0/tests/test_interprocedural_taint.py +64 -0
  376. agentguard_linter-0.1.0/tests/test_ir_models.py +116 -0
  377. agentguard_linter-0.1.0/tests/test_langgraph_adapter.py +98 -0
  378. agentguard_linter-0.1.0/tests/test_llm_triage.py +311 -0
  379. agentguard_linter-0.1.0/tests/test_packaging.py +62 -0
  380. agentguard_linter-0.1.0/tests/test_phase3_fixtures.py +50 -0
  381. agentguard_linter-0.1.0/tests/test_phase3_rules.py +105 -0
  382. agentguard_linter-0.1.0/tests/test_phase5_metadata.py +53 -0
  383. agentguard_linter-0.1.0/tests/test_phase5_plugins.py +46 -0
  384. agentguard_linter-0.1.0/tests/test_plugin_boundary.py +40 -0
  385. agentguard_linter-0.1.0/tests/test_plugins.py +197 -0
  386. agentguard_linter-0.1.0/tests/test_reporters.py +136 -0
  387. agentguard_linter-0.1.0/tests/test_rules.py +104 -0
  388. agentguard_linter-0.1.0/tests/test_rules_fixtures.py +70 -0
  389. agentguard_linter-0.1.0/tests/test_taint.py +45 -0
  390. agentguard_linter-0.1.0/tests/test_taint_arguments.py +193 -0
  391. agentguard_linter-0.1.0/tests/test_trace_plugin.py +385 -0
  392. agentguard_linter-0.1.0/uv.lock +2239 -0
  393. agentguard_linter-0.1.0/web/README.md +59 -0
  394. agentguard_linter-0.1.0/web/app/error.tsx +33 -0
  395. agentguard_linter-0.1.0/web/app/globals.css +795 -0
  396. agentguard_linter-0.1.0/web/app/layout.tsx +19 -0
  397. agentguard_linter-0.1.0/web/app/loading.tsx +14 -0
  398. agentguard_linter-0.1.0/web/app/page.tsx +47 -0
  399. agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/loading.tsx +14 -0
  400. agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/page.tsx +190 -0
  401. agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/scans/[scanId]/loading.tsx +14 -0
  402. agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/scans/[scanId]/page.tsx +82 -0
  403. agentguard_linter-0.1.0/web/components/api-state.tsx +44 -0
  404. agentguard_linter-0.1.0/web/components/app-shell.tsx +46 -0
  405. agentguard_linter-0.1.0/web/components/finding-list.tsx +39 -0
  406. agentguard_linter-0.1.0/web/components/metric-card.tsx +16 -0
  407. agentguard_linter-0.1.0/web/components/repository-card.tsx +40 -0
  408. agentguard_linter-0.1.0/web/components/risk-trend.tsx +39 -0
  409. agentguard_linter-0.1.0/web/components/scan-table.tsx +49 -0
  410. agentguard_linter-0.1.0/web/components/state-panel.tsx +41 -0
  411. agentguard_linter-0.1.0/web/components/status-badge.tsx +11 -0
  412. agentguard_linter-0.1.0/web/lib/api.ts +413 -0
  413. agentguard_linter-0.1.0/web/next-env.d.ts +5 -0
  414. agentguard_linter-0.1.0/web/next.config.mjs +17 -0
  415. agentguard_linter-0.1.0/web/package-lock.json +451 -0
  416. agentguard_linter-0.1.0/web/package.json +26 -0
  417. agentguard_linter-0.1.0/web/tsconfig.json +23 -0
  418. agentguard_linter-0.1.0/web/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,15 @@
1
+ .git
2
+ .github
3
+ .venv
4
+ .venvs
5
+ __pycache__
6
+ *.py[cod]
7
+ .mypy_cache
8
+ .pytest_cache
9
+ .ruff_cache
10
+ build
11
+ dist
12
+ web/node_modules
13
+ web/.next
14
+ web/tsconfig.tsbuildinfo
15
+ *.log
@@ -0,0 +1,6 @@
1
+ # Local server settings. Keep real credentials in your shell or secret manager.
2
+ AGENTGUARD_DATABASE_URL=postgresql+psycopg://agentguard:agentguard@localhost:5432/agentguard
3
+ AGENTGUARD_CORS_ORIGINS=http://localhost:3000
4
+ # AGENTGUARD_AUTH_REQUIRED=true
5
+ # AGENTGUARD_API_TOKENS=replace-me=local;read|write;acme/demo
6
+ # AGENTGUARD_GITHUB_WEBHOOK_SECRET=replace-me
@@ -0,0 +1 @@
1
+ * text=auto eol=lf
@@ -0,0 +1,53 @@
1
+ name: AgentGuard scan
2
+ description: Run AgentGuard and produce a SARIF report.
3
+ inputs:
4
+ path:
5
+ description: File or directory to scan.
6
+ required: false
7
+ default: "."
8
+ output:
9
+ description: SARIF output path.
10
+ required: false
11
+ default: "agentguard.sarif"
12
+ select:
13
+ description: Comma-separated rule selection patterns.
14
+ required: false
15
+ default: ""
16
+ ignore:
17
+ description: Comma-separated rule ignore patterns.
18
+ required: false
19
+ default: ""
20
+ fail-on:
21
+ description: Finding threshold that fails the step.
22
+ required: false
23
+ default: "error"
24
+ python-version:
25
+ description: Python version used by uv.
26
+ required: false
27
+ default: "3.13"
28
+ runs:
29
+ using: composite
30
+ steps:
31
+ - name: Set up Python
32
+ uses: actions/setup-python@v5
33
+ with:
34
+ python-version: ${{ inputs.python-version }}
35
+ - name: Set up uv
36
+ uses: astral-sh/setup-uv@v6
37
+ with:
38
+ version: "0.13.0"
39
+ enable-cache: true
40
+ - name: Run AgentGuard
41
+ shell: bash
42
+ env:
43
+ AG_PATH: ${{ inputs.path }}
44
+ AG_OUTPUT: ${{ inputs.output }}
45
+ AG_SELECT: ${{ inputs.select }}
46
+ AG_IGNORE: ${{ inputs.ignore }}
47
+ AG_FAIL_ON: ${{ inputs.fail-on }}
48
+ run: |
49
+ set -euo pipefail
50
+ args=("$AG_PATH" --format sarif --output "$AG_OUTPUT" --fail-on "$AG_FAIL_ON")
51
+ if [[ -n "$AG_SELECT" ]]; then args+=(--select "$AG_SELECT"); fi
52
+ if [[ -n "$AG_IGNORE" ]]; then args+=(--ignore "$AG_IGNORE"); fi
53
+ uvx --python "${{ inputs.python-version }}" --from agentguard agentguard scan "${args[@]}"
@@ -0,0 +1,82 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ check:
12
+ name: Python ${{ matrix.python-version }}
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
18
+ services:
19
+ postgres:
20
+ image: postgres:16
21
+ env:
22
+ POSTGRES_USER: agentguard
23
+ POSTGRES_PASSWORD: agentguard
24
+ POSTGRES_DB: agentguard_test
25
+ ports:
26
+ - 5432:5432
27
+ options: >-
28
+ --health-cmd "pg_isready -U agentguard -d agentguard_test"
29
+ --health-interval 10s
30
+ --health-timeout 5s
31
+ --health-retries 5
32
+ env:
33
+ UV_LINK_MODE: copy
34
+ UV_PYTHON: ${{ matrix.python-version }}
35
+ AGENTGUARD_TEST_DATABASE_URL: postgresql://agentguard:agentguard@localhost:5432/agentguard_test
36
+
37
+ steps:
38
+ - name: Check out repository
39
+ uses: actions/checkout@v4
40
+
41
+ - name: Set up Python
42
+ uses: actions/setup-python@v5
43
+ with:
44
+ python-version: ${{ matrix.python-version }}
45
+
46
+ - name: Set up uv
47
+ uses: astral-sh/setup-uv@v6
48
+ with:
49
+ version: "0.13.0"
50
+ enable-cache: true
51
+
52
+ - name: Install dependencies
53
+ run: make install
54
+
55
+ - name: Run checks
56
+ run: make check
57
+
58
+ web:
59
+ name: Dashboard TypeScript
60
+ runs-on: ubuntu-latest
61
+ defaults:
62
+ run:
63
+ working-directory: web
64
+ steps:
65
+ - name: Check out repository
66
+ uses: actions/checkout@v4
67
+
68
+ - name: Set up Node
69
+ uses: actions/setup-node@v4
70
+ with:
71
+ node-version-file: .nvmrc
72
+ cache: npm
73
+ cache-dependency-path: web/package-lock.json
74
+
75
+ - name: Install dashboard dependencies
76
+ run: npm ci
77
+
78
+ - name: Check dashboard types
79
+ run: npm test
80
+
81
+ - name: Build dashboard
82
+ run: npm run build
@@ -0,0 +1,30 @@
1
+ # Python caches and virtual environments
2
+ __pycache__/
3
+ *.py[cod]
4
+ .mypy_cache/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ .venv/
8
+ .venvs/
9
+ web/node_modules/
10
+ web/.next/
11
+
12
+ # Build and coverage outputs
13
+ *.egg-info/
14
+ .coverage
15
+ .coverage.*
16
+ build/
17
+ coverage.xml
18
+ dist/
19
+ htmlcov/
20
+
21
+ # Local configuration and secrets
22
+ .env
23
+ .env.*
24
+ !.env.example
25
+
26
+ # Editors and operating systems
27
+ .DS_Store
28
+ .idea/
29
+ .vscode/
30
+ *.swp
@@ -0,0 +1 @@
1
+ 20.17.0
@@ -0,0 +1,7 @@
1
+ - id: agentguard
2
+ name: AgentGuard
3
+ description: Scan staged Python files for agent reliability and security findings.
4
+ entry: agentguard scan --fail-on error
5
+ language: python
6
+ types: [python]
7
+ pass_filenames: true
@@ -0,0 +1,128 @@
1
+ # AGENTS.md
2
+
3
+ Instructions for AI coding agents working on **AgentGuard**.
4
+ Read this file and `SPEC.md` at the start of every session. `SPEC.md` is the source of truth for architecture, rules, and phases. This file is the source of truth for how you work.
5
+
6
+ ## Project
7
+
8
+ AgentGuard is a static analysis CLI and plugin platform for AI agentic codebases (LangGraph, CrewAI, AutoGen, plain Python agents). It detects reliability, cost, and security bugs before the agent runs.
9
+
10
+ - Language: Python 3.10+
11
+ - Owner: Samarth (solo developer, student). Treat the owner as technically capable; be direct and concise.
12
+ - **The repo starts empty.** No code exists yet. Build from Phase 0 of `SPEC.md`.
13
+ - Current phase: **check `STATUS.md`**. If it does not exist, create it and start at Phase 0, Step 0.1.
14
+
15
+ ## Environment (WSL)
16
+
17
+ This project runs in WSL Ubuntu, possibly under `/mnt/d/...` (a Windows drive). Quirks to handle:
18
+
19
+ - Set `UV_LINK_MODE=copy` (hardlinks fail across filesystems). Put it in the Makefile and `README` setup notes.
20
+ - Keep the virtualenv off the Windows drive for speed: use `UV_PROJECT_ENVIRONMENT="$HOME/.venvs/agentguard"`. Document this in the README and export it in the Makefile.
21
+ - Use LF line endings. Add a `.gitattributes` with `* text=auto eol=lf`.
22
+ - Do not use Windows paths in code or docs. Use `pathlib` and POSIX paths.
23
+ - If a tool is missing (`make`, `uv`, `git`), tell the owner the install command instead of working around it.
24
+
25
+ ## Workflow (mandatory)
26
+
27
+ 1. **Plan first, then wait.** For any task beyond a trivial fix, write a plan and stop. The plan lists: files to create or change, approach, tests to add, risks. Do **not** edit files until the owner replies with approval.
28
+ 2. **One unit per task.** A unit is one rule, one adapter, one CLI command, or one refactor step. Do not bundle units.
29
+ 3. **Build, verify, stop.** After implementing, run `make check` (below). Fix failures. Then stop and give a summary: what changed, what was tested, what remains, anything you are unsure about.
30
+ 4. **Update `STATUS.md`** at the end of every unit: phase, what is done, what is next, known issues.
31
+ 5. **Never expand scope.** Touch only files relevant to the task. If you notice unrelated problems, list them in the summary; do not fix them.
32
+
33
+ ## Commands
34
+
35
+ Use `uv` for environments and dependencies.
36
+
37
+ ```
38
+ uv sync --all-extras # install everything
39
+ make check # lint + typecheck + tests (run before declaring done)
40
+ make test # pytest only
41
+ make lint # ruff check + ruff format --check
42
+ make fmt # ruff format + ruff check --fix
43
+ make types # mypy --strict
44
+ ```
45
+
46
+ `make check` must pass with zero errors and zero warnings before any unit is considered done. If a command above does not exist yet, creating it is the first task of Phase 2.
47
+
48
+ ## Tooling (decided)
49
+
50
+ | Purpose | Tool |
51
+ |---|---|
52
+ | Env / deps | `uv` |
53
+ | Build backend | `hatchling` |
54
+ | Tests | `pytest`, `hypothesis`, snapshot tests for reporters |
55
+ | Lint + format | `ruff` |
56
+ | Types | `mypy --strict` |
57
+ | CLI | `typer` + `rich` |
58
+ | Plugins | `pluggy` + entry points (group `agentguard`) |
59
+ | Config models | `pydantic` v2 |
60
+ | Autofix | `libcst` |
61
+
62
+ Do not add dependencies without asking. If a new dependency is justified, put it in the plan with the reason.
63
+
64
+ ## Code standards
65
+
66
+ - Fully typed. No `Any` unless justified in a comment.
67
+ - Small functions, clear names, docstrings on public APIs.
68
+ - Findings are deterministic: same input gives same output, sorted, stable fingerprints.
69
+ - No network calls in core. LLM-related features live in optional plugins, off by default.
70
+ - No print statements in library code; use `rich` in CLI layer only.
71
+ - No broad `except Exception: pass`. Handle or re-raise with context.
72
+ - Prefer the standard library for simple tasks.
73
+
74
+ ## Architecture rules
75
+
76
+ - Rules operate on the **Agent IR**, never on raw framework syntax. Framework-specific logic belongs in adapters.
77
+ - Rules are plugins implementing the `Rule` base class. Core ships built-in rules through the same mechanism third parties use.
78
+ - Adapters translate framework code into IR. They never emit findings.
79
+ - Reporters consume findings only. They never re-analyze code.
80
+ - Do not let the engine import from adapters or rules directly; go through the plugin manager.
81
+
82
+ ## Testing rules
83
+
84
+ - Every rule needs fixtures under `tests/fixtures/<rule_id>/`: `bad_*.py` (must trigger), `good_*.py` (must not), and at least one edge case. Mark expected findings with `# expect: AGxxx` on the exact line.
85
+ - Every new reporter needs a snapshot test.
86
+ - Every IR builder change needs a unit test.
87
+ - **Never modify an existing test to make it pass.** If a test fails, fix the code. If you believe a test is wrong, say so in your summary and wait for approval.
88
+ - Never delete or skip tests to get green. Never use `# type: ignore` or `# noqa` without a one-line reason.
89
+
90
+ ## Rule documentation
91
+
92
+ Each rule needs `docs/rules/<ID>.md` containing: what it detects, why it matters, bad example, good example, how to fix, how to suppress. `agentguard explain <ID>` reads this file.
93
+
94
+ ## Git
95
+
96
+ - Work on a feature branch, never directly on `main`.
97
+ - Commit after each green unit with a conventional message (`feat(rules): add AG004 unbounded agent loop`).
98
+ - Do not commit generated files, caches, or secrets.
99
+ - Never force-push, rewrite history, or run destructive git commands without explicit approval.
100
+
101
+ ## Safety
102
+
103
+ - Do not run `rm -rf`, delete directories, or modify files outside this repository without approval.
104
+ - Never print or commit secrets. Read credentials from environment variables only.
105
+ - Do not install global packages or modify system configuration.
106
+ - When fixture code needs to look dangerous (shell calls, eval), keep it inert: it is parsed, never executed.
107
+
108
+ ## Verifying framework APIs
109
+
110
+ LangGraph, CrewAI, and AutoGen change fast. Do not rely on memory for their APIs. Check the installed version's source or current docs before writing an adapter, and pin the tested version in the plan. If you cannot verify something, say so rather than guessing.
111
+
112
+ ## Summary format (end of every unit)
113
+
114
+ ```
115
+ Done: <what was implemented>
116
+ Tested: <commands run and results>
117
+ Changed: <files>
118
+ Not done / next: <remaining work>
119
+ Concerns: <uncertainties, risks, things to review closely>
120
+ ```
121
+
122
+ ## What not to do
123
+
124
+ - Do not start a new phase without approval.
125
+ - Do not refactor code that is unrelated to the current task.
126
+ - Do not add features not in `SPEC.md`; suggest them in the summary instead.
127
+ - Do not report "done" with failing checks.
128
+ - Do not guess when requirements are ambiguous. Ask one specific question.
@@ -0,0 +1,22 @@
1
+ FROM python:3.11-slim
2
+
3
+ ENV PYTHONDONTWRITEBYTECODE=1 \
4
+ PYTHONUNBUFFERED=1 \
5
+ UV_LINK_MODE=copy \
6
+ UV_PROJECT_ENVIRONMENT=/opt/agentguard/.venv
7
+
8
+ WORKDIR /opt/agentguard
9
+
10
+ COPY pyproject.toml uv.lock README.md LICENSE ./
11
+ COPY packages ./packages
12
+ COPY docs ./docs
13
+ COPY benchmarks ./benchmarks
14
+ COPY tests ./tests
15
+ COPY Makefile ./Makefile
16
+
17
+ RUN pip install --no-cache-dir uv==0.13.0 \
18
+ && uv sync --locked --all-extras --all-packages --no-dev
19
+
20
+ EXPOSE 8000
21
+
22
+ CMD ["uv", "run", "--locked", "--package", "agentguard-server", "uvicorn", "agentguard_server.main:app", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Samarth
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,28 @@
1
+ .PHONY: install check test server-test lint fmt types
2
+
3
+ UV_LINK_MODE := copy
4
+ UV_PROJECT_ENVIRONMENT ?= $(HOME)/.venvs/agentguard
5
+ export UV_LINK_MODE
6
+ export UV_PROJECT_ENVIRONMENT
7
+
8
+ install:
9
+ uv sync --locked --all-extras --all-packages
10
+
11
+ check: lint types test server-test
12
+
13
+ test:
14
+ uv run --locked --all-extras pytest
15
+
16
+ server-test:
17
+ uv run --locked --all-extras --package agentguard-server pytest packages/agentguard-server/tests
18
+
19
+ lint:
20
+ uv run --locked --all-extras ruff check .
21
+ uv run --locked --all-extras ruff format --check .
22
+
23
+ fmt:
24
+ uv run --locked --all-extras ruff check --fix .
25
+ uv run --locked --all-extras ruff format .
26
+
27
+ types:
28
+ uv run --locked --all-extras mypy --strict packages/agentguard-core/src packages/agentguard-langgraph/src packages/agentguard-graph/src packages/agentguard-owasp/src packages/agentguard-llm-triage/src packages/agentguard-trace/src packages/agentguard-server/src tests