specterqa 0.3.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 (79) hide show
  1. specterqa-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  2. specterqa-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +51 -0
  3. specterqa-0.3.0/.github/pull_request_template.md +25 -0
  4. specterqa-0.3.0/.github/workflows/ci.yml +51 -0
  5. specterqa-0.3.0/.github/workflows/publish.yml +31 -0
  6. specterqa-0.3.0/.gitignore +57 -0
  7. specterqa-0.3.0/.mcpregistry_github_token +1 -0
  8. specterqa-0.3.0/.mcpregistry_registry_token +1 -0
  9. specterqa-0.3.0/.well-known/agent.json +106 -0
  10. specterqa-0.3.0/CHANGELOG.md +76 -0
  11. specterqa-0.3.0/CONTRIBUTING.md +94 -0
  12. specterqa-0.3.0/LICENSE +21 -0
  13. specterqa-0.3.0/PKG-INFO +442 -0
  14. specterqa-0.3.0/README.md +400 -0
  15. specterqa-0.3.0/SECURITY.md +70 -0
  16. specterqa-0.3.0/SECURITY_ADVISORY.md +129 -0
  17. specterqa-0.3.0/docs/ci-integration.md +255 -0
  18. specterqa-0.3.0/docs/configuration.md +293 -0
  19. specterqa-0.3.0/docs/cost-guide.md +223 -0
  20. specterqa-0.3.0/docs/for-agents.md +447 -0
  21. specterqa-0.3.0/examples/demo-app/app.py +45 -0
  22. specterqa-0.3.0/examples/demo-app/requirements.txt +1 -0
  23. specterqa-0.3.0/examples/demo-app/templates/dashboard.html +57 -0
  24. specterqa-0.3.0/examples/demo-app/templates/homepage.html +55 -0
  25. specterqa-0.3.0/examples/demo-app/templates/signup.html +55 -0
  26. specterqa-0.3.0/examples/journeys/demo-onboarding.yaml +35 -0
  27. specterqa-0.3.0/examples/journeys/forgeos-onboarding.yaml +61 -0
  28. specterqa-0.3.0/examples/personas/alex-developer.yaml +18 -0
  29. specterqa-0.3.0/examples/products/demo.yaml +12 -0
  30. specterqa-0.3.0/examples/products/forgeos.yaml +12 -0
  31. specterqa-0.3.0/pyproject.toml +84 -0
  32. specterqa-0.3.0/server.json +37 -0
  33. specterqa-0.3.0/src/specterqa/__init__.py +3 -0
  34. specterqa-0.3.0/src/specterqa/__main__.py +5 -0
  35. specterqa-0.3.0/src/specterqa/cli/__init__.py +1 -0
  36. specterqa-0.3.0/src/specterqa/cli/app.py +94 -0
  37. specterqa-0.3.0/src/specterqa/cli/config_cmd.py +242 -0
  38. specterqa-0.3.0/src/specterqa/cli/dashboard.py +145 -0
  39. specterqa-0.3.0/src/specterqa/cli/init_cmd.py +269 -0
  40. specterqa-0.3.0/src/specterqa/cli/install.py +129 -0
  41. specterqa-0.3.0/src/specterqa/cli/report.py +243 -0
  42. specterqa-0.3.0/src/specterqa/cli/run.py +776 -0
  43. specterqa-0.3.0/src/specterqa/cli/validate.py +554 -0
  44. specterqa-0.3.0/src/specterqa/config.py +134 -0
  45. specterqa-0.3.0/src/specterqa/credentials.py +89 -0
  46. specterqa-0.3.0/src/specterqa/engine/__init__.py +49 -0
  47. specterqa-0.3.0/src/specterqa/engine/action_executor.py +1622 -0
  48. specterqa-0.3.0/src/specterqa/engine/ai_step_runner.py +590 -0
  49. specterqa-0.3.0/src/specterqa/engine/api_runner.py +552 -0
  50. specterqa-0.3.0/src/specterqa/engine/browser_runner.py +790 -0
  51. specterqa-0.3.0/src/specterqa/engine/cost_tracker.py +408 -0
  52. specterqa-0.3.0/src/specterqa/engine/mock_server.py +480 -0
  53. specterqa-0.3.0/src/specterqa/engine/native_action_executor.py +181 -0
  54. specterqa-0.3.0/src/specterqa/engine/native_app_runner.py +1523 -0
  55. specterqa-0.3.0/src/specterqa/engine/orchestrator.py +1000 -0
  56. specterqa-0.3.0/src/specterqa/engine/persona_agent.py +638 -0
  57. specterqa-0.3.0/src/specterqa/engine/protocols.py +85 -0
  58. specterqa-0.3.0/src/specterqa/engine/report_generator.py +210 -0
  59. specterqa-0.3.0/src/specterqa/engine/sim_action_executor.py +270 -0
  60. specterqa-0.3.0/src/specterqa/engine/simulator_runner.py +792 -0
  61. specterqa-0.3.0/src/specterqa/mcp/__init__.py +12 -0
  62. specterqa-0.3.0/src/specterqa/mcp/__main__.py +5 -0
  63. specterqa-0.3.0/src/specterqa/mcp/server.py +884 -0
  64. specterqa-0.3.0/src/specterqa/models.py +27 -0
  65. specterqa-0.3.0/src/specterqa/viewer/__init__.py +1 -0
  66. specterqa-0.3.0/src/specterqa/viewer/server.py +476 -0
  67. specterqa-0.3.0/src/specterqa/viewer/static/style.css +908 -0
  68. specterqa-0.3.0/src/specterqa/viewer/templates/base.html +33 -0
  69. specterqa-0.3.0/src/specterqa/viewer/templates/detail.html +284 -0
  70. specterqa-0.3.0/src/specterqa/viewer/templates/index.html +117 -0
  71. specterqa-0.3.0/tests/__init__.py +0 -0
  72. specterqa-0.3.0/tests/conftest.py +79 -0
  73. specterqa-0.3.0/tests/test_cli_init.py +175 -0
  74. specterqa-0.3.0/tests/test_config.py +193 -0
  75. specterqa-0.3.0/tests/test_cost_tracker.py +310 -0
  76. specterqa-0.3.0/tests/test_credentials.py +228 -0
  77. specterqa-0.3.0/tests/test_mcp_server.py +1754 -0
  78. specterqa-0.3.0/tests/test_models.py +136 -0
  79. specterqa-0.3.0/tests/test_report_generator.py +279 -0
