qaas-python 0.2.0__tar.gz → 0.2.1__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.
- {qaas_python-0.2.0 → qaas_python-0.2.1}/PKG-INFO +1 -1
- {qaas_python-0.2.0 → qaas_python-0.2.1}/pyproject.toml +1 -1
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/cli.py +6 -8
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/conductor.py +22 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/target.py +18 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_conductor.py +20 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/.gitignore +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/ARCHITECTURE.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/BUILD_PLAN.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/CLAUDE.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/LICENSE +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/README.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/config/targets/corvid.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/adapters/__init__.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/adapters/tracker.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/adapters/vcs.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/config.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/arbiter.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/cartographer.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/clerk.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/conduit.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/forge.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/mender.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/proof.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/surface.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/vault.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/agents/warden.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/defaults/config/system.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/discover.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/envelope.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/guardrails.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/__init__.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/context.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/contract_diff.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/defect_memory.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/env_control.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/envelope_server.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/test_runner.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/tracker.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/mcp/vcs.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/paths.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/.claude-plugin/plugin.json +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/a11y-audit/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/adversarial-review/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/api-surface-extraction/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/authz-matrix-check/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/console-error-triage/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/contract-test-generation/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/dedupe-strategy/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/environment-pinning/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/error-taxonomy/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/exploratory-ui-walk/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/failing-test-authoring/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/flake-detection/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/form-state-probe/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/minimal-diff-discipline/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/openapi-diff/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/ownership-resolution/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/product-task-graph/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/regression-risk-scoring/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/regression-suite-selection/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/repo-cartography/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/repro-minimisation/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/rollback-plan-authoring/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/root-cause-vs-symptom/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/routing-rules/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/severity-rubric/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/test-first-fix/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/test-quality-audit/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/ticket-writer/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/verdict-reporting/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/verification-protocol/SKILL.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/ARBITER.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/CARTOGRAPHER.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/CLERK.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/CONDUIT.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/FORGE.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/MENDER.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/PROOF.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/SURFACE.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/VAULT.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/WARDEN.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/prompts/_shared.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/registry.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/runner.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/scorecard.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/sdk_compat.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/store.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/tasks.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/trace.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/CODEOWNERS +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/Dockerfile +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/__init__.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/auth.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/config.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/db.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/errors.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/main.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/models.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/routes/__init__.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/routes/auth.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/routes/invoices.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/routes/orders.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/routes/stream.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/app/schemas.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/migrations/001_init.sql +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/pyproject.toml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/api/seed/fixtures.sql +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/defects.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/docker-compose.yml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/openapi.yaml +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/.gitignore +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/Dockerfile +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/index.html +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/package-lock.json +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/package.json +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/api.ts +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/components/Button.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/components/Layout.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/components/SearchInput.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/main.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/routes/CheckoutReview.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/routes/Login.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/routes/NewOrder.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/routes/OrderDetail.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/routes/OrdersList.tsx +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/src/styles.css +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/tsconfig.json +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/target-app/web/vite.config.ts +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/adapters/test_github_vcs.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/adapters/test_jira_tracker.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/conftest.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/conftest.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/test_contract_diff.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/test_defect_memory.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/test_env_control.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/test_test_runner.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/test_tracker.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/mcp/test_vcs.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/support.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/target_app/test_seeded_defects.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_cli.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_config.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_discover.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_envelope.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_guardrails.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_hooks_and_skills.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_paths.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_prompt_overrides.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_registry.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_scorecard.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_skills_actually_load.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_store.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_target_profile_is_honoured.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_trace.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tests/test_user_mcp_servers.py +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/01-code-structure.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/02-how-agents-communicate.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/03-skills-and-hooks.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/04-mcp-servers.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/05-prompt-configuration.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/06-jira-integration.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/07-github-actions.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/08-packaging-and-publishing.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/09-guardrails-and-safety.md +0 -0
- {qaas_python-0.2.0 → qaas_python-0.2.1}/tutorial/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: qaas-python
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A multi-agent QA system: finds real defects, reproduces them, files tickets, fixes them, and proves the fix
|
|
5
5
|
Project-URL: Homepage, https://github.com/allaabdella2-us/qa-multi-agent-system
|
|
6
6
|
Project-URL: Repository, https://github.com/allaabdella2-us/qa-multi-agent-system
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Distribution name is `qaas-python` (`qaas` was taken); the import package and
|
|
3
3
|
# the CLI are both `qaas`.
|
|
4
4
|
name = "qaas-python"
|
|
5
|
-
version = "0.2.
|
|
5
|
+
version = "0.2.1"
|
|
6
6
|
description = "A multi-agent QA system: finds real defects, reproduces them, files tickets, fixes them, and proves the fix"
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
license = "MIT"
|
|
@@ -449,16 +449,14 @@ def doctor(
|
|
|
449
449
|
|
|
450
450
|
|
|
451
451
|
def _agent_usable(spec, caps: dict[str, bool]) -> bool:
|
|
452
|
-
"""
|
|
452
|
+
"""Delegates to `target.agent_usable`, which the conductor also uses.
|
|
453
453
|
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
Two copies of this rule meant `qaas doctor` could report an agent unusable
|
|
455
|
+
while a run dispatched it anyway.
|
|
456
456
|
"""
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return caps["live_api"] or caps["static_analysis"]
|
|
461
|
-
return True
|
|
457
|
+
from qaas.target import agent_usable
|
|
458
|
+
|
|
459
|
+
return agent_usable(spec.name, caps)
|
|
462
460
|
|
|
463
461
|
|
|
464
462
|
@app.command()
|
|
@@ -25,6 +25,7 @@ from typing import Any, Callable
|
|
|
25
25
|
|
|
26
26
|
from qaas.config import AgentSpec, SystemConfig, load_config
|
|
27
27
|
from qaas.envelope import DefectEnvelope
|
|
28
|
+
from qaas.target import agent_usable
|
|
28
29
|
from qaas.mcp.context import ToolContext
|
|
29
30
|
from qaas.runner import RunOutcome, run_agent
|
|
30
31
|
from qaas.store import RunStore, SystemMapStore
|
|
@@ -269,6 +270,27 @@ class Conductor:
|
|
|
269
270
|
async def _phase_discover(self, specs, store, budget, report, mode, map_version) -> None:
|
|
270
271
|
"""Discovery agents are independent. Run them concurrently, bounded."""
|
|
271
272
|
discovery = [s for name, s in specs.items() if s.layer == "discovery"]
|
|
273
|
+
|
|
274
|
+
# Skip agents this target cannot support. `qaas doctor` has always
|
|
275
|
+
# reported these ("agents that cannot: SURFACE"), but nothing acted on
|
|
276
|
+
# it, so a run against a target with no reachable UI would still
|
|
277
|
+
# dispatch SURFACE and spend its entire budget hunting a browser that
|
|
278
|
+
# was never there. Being told an agent cannot work and then watching it
|
|
279
|
+
# run is worse than not being told.
|
|
280
|
+
profile = getattr(self.config, "profile", None)
|
|
281
|
+
if profile is not None:
|
|
282
|
+
caps = profile.capabilities()
|
|
283
|
+
unusable = [s for s in discovery if not agent_usable(s.name, caps)]
|
|
284
|
+
if unusable:
|
|
285
|
+
discovery = [s for s in discovery if s not in unusable]
|
|
286
|
+
store.log(
|
|
287
|
+
"skipped",
|
|
288
|
+
reason="target cannot support these agents",
|
|
289
|
+
agents=[s.name for s in unusable],
|
|
290
|
+
)
|
|
291
|
+
for spec in unusable:
|
|
292
|
+
self._emit("skipped", agent=spec.name, reason="target lacks the capability")
|
|
293
|
+
|
|
272
294
|
if not discovery:
|
|
273
295
|
return
|
|
274
296
|
|
|
@@ -259,3 +259,21 @@ def load_target(name: str, targets_dir: Path | str = "config/targets") -> Target
|
|
|
259
259
|
# directory is the bug that hid `<project>/config/targets/` the moment anything
|
|
260
260
|
# wrote into `.qaas/config/targets/`; profiles layer across every config
|
|
261
261
|
# directory, and `config.target_files(dirs)` is the one place that knows it.
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def agent_usable(agent_name: str, caps: dict[str, bool]) -> bool:
|
|
265
|
+
"""Whether an agent can do useful work with the capabilities available.
|
|
266
|
+
|
|
267
|
+
Lives here, beside `capabilities()`, because it has two callers that must
|
|
268
|
+
agree: `qaas doctor` reports it, and the conductor acts on it. They did not
|
|
269
|
+
agree for a while -- doctor would say "agents that cannot: SURFACE" and then
|
|
270
|
+
a run would dispatch SURFACE anyway and spend its whole budget looking for a
|
|
271
|
+
browser that was never there. Being told an agent cannot work and then
|
|
272
|
+
watching it run is worse than not being told.
|
|
273
|
+
|
|
274
|
+
Everything except SURFACE can contribute from static analysis alone, at
|
|
275
|
+
lower confidence. SURFACE without a reachable UI has nothing to do at all.
|
|
276
|
+
"""
|
|
277
|
+
if agent_name == "SURFACE":
|
|
278
|
+
return caps.get("live_ui", False)
|
|
279
|
+
return True
|
|
@@ -561,3 +561,23 @@ async def test_a_new_discovery_agent_runs_without_a_hand_written_task(cfg, tmp_p
|
|
|
561
561
|
report = await make_conductor(cfg, tmp_path).run("nightly")
|
|
562
562
|
ran = {name for name, _ in calls}
|
|
563
563
|
assert {"VAULT", "WARDEN"} <= ran, f"a config-only agent was skipped: {sorted(ran)}"
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
async def test_an_agent_the_target_cannot_support_is_not_dispatched(cfg, tmp_path, fake_agents):
|
|
567
|
+
"""`qaas doctor` has always reported "agents that cannot: SURFACE" for a
|
|
568
|
+
target with no reachable UI. Nothing acted on it: the run dispatched SURFACE
|
|
569
|
+
anyway and spent its budget looking for a browser that was never there.
|
|
570
|
+
|
|
571
|
+
Being told an agent cannot work and then watching it run is worse than not
|
|
572
|
+
being told, which is why this asserts the dispatch, not the report.
|
|
573
|
+
"""
|
|
574
|
+
calls, behaviour = fake_agents
|
|
575
|
+
from qaas.target import Environment, TargetProfile
|
|
576
|
+
|
|
577
|
+
static_only = TargetProfile(name="static", root=".", environment=Environment(mode="none"))
|
|
578
|
+
cfg2 = cfg.model_copy(update={"profile": static_only})
|
|
579
|
+
|
|
580
|
+
await make_conductor(cfg2, tmp_path).run("pr-check")
|
|
581
|
+
ran = {name for name, _ in calls}
|
|
582
|
+
assert "SURFACE" not in ran, "dispatched SURFACE at a target with no UI"
|
|
583
|
+
assert "CONDUIT" in ran, "static analysis agents must still run"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/api-surface-extraction/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/console-error-triage/SKILL.md
RENAMED
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/contract-test-generation/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/failing-test-authoring/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/minimal-diff-discipline/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/ownership-resolution/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/regression-risk-scoring/SKILL.md
RENAMED
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/regression-suite-selection/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/rollback-plan-authoring/SKILL.md
RENAMED
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/root-cause-vs-symptom/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qaas_python-0.2.0 → qaas_python-0.2.1}/src/qaas/plugin/skills/verification-protocol/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|