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.
- agentguard_linter-0.1.0/.dockerignore +15 -0
- agentguard_linter-0.1.0/.env.example +6 -0
- agentguard_linter-0.1.0/.gitattributes +1 -0
- agentguard_linter-0.1.0/.github/actions/agentguard/action.yml +53 -0
- agentguard_linter-0.1.0/.github/workflows/ci.yml +82 -0
- agentguard_linter-0.1.0/.gitignore +30 -0
- agentguard_linter-0.1.0/.nvmrc +1 -0
- agentguard_linter-0.1.0/.pre-commit-hooks.yaml +7 -0
- agentguard_linter-0.1.0/AGENTS.md +128 -0
- agentguard_linter-0.1.0/Dockerfile +22 -0
- agentguard_linter-0.1.0/LICENSE +21 -0
- agentguard_linter-0.1.0/Makefile +28 -0
- agentguard_linter-0.1.0/PKG-INFO +403 -0
- agentguard_linter-0.1.0/README.md +361 -0
- agentguard_linter-0.1.0/SPEC.md +469 -0
- agentguard_linter-0.1.0/STATUS.md +661 -0
- agentguard_linter-0.1.0/benchmarks/__init__.py +1 -0
- agentguard_linter-0.1.0/benchmarks/corpus_gate.py +76 -0
- agentguard_linter-0.1.0/benchmarks/scan_10k.py +161 -0
- agentguard_linter-0.1.0/docker-compose.yml +38 -0
- agentguard_linter-0.1.0/docs/ROADMAP_AND_ISSUES.md +560 -0
- agentguard_linter-0.1.0/docs/architecture.md +79 -0
- agentguard_linter-0.1.0/docs/autofix.md +44 -0
- agentguard_linter-0.1.0/docs/benchmarks.md +94 -0
- agentguard_linter-0.1.0/docs/ci.md +79 -0
- agentguard_linter-0.1.0/docs/distribution.md +61 -0
- agentguard_linter-0.1.0/docs/rules/AG001.md +70 -0
- agentguard_linter-0.1.0/docs/rules/AG002.md +81 -0
- agentguard_linter-0.1.0/docs/rules/AG003.md +65 -0
- agentguard_linter-0.1.0/docs/rules/AG004.md +35 -0
- agentguard_linter-0.1.0/docs/rules/AG005.md +33 -0
- agentguard_linter-0.1.0/docs/rules/AG006.md +31 -0
- agentguard_linter-0.1.0/docs/rules/AG007.md +32 -0
- agentguard_linter-0.1.0/docs/rules/AG008.md +37 -0
- agentguard_linter-0.1.0/docs/rules/AG009.md +32 -0
- agentguard_linter-0.1.0/docs/rules/AG010.md +32 -0
- agentguard_linter-0.1.0/docs/rules/AG011.md +33 -0
- agentguard_linter-0.1.0/docs/rules/AG020.md +33 -0
- agentguard_linter-0.1.0/docs/rules/AG021.md +31 -0
- agentguard_linter-0.1.0/docs/rules/AG022.md +33 -0
- agentguard_linter-0.1.0/docs/rules/AG023.md +31 -0
- agentguard_linter-0.1.0/docs/server.md +105 -0
- agentguard_linter-0.1.0/examples/clean_agent/clean_agent.py +22 -0
- agentguard_linter-0.1.0/examples/langgraph_support_bot/support_bot.py +47 -0
- agentguard_linter-0.1.0/examples/plain_python_agent/plain_agent.py +28 -0
- agentguard_linter-0.1.0/packages/agentguard-core/README.md +7 -0
- agentguard_linter-0.1.0/packages/agentguard-core/pyproject.toml +19 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/__init__.py +3 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/__main__.py +6 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/__init__.py +13 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/autogen.py +60 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/base.py +24 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/crewai.py +60 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/adapters/generic.py +735 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/baseline.py +63 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/__init__.py +48 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/baseline.py +32 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/plugins.py +162 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/rules.py +45 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/cli/scan.py +360 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/config.py +134 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/__init__.py +1 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/discovery.py +165 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/fingerprint.py +20 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/parser.py +81 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/runner.py +99 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/engine/suppression.py +97 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/findings.py +83 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/__init__.py +15 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/ag003_timeout.py +68 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/ag004_recursion_limit.py +104 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/ag010_model_pin.py +73 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/fixes/engine.py +66 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/__init__.py +41 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/builder.py +38 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/calls.py +75 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/models.py +232 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/taint.py +208 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/ir/taint_interprocedural.py +792 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/__init__.py +6 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/builtin.py +69 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/manager.py +183 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/plugins/spec.py +47 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/__init__.py +8 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/base.py +17 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/json_reporter.py +54 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/sarif.py +111 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/reporters/text.py +34 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/__init__.py +12 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag001_unbounded_retries.py +72 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag002_shared_mutable_fanout.py +122 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag003_missing_timeout.py +54 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag004_unbounded_agent_loop.py +30 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag005_no_cost_budget.py +34 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag006_unreachable_graph_node.py +30 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag007_conditional_edge_unmapped_key.py +34 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag008_exception_swallowed_in_tool.py +40 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag009_non_idempotent_tool_with_retry.py +36 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag010_unpinned_model_alias.py +34 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag011_unbounded_state_growth.py +27 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag020_prompt_injection_sink.py +35 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag021_dangerous_tool_no_approval.py +34 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag022_llm_output_to_sink.py +39 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/ag023_hardcoded_secret.py +30 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/base.py +100 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/builtins.py +9 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/phase3_common.py +50 -0
- agentguard_linter-0.1.0/packages/agentguard-core/src/agentguard/rules/registry.py +95 -0
- agentguard_linter-0.1.0/packages/agentguard-graph/README.md +27 -0
- agentguard_linter-0.1.0/packages/agentguard-graph/pyproject.toml +15 -0
- agentguard_linter-0.1.0/packages/agentguard-graph/src/agentguard_graph/__init__.py +314 -0
- agentguard_linter-0.1.0/packages/agentguard-langgraph/README.md +4 -0
- agentguard_linter-0.1.0/packages/agentguard-langgraph/pyproject.toml +16 -0
- agentguard_linter-0.1.0/packages/agentguard-langgraph/src/agentguard_langgraph/__init__.py +14 -0
- agentguard_linter-0.1.0/packages/agentguard-langgraph/src/agentguard_langgraph/adapter.py +475 -0
- agentguard_linter-0.1.0/packages/agentguard-llm-triage/README.md +73 -0
- agentguard_linter-0.1.0/packages/agentguard-llm-triage/pyproject.toml +15 -0
- agentguard_linter-0.1.0/packages/agentguard-llm-triage/src/agentguard_llm_triage/__init__.py +638 -0
- agentguard_linter-0.1.0/packages/agentguard-owasp/README.md +22 -0
- agentguard_linter-0.1.0/packages/agentguard-owasp/pyproject.toml +15 -0
- agentguard_linter-0.1.0/packages/agentguard-owasp/src/agentguard_owasp/__init__.py +52 -0
- agentguard_linter-0.1.0/packages/agentguard-server/README.md +69 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic/env.py +56 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic/script.py.mako +24 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0001_initial.py +170 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0002_webhook_deliveries.py +33 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0003_badge_visibility.py +25 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic/versions/0004_audit_records.py +35 -0
- agentguard_linter-0.1.0/packages/agentguard-server/alembic.ini +38 -0
- agentguard_linter-0.1.0/packages/agentguard-server/pyproject.toml +35 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/__init__.py +7 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/api.py +634 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/app.py +138 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/audit.py +108 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/badges.py +326 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/config.py +103 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/db.py +33 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/github.py +307 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/main.py +21 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/models.py +295 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/platform_api.py +194 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/retention.py +48 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/schemas.py +216 -0
- agentguard_linter-0.1.0/packages/agentguard-server/src/agentguard_server/security.py +197 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_api.py +197 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_audit.py +33 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_badges.py +163 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_config.py +34 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_github.py +168 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_http_platform.py +193 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_models.py +36 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_postgres.py +54 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_retention.py +45 -0
- agentguard_linter-0.1.0/packages/agentguard-server/tests/test_security.py +51 -0
- agentguard_linter-0.1.0/packages/agentguard-trace/README.md +44 -0
- agentguard_linter-0.1.0/packages/agentguard-trace/pyproject.toml +15 -0
- agentguard_linter-0.1.0/packages/agentguard-trace/src/agentguard_trace/__init__.py +807 -0
- agentguard_linter-0.1.0/pyproject.toml +107 -0
- agentguard_linter-0.1.0/tests/__init__.py +1 -0
- agentguard_linter-0.1.0/tests/fixture_support.py +57 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/bad_backoff.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/bad_max_retries.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/bad_recursion.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/bad_tenacity.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/bad_while.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/edge_dynamic_max.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/edge_unknown_bound.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/edge_wait_only.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/good_backoff.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/good_bounded_for.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/good_deadline.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/good_event_loop.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag001/good_tenacity.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/bad_asyncio.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/bad_langgraph_send.py +20 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/bad_langgraph_static.py +23 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/bad_mutable_default.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/bad_thread_pool.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/edge_dynamic_fanout.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/edge_single_writer.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/edge_state_reducer_custom.py +27 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/good_default_none.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/good_langgraph_reducer.py +24 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/good_local.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/good_lock.py +14 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/good_read_only.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag002/good_sequential.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/bad_httpx_none.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/bad_langchain.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/bad_loop.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/bad_openai.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/bad_requests.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/edge_aiohttp.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/edge_alias.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/edge_dynamic_timeout.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/good_httpx_default.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/good_kwargs.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/good_openai.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/good_requests.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag003/good_subprocess.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/bad_cycle.py +18 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/bad_five.py +17 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/bad_four.py +17 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/bad_three.py +17 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/bad_two.py +17 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/edge_no_cycle.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/edge_three.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/edge_two.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/good_five.py +18 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/good_four.py +18 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/good_limit.py +19 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/good_three.py +18 -0
- agentguard_linter-0.1.0/tests/fixtures/ag004/good_two.py +18 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/bad_five.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/bad_four.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/bad_loop_budget.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/bad_three.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/bad_two.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/edge_dynamic_budget.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/edge_three.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/edge_two.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/good_five.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/good_four.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/good_loop_budget.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/good_three.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag005/good_two.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/bad_five.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/bad_four.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/bad_orphan.py +16 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/bad_three.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/bad_two.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/edge_missing_entry.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/edge_three.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/edge_two.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/good_connected.py +17 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/good_five.py +16 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/good_four.py +16 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/good_three.py +16 -0
- agentguard_linter-0.1.0/tests/fixtures/ag006/good_two.py +16 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/bad_five.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/bad_four.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/bad_route.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/bad_three.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/bad_two.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/edge_terminal_route.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/edge_three.py +14 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/edge_two.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/good_five.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/good_four.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/good_route.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/good_three.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag007/good_two.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/bad_five.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/bad_four.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/bad_three.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/bad_tool_exception.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/bad_two.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/edge_fallback.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/edge_three.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/edge_two.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/good_five.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/good_four.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/good_three.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/good_tool_exception.py +19 -0
- agentguard_linter-0.1.0/tests/fixtures/ag008/good_two.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/bad_five.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/bad_four.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/bad_retry_tool.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/bad_three.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/bad_two.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/edge_bounded.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/edge_three.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/edge_two.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/good_five.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/good_four.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/good_no_retry.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/good_three.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag009/good_two.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/bad_alias.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/bad_five.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/bad_four.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/bad_three.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/bad_two.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/edge_dynamic.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/edge_three.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/edge_two.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/good_five.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/good_four.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/good_pinned.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/good_three.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag010/good_two.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/bad_five.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/bad_four.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/bad_growth.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/bad_three.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/bad_two.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/edge_other_collection.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/edge_three.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/edge_two.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/good_bounded.py +2 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/good_five.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/good_four.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/good_three.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag011/good_two.py +2 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/bad_five.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/bad_four.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/bad_system_prompt.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/bad_three.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/bad_two.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/edge_literal_prompt.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/edge_three.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/edge_two.py +10 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/good_five.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/good_four.py +6 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/good_three.py +11 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/good_two.py +12 -0
- agentguard_linter-0.1.0/tests/fixtures/ag020/good_user_message.py +12 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/bad_delete_tool.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/bad_five.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/bad_four.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/bad_three.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/bad_two.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/edge_three.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/edge_two.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/edge_unknown_tool.py +8 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/good_approval.py +14 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/good_five.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/good_four.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/good_three.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag021/good_two.py +13 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/bad_exec_output.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/bad_five.py +12 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/bad_four.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/bad_three.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/bad_two.py +7 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/edge_literal_command.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/edge_three.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/edge_two.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/good_five.py +14 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/good_four.py +9 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/good_three.py +4 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/good_two.py +14 -0
- agentguard_linter-0.1.0/tests/fixtures/ag022/good_typed_dispatch.py +15 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/bad_five.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/bad_four.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/bad_secret.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/bad_three.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/bad_two.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/edge_test_name.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/edge_three.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/edge_two.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/good_environment.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/good_five.py +1 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/good_four.py +5 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/good_three.py +3 -0
- agentguard_linter-0.1.0/tests/fixtures/ag023/good_two.py +3 -0
- agentguard_linter-0.1.0/tests/test_ag001.py +25 -0
- agentguard_linter-0.1.0/tests/test_ag002.py +27 -0
- agentguard_linter-0.1.0/tests/test_ag003.py +38 -0
- agentguard_linter-0.1.0/tests/test_baseline.py +52 -0
- agentguard_linter-0.1.0/tests/test_benchmarks.py +41 -0
- agentguard_linter-0.1.0/tests/test_bootstrap.py +15 -0
- agentguard_linter-0.1.0/tests/test_ci_assets.py +51 -0
- agentguard_linter-0.1.0/tests/test_cli.py +273 -0
- agentguard_linter-0.1.0/tests/test_cli_plugins.py +59 -0
- agentguard_linter-0.1.0/tests/test_config.py +111 -0
- agentguard_linter-0.1.0/tests/test_engine.py +96 -0
- agentguard_linter-0.1.0/tests/test_engine_edges.py +150 -0
- agentguard_linter-0.1.0/tests/test_findings.py +74 -0
- agentguard_linter-0.1.0/tests/test_fixes.py +154 -0
- agentguard_linter-0.1.0/tests/test_framework_adapters.py +37 -0
- agentguard_linter-0.1.0/tests/test_generic_adapter.py +76 -0
- agentguard_linter-0.1.0/tests/test_graph_acceptance.py +296 -0
- agentguard_linter-0.1.0/tests/test_graph_plugin.py +80 -0
- agentguard_linter-0.1.0/tests/test_interprocedural_taint.py +64 -0
- agentguard_linter-0.1.0/tests/test_ir_models.py +116 -0
- agentguard_linter-0.1.0/tests/test_langgraph_adapter.py +98 -0
- agentguard_linter-0.1.0/tests/test_llm_triage.py +311 -0
- agentguard_linter-0.1.0/tests/test_packaging.py +62 -0
- agentguard_linter-0.1.0/tests/test_phase3_fixtures.py +50 -0
- agentguard_linter-0.1.0/tests/test_phase3_rules.py +105 -0
- agentguard_linter-0.1.0/tests/test_phase5_metadata.py +53 -0
- agentguard_linter-0.1.0/tests/test_phase5_plugins.py +46 -0
- agentguard_linter-0.1.0/tests/test_plugin_boundary.py +40 -0
- agentguard_linter-0.1.0/tests/test_plugins.py +197 -0
- agentguard_linter-0.1.0/tests/test_reporters.py +136 -0
- agentguard_linter-0.1.0/tests/test_rules.py +104 -0
- agentguard_linter-0.1.0/tests/test_rules_fixtures.py +70 -0
- agentguard_linter-0.1.0/tests/test_taint.py +45 -0
- agentguard_linter-0.1.0/tests/test_taint_arguments.py +193 -0
- agentguard_linter-0.1.0/tests/test_trace_plugin.py +385 -0
- agentguard_linter-0.1.0/uv.lock +2239 -0
- agentguard_linter-0.1.0/web/README.md +59 -0
- agentguard_linter-0.1.0/web/app/error.tsx +33 -0
- agentguard_linter-0.1.0/web/app/globals.css +795 -0
- agentguard_linter-0.1.0/web/app/layout.tsx +19 -0
- agentguard_linter-0.1.0/web/app/loading.tsx +14 -0
- agentguard_linter-0.1.0/web/app/page.tsx +47 -0
- agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/loading.tsx +14 -0
- agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/page.tsx +190 -0
- agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/scans/[scanId]/loading.tsx +14 -0
- agentguard_linter-0.1.0/web/app/repositories/[repositoryId]/scans/[scanId]/page.tsx +82 -0
- agentguard_linter-0.1.0/web/components/api-state.tsx +44 -0
- agentguard_linter-0.1.0/web/components/app-shell.tsx +46 -0
- agentguard_linter-0.1.0/web/components/finding-list.tsx +39 -0
- agentguard_linter-0.1.0/web/components/metric-card.tsx +16 -0
- agentguard_linter-0.1.0/web/components/repository-card.tsx +40 -0
- agentguard_linter-0.1.0/web/components/risk-trend.tsx +39 -0
- agentguard_linter-0.1.0/web/components/scan-table.tsx +49 -0
- agentguard_linter-0.1.0/web/components/state-panel.tsx +41 -0
- agentguard_linter-0.1.0/web/components/status-badge.tsx +11 -0
- agentguard_linter-0.1.0/web/lib/api.ts +413 -0
- agentguard_linter-0.1.0/web/next-env.d.ts +5 -0
- agentguard_linter-0.1.0/web/next.config.mjs +17 -0
- agentguard_linter-0.1.0/web/package-lock.json +451 -0
- agentguard_linter-0.1.0/web/package.json +26 -0
- agentguard_linter-0.1.0/web/tsconfig.json +23 -0
- agentguard_linter-0.1.0/web/tsconfig.tsbuildinfo +1 -0
|
@@ -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,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
|