@@ -0,0 +1,83 @@
1
+ name: Bug Report
2
+ description: Report a bug in SpecterQA
3
+ title: "[Bug]: "
4
+ labels: ["bug", "triage"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for reporting a bug! Please fill out the sections below so we can reproduce and fix the issue.
10
+
11
+ - type: textarea
12
+ id: description
13
+ attributes:
14
+ label: Description
15
+ description: A clear and concise description of what the bug is.
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: steps
21
+ attributes:
22
+ label: Steps to reproduce
23
+ description: How can we reproduce this behavior?
24
+ placeholder: |
25
+ 1. Create a persona YAML with ...
26
+ 2. Run `specterqa run ...`
27
+ 3. See error ...
28
+ validations:
29
+ required: true
30
+
31
+ - type: textarea
32
+ id: expected
33
+ attributes:
34
+ label: Expected behavior
35
+ description: What did you expect to happen?
36
+ validations:
37
+ required: true
38
+
39
+ - type: textarea
40
+ id: actual
41
+ attributes:
42
+ label: Actual behavior
43
+ description: What actually happened? Include error messages or screenshots if applicable.
44
+ validations:
45
+ required: true
46
+
47
+ - type: input
48
+ id: specterqa-version
49
+ attributes:
50
+ label: SpecterQA version
51
+ description: "Output of `specterqa --version` or `pip show specterqa`"
52
+ placeholder: "0.1.0"
53
+ validations:
54
+ required: true
55
+
56
+ - type: input
57
+ id: python-version
58
+ attributes:
59
+ label: Python version
60
+ description: "Output of `python --version`"
61
+ placeholder: "3.12.0"
62
+ validations:
63
+ required: true
64
+
65
+ - type: dropdown
66
+ id: os
67
+ attributes:
68
+ label: Operating system
69
+ options:
70
+ - Linux
71
+ - macOS
72
+ - Windows
73
+ - Other
74
+ validations:
75
+ required: true
76
+
77
+ - type: textarea
78
+ id: additional
79
+ attributes:
80
+ label: Additional context
81
+ description: Any other context, logs, or screenshots about the problem.
82
+ validations:
83
+ required: false
@@ -0,0 +1,51 @@
1
+ name: Feature Request
2
+ description: Suggest a new feature or improvement for SpecterQA
3
+ title: "[Feature]: "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ Thanks for suggesting an improvement! Please describe your idea below.
10
+
11
+ - type: textarea
12
+ id: description
13
+ attributes:
14
+ label: Description
15
+ description: A clear and concise description of the feature you'd like.
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: use-case
21
+ attributes:
22
+ label: Use case
23
+ description: What problem does this solve? Who benefits from it?
24
+ placeholder: |
25
+ As a QA engineer, I want to ... so that ...
26
+ validations:
27
+ required: true
28
+
29
+ - type: textarea
30
+ id: proposed-solution
31
+ attributes:
32
+ label: Proposed solution
33
+ description: How do you envision this working? Include API ideas, CLI flags, YAML config examples, etc.
34
+ validations:
35
+ required: false
36
+
37
+ - type: textarea
38
+ id: alternatives
39
+ attributes:
40
+ label: Alternatives considered
41
+ description: Have you considered other approaches? What are the trade-offs?
42
+ validations:
43
+ required: false
44
+
45
+ - type: textarea
46
+ id: additional
47
+ attributes:
48
+ label: Additional context
49
+ description: Any other context, mockups, or references.
50
+ validations:
51
+ required: false
@@ -0,0 +1,25 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do? Why is it needed? Link related issues with "Closes #123". -->
4
+
5
+ ## Changes
6
+
7
+ <!-- Bullet list of the key changes in this PR. -->
8
+
9
+ -
10
+
11
+ ## Test plan
12
+
13
+ <!-- How did you verify this works? Include commands, screenshots, or test output. -->
14
+
15
+ - [ ] Tests pass locally (`pytest tests/ -v`)
16
+ - [ ] Linting passes (`ruff check src/`)
17
+ - [ ] Formatting passes (`ruff format --check src/`)
18
+
19
+ ## Checklist
20
+
21
+ - [ ] I have read the [contributing guide](../CONTRIBUTING.md)
22
+ - [ ] My code follows the project's style (ruff-enforced)
23
+ - [ ] I have added tests for new functionality
24
+ - [ ] I have updated documentation if needed
25
+ - [ ] All new and existing tests pass
@@ -0,0 +1,51 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ lint:
15
+ name: Lint
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev,mcp]"
26
+
27
+ - name: Ruff check
28
+ run: ruff check src/
29
+
30
+ - name: Ruff format check
31
+ run: ruff format --check src/
32
+
33
+ test:
34
+ name: Test (Python ${{ matrix.python-version }})
35
+ runs-on: ubuntu-latest
36
+ strategy:
37
+ fail-fast: false
38
+ matrix:
39
+ python-version: ["3.10", "3.11", "3.12"]
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+
43
+ - uses: actions/setup-python@v5
44
+ with:
45
+ python-version: ${{ matrix.python-version }}
46
+
47
+ - name: Install dependencies
48
+ run: pip install -e ".[dev,mcp]"
49
+
50
+ - name: Run tests
51
+ run: pytest tests/ -v --tb=short
@@ -0,0 +1,31 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+
10
+ jobs:
11
+ publish:
12
+ name: Build and publish to PyPI
13
+ runs-on: ubuntu-latest
14
+ environment:
15
+ name: pypi
16
+ url: https://pypi.org/p/specterqa
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install build tools
25
+ run: pip install build
26
+
27
+ - name: Build package
28
+ run: python -m build
29
+
30
+ - name: Publish to PyPI
31
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,57 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ .Python
9
+ build/
10
+ develop-eggs/
11
+ dist/
12
+ downloads/
13
+ eggs/
14
+ .eggs/
15
+ lib/
16
+ lib64/
17
+ parts/
18
+ sdist/
19
+ var/
20
+ wheels/
21
+ *.egg-info/
22
+ *.egg
23
+
24
+ # Virtual environments
25
+ .venv/
26
+ env/
27
+ venv/
28
+ ENV/
29
+
30
+ # IDE
31
+ .vscode/
32
+ .idea/
33
+ *.swp
34
+ *.swo
35
+ *~
36
+
37
+ # Testing
38
+ .pytest_cache/
39
+ .coverage
40
+ htmlcov/
41
+ .mypy_cache/
42
+ .ruff_cache/
43
+
44
+ # Environment variables
45
+ .env
46
+ .env.local
47
+ .env.*.local
48
+
49
+ # GhostQA project config and evidence
50
+ .ghostqa/config.yaml
51
+ .ghostqa/evidence/
52
+ evidence/
53
+ **/evidence/**/*.png
54
+
55
+ # OS
56
+ .DS_Store
57
+ Thumbs.db
@@ -0,0 +1 @@
1
+ ghu_W3yptWq9TzcU9hjKG9YQSuy4XA5OEt3tuVe9
@@ -0,0 +1 @@
1
+ {"token":"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtY3AtcmVnaXN0cnkiLCJleHAiOjE3NzE4MzAwMDgsIm5iZiI6MTc3MTgyOTcwOCwiaWF0IjoxNzcxODI5NzA4LCJhdXRoX21ldGhvZCI6ImdpdGh1Yi1hdCIsImF1dGhfbWV0aG9kX3N1YiI6IlN5bmNUZWtMTEMiLCJwZXJtaXNzaW9ucyI6W3siYWN0aW9uIjoicHVibGlzaCIsInJlc291cmNlIjoiaW8uZ2l0aHViLlN5bmNUZWtMTEMvKiJ9XX0.t0WySIpPwOm0CcdJrNreFdLjZAV1y_aQ2VIA8Ujc_c2Hv7vYxUeI4DBRO-HQnQNi3kYBMYbC8L5ay_f4BXxgBQ","expires_at":1771830008}
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "SpecterQA",
3
+ "description": "AI behavioral testing for web and native applications. AI personas navigate your app in real browser sessions and report UX issues, broken flows, and errors — no test scripts required.",
4
+ "version": "0.3.0",
5
+ "url": "https://github.com/SyncTek-LLC/specterqa",
6
+ "homepage": "https://github.com/SyncTek-LLC/specterqa",
7
+ "license": "MIT",
8
+ "capabilities": [
9
+ "behavioral_testing",
10
+ "ux_analysis",
11
+ "vision_testing",
12
+ "cost_tracking",
13
+ "mcp"
14
+ ],
15
+ "invocation": {
16
+ "cli": {
17
+ "command": "specterqa run -p <product>",
18
+ "install": "pip install specterqa",
19
+ "json_output_flag": "--output json",
20
+ "exit_codes": {
21
+ "0": "all_passed",
22
+ "1": "test_failure",
23
+ "2": "config_error",
24
+ "3": "infra_error"
25
+ }
26
+ },
27
+ "python": {
28
+ "import": "from specterqa.engine.orchestrator import SpecterQAOrchestrator",
29
+ "package": "specterqa",
30
+ "entry_class": "specterqa.engine.orchestrator.SpecterQAOrchestrator"
31
+ },
32
+ "mcp": {
33
+ "command": "specterqa-mcp",
34
+ "transport": "stdio",
35
+ "config_example": {
36
+ "specterqa": {
37
+ "command": "specterqa-mcp",
38
+ "args": []
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "cost_model": {
44
+ "type": "per_run",
45
+ "basis": "anthropic_api_usage",
46
+ "typical_range_usd": [0.30, 1.50],
47
+ "budget_enforcement": true,
48
+ "default_budget_usd": 5.00,
49
+ "notes": "specterqa_run MCP calls are synchronous and may take 45-300 seconds. Budget cap enforced per run."
50
+ },
51
+ "tools": [
52
+ {
53
+ "name": "specterqa_run",
54
+ "description": "Run behavioral tests on a product. AI personas navigate the app and report UX issues. Synchronous — may take 45-300s. Incurs Anthropic API costs (default budget: $5.00).",
55
+ "inputs": {
56
+ "product": "string (required) — product name matching .specterqa/products/<name>.yaml",
57
+ "journey": "string (optional) — journey ID; runs all journeys if omitted",
58
+ "level": "string (optional) — smoke | standard | thorough",
59
+ "budget": "float (optional) — cost cap in USD, default 5.00",
60
+ "directory": "string (optional) — project root directory, defaults to CWD"
61
+ },
62
+ "outputs": "JSON with passed, run_id, step_reports, findings, cost_usd, cost_summary"
63
+ },
64
+ {
65
+ "name": "specterqa_list_products",
66
+ "description": "List configured test products and their available journeys.",
67
+ "inputs": {
68
+ "directory": "string (optional) — project root directory, defaults to CWD"
69
+ },
70
+ "outputs": "Array of product configs with product name, display name, and journey IDs"
71
+ },
72
+ {
73
+ "name": "specterqa_get_results",
74
+ "description": "Retrieve full structured results from a previous run by run ID.",
75
+ "inputs": {
76
+ "run_id": "string (required) — run ID in format GQA-RUN-YYYYMMDD-HHMMSS-xxxx",
77
+ "directory": "string (optional) — project root directory, defaults to CWD"
78
+ },
79
+ "outputs": "Full run result JSON including step reports, findings, screenshots paths, and cost breakdown"
80
+ },
81
+ {
82
+ "name": "specterqa_init",
83
+ "description": "Initialize a new SpecterQA project directory with sample product, persona, and journey configs.",
84
+ "inputs": {
85
+ "directory": "string (optional) — target directory for initialization, defaults to CWD"
86
+ },
87
+ "outputs": "List of created file paths"
88
+ }
89
+ ],
90
+ "requirements": {
91
+ "python": ">=3.10",
92
+ "anthropic_api_key": true,
93
+ "playwright": ">=1.48.0",
94
+ "notes": "Run 'specterqa install' after pip install to download Playwright browsers"
95
+ },
96
+ "output_schema": {
97
+ "run_result": {
98
+ "passed": "boolean — top-level pass/fail",
99
+ "run_id": "string — unique run identifier",
100
+ "step_reports": "array — per-step pass/fail, duration, error",
101
+ "findings": "array — UX issues found, each with severity, category, description, step_id",
102
+ "cost_usd": "float — total API cost for this run",
103
+ "cost_summary": "object — detailed cost breakdown with budget status"
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,76 @@
1
+ # Changelog
2
+
3
+ All notable changes to SpecterQA are documented here.
4
+
5
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [0.3.0] — 2026-02-23
11
+
12
+ ### Changed
13
+
14
+ - **Rebrand: GhostQA -> SpecterQA.** Package renamed from `ghostqa` to `specterqa`. All imports, CLI commands, MCP tool names, environment variables, and project directory paths updated accordingly. Key changes:
15
+ - CLI: `ghostqa` -> `specterqa`, `ghostqa-mcp` -> `specterqa-mcp`
16
+ - Python imports: `from ghostqa` -> `from specterqa`
17
+ - Classes: `GhostQAConfig` -> `SpecterQAConfig`, `GhostQAOrchestrator` -> `SpecterQAOrchestrator`
18
+ - MCP tools: `ghostqa_run` -> `specterqa_run`, `ghostqa_list_products` -> `specterqa_list_products`, etc.
19
+ - Env vars: `GHOSTQA_ALLOWED_DIRS` -> `SPECTERQA_ALLOWED_DIRS`, `GHOSTQA_PROJECT_DIR` -> `SPECTERQA_PROJECT_DIR`, etc.
20
+ - Project directory: `.ghostqa/` -> `.specterqa/`
21
+ - Repository URL: `github.com/SyncTek-LLC/ghostqa` -> `github.com/SyncTek-LLC/specterqa`
22
+
23
+ ---
24
+
25
+ ## [0.2.2] — 2026-02-23
26
+
27
+ ### Changed
28
+
29
+ - Added MCP Registry verification metadata to README (`mcp-name` comment)
30
+ - Added `server.json` for Official MCP Registry submission
31
+
32
+ ---
33
+
34
+ ## [0.2.1] — 2026-02-23
35
+
36
+ ### Security
37
+
38
+ - **[CRITICAL] Command injection fix (GHSA-SPECTERQA-001):** Removed the `check_command` field from the product YAML schema. The field allowed arbitrary shell commands to be embedded in a YAML service definition and executed by the SpecterQA process. Precondition service checks are now limited to TCP connectivity and HTTP health endpoint checks, which are safe. No workaround exists for v0.2.0 and earlier other than removing `check_command` from all product YAMLs. See [SECURITY_ADVISORY.md](SECURITY_ADVISORY.md) for full details.
39
+ - **MCP directory traversal fix (SPECTERQA_ALLOWED_DIRS):** The MCP server's `specterqa_run` tool now enforces an allowlist for the `directory` parameter when the `SPECTERQA_ALLOWED_DIRS` environment variable is set. Any path not under an allowed prefix is rejected with a structured error response. When the variable is unset, all paths remain accessible (permissive default for local development). Users running the MCP server in shared or multi-user environments should set this variable. See the [README Security section](README.md#security) and [docs/for-agents.md](docs/for-agents.md) for configuration guidance.
40
+ - **Credential scrubbing in run artifacts:** Run result JSON files and log output now automatically scrub known credential patterns (API keys, bearer tokens, passwords, connection strings) before writing to disk. Evidence directories are safer to share and commit as CI artifacts.
41
+ - **API key template removed from sample config:** The `specterqa init` sample configuration previously included a placeholder `anthropic_api_key: sk-ant-...` in `.specterqa/config.yaml`. This has been replaced with an environment variable reference (`${ANTHROPIC_API_KEY}`) to prevent accidental key commits.
42
+
43
+ ### Added
44
+
45
+ - **`--plain` mode for CI and screen readers:** `specterqa run --plain` disables Rich formatting, colors, and progress spinners and emits plain text to stdout. Useful in CI environments where Rich markup becomes noise, and for accessibility tools that consume terminal output.
46
+ - **`--fail-on-severity` threshold flag:** `specterqa run --fail-on-severity high` causes the run to exit with a non-zero status if any finding at or above the specified severity level is recorded, even if all steps technically passed. Accepted values: `low`, `medium`, `high`, `critical`, `block`. Default behavior (exit 0 on step pass) is unchanged.
47
+ - **`specterqa validate` command:** Validates product, persona, and journey YAML files against the SpecterQA schema without running a test. Reports schema errors, missing required fields, and deprecated fields (including `check_command`, which now produces a schema error). Useful in CI as a pre-flight check.
48
+ - **`.well-known/agent.json` — A2A Agent Card:** SpecterQA now ships an Agent Card at `.well-known/agent.json` following the [Agent-to-Agent (A2A) protocol](https://google.github.io/A2A/). This allows A2A-compatible agent hosts to discover SpecterQA's capabilities, available tools, input/output schemas, and cost model without prior out-of-band configuration.
49
+ - **108 new MCP server tests (248 total):** The MCP server test suite has been expanded from 140 to 248 tests, covering the `SPECTERQA_ALLOWED_DIRS` allowlist enforcement, credential scrubbing behavior, `specterqa validate` tool, the `--plain` and `--fail-on-severity` CLI flags, and edge cases in the `specterqa_run` tool response schema.
50
+
51
+ ### Changed
52
+
53
+ - The `services.*.check_command` field in product YAMLs is now a schema error. Existing configs containing this field will be rejected by `specterqa validate` and produce a startup error on `specterqa run`. Remove the field and use `health_endpoint` or TCP port checks instead.
54
+ - The `specterqa init` sample product YAML no longer includes a `check_command` example.
55
+
56
+ ---
57
+
58
+ ## [0.2.0] — 2026-02-22
59
+
60
+ Initial public release.
61
+
62
+ - Persona-based behavioral testing via YAML-configured personas and journeys
63
+ - Claude vision model integration (Haiku for simple actions, Sonnet for complex reasoning)
64
+ - Playwright-based browser automation with headless support
65
+ - macOS native app testing via Accessibility API (pyobjc optional extra)
66
+ - iOS Simulator testing via simctl (pyobjc optional extra)
67
+ - Budget enforcement with per-run, per-day, and per-month caps
68
+ - JUnit XML output for CI integration
69
+ - JSON structured output (`--output json`) for programmatic consumption
70
+ - Evidence collection: screenshots, findings, cost breakdown, run-result.json per run
71
+ - Stuck detection with model escalation (Haiku → Sonnet → abort)
72
+ - Template variables in journey steps (`{{persona.credentials.email}}`)
73
+ - MCP server (`specterqa-mcp`) exposing `specterqa_run`, `specterqa_list_products`, `specterqa_get_results`, `specterqa_init`
74
+ - Tiered model routing with optional local Ollama fallback for zero-cost simple actions
75
+ - Federated protocol: swap in custom `AIDecider` or `ActionExecutor` implementations
76
+ - 140 unit tests across config, cost tracking, report generation, MCP server, and CLI
@@ -0,0 +1,94 @@
1
+ # Contributing to SpecterQA
2
+
3
+ Thanks for your interest in contributing to SpecterQA! This guide will help you get started.
4
+
5
+ ## Development Setup
6
+
7
+ 1. **Clone the repository**
8
+
9
+ ```bash
10
+ git clone https://github.com/SyncTek-LLC/specterqa.git
11
+ cd specterqa
12
+ ```
13
+
14
+ 2. **Create a virtual environment**
15
+
16
+ ```bash
17
+ python -m venv .venv
18
+ source .venv/bin/activate # Linux/macOS
19
+ # .venv\Scripts\activate # Windows
20
+ ```
21
+
22
+ 3. **Install in development mode**
23
+
24
+ ```bash
25
+ pip install -e ".[dev]"
26
+ ```
27
+
28
+ 4. **Install Playwright browsers** (needed for integration tests)
29
+
30
+ ```bash
31
+ playwright install chromium
32
+ ```
33
+
34
+ ## Running Tests
35
+
36
+ ```bash
37
+ # Run all unit tests
38
+ pytest tests/ -v
39
+
40
+ # Run with coverage
41
+ pytest tests/ -v --cov=src/specterqa --cov-report=term-missing
42
+
43
+ # Skip integration tests (which require a running app and API key)
44
+ pytest tests/ -v -m "not integration"
45
+ ```
46
+
47
+ ## Code Quality
48
+
49
+ We use [Ruff](https://docs.astral.sh/ruff/) for linting and formatting.
50
+
51
+ ```bash
52
+ # Check for lint issues
53
+ ruff check src/
54
+
55
+ # Auto-fix lint issues
56
+ ruff check src/ --fix
57
+
58
+ # Check formatting
59
+ ruff format --check src/
60
+
61
+ # Auto-format
62
+ ruff format src/
63
+ ```
64
+
65
+ Type checking with mypy:
66
+
67
+ ```bash
68
+ mypy src/specterqa
69
+ ```
70
+
71
+ ## Submitting Changes
72
+
73
+ 1. **Fork the repository** and create a branch from `main`.
74
+ 2. **Make your changes.** Add tests for new functionality.
75
+ 3. **Ensure all checks pass:**
76
+ ```bash
77
+ ruff check src/
78
+ ruff format --check src/
79
+ pytest tests/ -v
80
+ ```
81
+ 4. **Open a pull request** against `main`. Fill out the PR template.
82
+ 5. A maintainer will review your PR. Address any feedback, then it will be merged.
83
+
84
+ ## Reporting Bugs
85
+
86
+ Use the [bug report template](https://github.com/SyncTek-LLC/specterqa/issues/new?template=bug_report.yml) on GitHub Issues.
87
+
88
+ ## Requesting Features
89
+
90
+ Use the [feature request template](https://github.com/SyncTek-LLC/specterqa/issues/new?template=feature_request.yml) on GitHub Issues.
91
+
92
+ ## License
93
+
94
+ By contributing to SpecterQA, you agree that your contributions will be licensed under the [MIT License](LICENSE). All contributions are subject to this project's license terms.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SyncTek LLC
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.