qaas-python 0.0.1__py3-none-any.whl

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 (96) hide show
  1. qaas/adapters/__init__.py +19 -0
  2. qaas/adapters/tracker.py +1783 -0
  3. qaas/adapters/vcs.py +555 -0
  4. qaas/cli.py +1757 -0
  5. qaas/config.py +409 -0
  6. qaas/defaults/config/agents/api.yaml +18 -0
  7. qaas/defaults/config/agents/architect.yaml +21 -0
  8. qaas/defaults/config/agents/auditor.yaml +19 -0
  9. qaas/defaults/config/agents/browser.yaml +15 -0
  10. qaas/defaults/config/agents/dba.yaml +20 -0
  11. qaas/defaults/config/agents/fixer.yaml +55 -0
  12. qaas/defaults/config/agents/guide.yaml +23 -0
  13. qaas/defaults/config/agents/load.yaml +26 -0
  14. qaas/defaults/config/agents/mapper.yaml +19 -0
  15. qaas/defaults/config/agents/reporter.yaml +19 -0
  16. qaas/defaults/config/agents/reproducer.yaml +21 -0
  17. qaas/defaults/config/agents/reviewer.yaml +18 -0
  18. qaas/defaults/config/agents/socket.yaml +23 -0
  19. qaas/defaults/config/agents/triage.yaml +20 -0
  20. qaas/defaults/config/agents/verifier.yaml +20 -0
  21. qaas/defaults/config/system.yaml +64 -0
  22. qaas/discover.py +242 -0
  23. qaas/envelope.py +318 -0
  24. qaas/envfile.py +100 -0
  25. qaas/guardrails.py +589 -0
  26. qaas/mcp/__init__.py +0 -0
  27. qaas/mcp/context.py +78 -0
  28. qaas/mcp/contract_diff.py +1011 -0
  29. qaas/mcp/defect_memory.py +495 -0
  30. qaas/mcp/env_control.py +925 -0
  31. qaas/mcp/envelope_server.py +463 -0
  32. qaas/mcp/test_runner.py +842 -0
  33. qaas/mcp/tracker.py +420 -0
  34. qaas/mcp/vcs.py +501 -0
  35. qaas/paths.py +317 -0
  36. qaas/plugin/.claude-plugin/plugin.json +9 -0
  37. qaas/plugin/skills/a11y-audit/SKILL.md +34 -0
  38. qaas/plugin/skills/adversarial-review/SKILL.md +120 -0
  39. qaas/plugin/skills/api-surface-extraction/SKILL.md +38 -0
  40. qaas/plugin/skills/authz-matrix-check/SKILL.md +46 -0
  41. qaas/plugin/skills/console-error-triage/SKILL.md +39 -0
  42. qaas/plugin/skills/contract-test-generation/SKILL.md +36 -0
  43. qaas/plugin/skills/dedupe-strategy/SKILL.md +39 -0
  44. qaas/plugin/skills/environment-pinning/SKILL.md +35 -0
  45. qaas/plugin/skills/error-taxonomy/SKILL.md +42 -0
  46. qaas/plugin/skills/exploratory-ui-walk/SKILL.md +46 -0
  47. qaas/plugin/skills/failing-test-authoring/SKILL.md +47 -0
  48. qaas/plugin/skills/flake-detection/SKILL.md +39 -0
  49. qaas/plugin/skills/form-state-probe/SKILL.md +36 -0
  50. qaas/plugin/skills/minimal-diff-discipline/SKILL.md +70 -0
  51. qaas/plugin/skills/openapi-diff/SKILL.md +45 -0
  52. qaas/plugin/skills/ownership-resolution/SKILL.md +31 -0
  53. qaas/plugin/skills/product-task-graph/SKILL.md +35 -0
  54. qaas/plugin/skills/regression-risk-scoring/SKILL.md +59 -0
  55. qaas/plugin/skills/regression-suite-selection/SKILL.md +36 -0
  56. qaas/plugin/skills/repo-cartography/SKILL.md +38 -0
  57. qaas/plugin/skills/repro-minimisation/SKILL.md +41 -0
  58. qaas/plugin/skills/rollback-plan-authoring/SKILL.md +81 -0
  59. qaas/plugin/skills/root-cause-vs-symptom/SKILL.md +67 -0
  60. qaas/plugin/skills/routing-rules/SKILL.md +34 -0
  61. qaas/plugin/skills/severity-rubric/SKILL.md +42 -0
  62. qaas/plugin/skills/test-first-fix/SKILL.md +66 -0
  63. qaas/plugin/skills/test-quality-audit/SKILL.md +58 -0
  64. qaas/plugin/skills/ticket-writer/SKILL.md +40 -0
  65. qaas/plugin/skills/verdict-reporting/SKILL.md +35 -0
  66. qaas/plugin/skills/verification-protocol/SKILL.md +39 -0
  67. qaas/prompts/API.md +44 -0
  68. qaas/prompts/ARCHITECT.md +80 -0
  69. qaas/prompts/AUDITOR.md +62 -0
  70. qaas/prompts/BROWSER.md +46 -0
  71. qaas/prompts/DBA.md +59 -0
  72. qaas/prompts/FIXER.md +55 -0
  73. qaas/prompts/GUIDE.md +94 -0
  74. qaas/prompts/LOAD.md +109 -0
  75. qaas/prompts/MAPPER.md +46 -0
  76. qaas/prompts/REPORTER.md +61 -0
  77. qaas/prompts/REPRODUCER.md +43 -0
  78. qaas/prompts/REVIEWER.md +53 -0
  79. qaas/prompts/SOCKET.md +100 -0
  80. qaas/prompts/TRIAGE.md +45 -0
  81. qaas/prompts/VERIFIER.md +41 -0
  82. qaas/prompts/_shared.md +45 -0
  83. qaas/registry.py +496 -0
  84. qaas/router.py +581 -0
  85. qaas/runner.py +210 -0
  86. qaas/scorecard.py +448 -0
  87. qaas/sdk_compat.py +52 -0
  88. qaas/store.py +323 -0
  89. qaas/target.py +287 -0
  90. qaas/tasks.py +438 -0
  91. qaas/trace.py +342 -0
  92. qaas_python-0.0.1.dist-info/METADATA +429 -0
  93. qaas_python-0.0.1.dist-info/RECORD +96 -0
  94. qaas_python-0.0.1.dist-info/WHEEL +4 -0
  95. qaas_python-0.0.1.dist-info/entry_points.txt +2 -0
  96. qaas_python-0.0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,429 @@
1
+ Metadata-Version: 2.5
2
+ Name: qaas-python
3
+ Version: 0.0.1
4
+ Summary: A multi-agent QA system: finds real defects, reproduces them, files tickets, fixes them, and proves the fix
5
+ Project-URL: Homepage, https://github.com/allaabdella2-us/qa-multi-agent-system
6
+ Project-URL: Repository, https://github.com/allaabdella2-us/qa-multi-agent-system
7
+ Project-URL: Issues, https://github.com/allaabdella2-us/qa-multi-agent-system/issues
8
+ Project-URL: Changelog, https://github.com/allaabdella2-us/qa-multi-agent-system/blob/main/CHANGELOG.md
9
+ Author: Alla Abdella
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: agents,bug-finding,claude,llm,multi-agent,qa,testing
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Quality Assurance
19
+ Classifier: Topic :: Software Development :: Testing
20
+ Requires-Python: >=3.12
21
+ Requires-Dist: claude-agent-sdk>=0.2.127
22
+ Requires-Dist: pydantic>=2.9
23
+ Requires-Dist: pyyaml>=6.0
24
+ Requires-Dist: rich>=13.9
25
+ Requires-Dist: typer>=0.16
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
28
+ Requires-Dist: pytest>=8.3; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ <div align="center">
32
+
33
+ # 🐦‍⬛ qaas
34
+
35
+ ### A multi-agent QA system that finds real defects — and proves it
36
+
37
+ **Reads your application → finds defects → reproduces each with a failing test → files the ticket → fixes it → reviews the fix → verifies it.**
38
+
39
+ [![PyPI](https://img.shields.io/pypi/v/qaas-python?color=3775A9&logo=pypi&logoColor=white)](https://pypi.org/project/qaas-python/)
40
+ [![Python](https://img.shields.io/pypi/pyversions/qaas-python?color=3776AB&logo=python&logoColor=white)](https://pypi.org/project/qaas-python/)
41
+ [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
42
+ [![CI](https://github.com/allaabdella2-us/qa-multi-agent-system/actions/workflows/ci.yml/badge.svg)](https://github.com/allaabdella2-us/qa-multi-agent-system/actions/workflows/ci.yml)
43
+ [![Tests](https://img.shields.io/badge/tests-686%20offline-success)](#-contributing)
44
+ [![Built on](https://img.shields.io/badge/built%20on-Claude%20Agent%20SDK-D97757)](https://docs.claude.com/en/api/agent-sdk/overview)
45
+
46
+ [Quickstart](#-quickstart-in-60-seconds) · [Your repo](#-point-it-at-your-repository) · [Jira](#-file-into-jira) · [Architecture](ARCHITECTURE.md)
47
+
48
+ </div>
49
+
50
+ ---
51
+
52
+ Most "AI QA" tools generate tests. **This one behaves like a QA team.**
53
+
54
+ Fifteen agents, each with its own context, tool allowlist and budget, coordinated by
55
+ a state machine that is ordinary Python — because a model cannot enforce a budget
56
+ it is itself spending.
57
+
58
+ ```
59
+ DISCOVERY LOOP REMEDIATION LOOP
60
+ ┌──────────────────────────────────────┐ ┌───────────────────────────┐
61
+ │ MAPPER ─▶ API ─┐ │ │ FIXER ─▶ REVIEWER │
62
+ │ (system map) BROWSER ─┴─▶ REPRODUCER ─┼─▶ TRIAGE│ (fix) (review) │
63
+ │ (discover) (repro) │ (file)│ │
64
+ └──────────────────────────────┬───────┘ └──────────┬────────────────┘
65
+ │ │
66
+ ▼ ▼
67
+ [ TICKET ] ◀────────────── VERIFIER (verify)
68
+ ```
69
+
70
+ Nothing crosses between the loops except a ticket — which is also the audit trail.
71
+
72
+ ---
73
+
74
+ ## ✨ Why this one is different
75
+
76
+ | | |
77
+ |---|---|
78
+ | 🧠 **The orchestrator is code, not a prompt** | A model cannot enforce a budget it is spending. Phase ordering, concurrency, retries and the loop breakers live in `router.py`. That is also why **686 tests run offline, free, with no API key.** |
79
+ | 🧱 **Every agent is its own `query()`** | Not subagents of a shared parent. Each gets a real context boundary, an enforceable tool allowlist, and its own cost number. |
80
+ | 🔬 **Evidence or it did not happen** | `has_evidence()` and `is_fileable()` are methods on the envelope model, not requests in a prompt. An agent cannot talk its way past them. |
81
+ | 📊 **Measured, not asserted** | A deliberately buggy demo app ships with a golden ledger of **16 seeded defects + 4 planted non-defects**. `qaas score` reports recall *and* precision, so a prompt change has a number attached. |
82
+ | 🔒 **Merge is impossible by construction** | No merge method exists anywhere. `gh pr merge` is refused. Pull requests open as drafts. Shipping stays a human decision. |
83
+ | 🔍 **Every action is on the record** | 28 kinds of ledger event — every tool call, denial, verdict and escalation. `qaas trace` reads it back as a timeline. |
84
+
85
+ ---
86
+
87
+ ## 🤖 The roster
88
+
89
+ | agent | layer | what it does |
90
+ |---|---|---|
91
+ | 🗺️ MAPPER | map | services, routes, schema, ownership → the system map everything reads |
92
+ | 🏛️ ARCHITECT | discovery | circular deps, layering violations, god modules, dead code |
93
+ | 🔌 API | discovery | API contract drift, authz gaps, error-shape inconsistency |
94
+ | 🖱️ BROWSER | discovery | drives the UI through real journeys |
95
+ | 🗄️ DBA | discovery | schema constraints the code assumes and the database does not enforce |
96
+ | 🔒 AUDITOR | discovery | missing authorization, secrets, vulnerable dependencies, leaks |
97
+ | 📡 SOCKET | discovery | WebSocket auth, reconnect, ordering, backpressure |
98
+ | 🧭 GUIDE | discovery | whether a person can *find* a feature, not just whether it works |
99
+ | ⏱️ LOAD | discovery | N+1 queries, unindexed hot paths, unbounded results, bundle outliers |
100
+ | 🔨 REPRODUCER | triage | reproduces, minimises, measures flake, commits a failing test |
101
+ | 📝 TRIAGE | triage | dedupes, scores severity, routes, files — the only tracker writer |
102
+ | 🔧 FIXER | remediation | the minimal fix, on a branch |
103
+ | ⚖️ REVIEWER | remediation | adversarial review: APPROVE / REQUEST_CHANGES / ESCALATE |
104
+ | ✅ VERIFIER | verify | re-runs the original test → VERIFIED / NOT_FIXED / REGRESSED |
105
+ | 📊 REPORTER | reporting | what the run found, what recurred, and what it could not reach |
106
+
107
+ **ROUTER** is the sixteenth. It is the Python state machine rather than an
108
+ agent — a model cannot enforce a budget it is itself spending.
109
+
110
+ ---
111
+
112
+ ## 🚀 Quickstart in 60 seconds
113
+
114
+ ```bash
115
+ pip install qaas-python
116
+ ```
117
+
118
+ ```bash
119
+ cd ~/code/your-app
120
+ qaas init . # inspects the repo, writes + activates a target profile
121
+ qaas validate # config, prompts, allowlists ← no API call
122
+ qaas run --mode pr-check --dry-run # every agent's exact options ← no API call
123
+ ```
124
+
125
+ Or point it straight at a URL:
126
+
127
+ ```bash
128
+ qaas run --repo https://github.com/you/your-app --dry-run
129
+ ```
130
+
131
+ > [!TIP]
132
+ > Nothing above contacts an API. `--dry-run` prints exactly what each agent would
133
+ > receive — model, budget, turn cap, tool allowlist, prompt size.
134
+
135
+ **Auth:** the Claude Code CLI if you are signed in, otherwise `ANTHROPIC_API_KEY`.
136
+
137
+ ---
138
+
139
+ ## 🎯 Point it at your repository
140
+
141
+ ```bash
142
+ qaas init https://github.com/you/your-app # clones, inspects, writes a profile
143
+ qaas init ~/code/your-app --name your-app # or a local path
144
+ ```
145
+
146
+ `init` writes `.qaas/config/targets/<name>.yaml` **and activates it**. Every value
147
+ in it is a **guess you are expected to correct** — it reports what it detected and
148
+ what it could not find.
149
+
150
+ The load-bearing field is `environment.mode`:
151
+
152
+ | mode | meaning | what agents may do |
153
+ |---|---|---|
154
+ | 🔵 `none` | no running instance | read code, schema and spec only |
155
+ | 🟡 `external` | already running (staging, dev server) | read and exercise, **never** reset |
156
+ | 🟢 `compose` | qaas owns the lifecycle | seed, reset, tear down |
157
+
158
+ > [!NOTE]
159
+ > `none` is a perfectly good place to start, and where most first runs against a
160
+ > real repository begin. Findings stay honest about it: an agent that could not
161
+ > observe a behaviour says so and lowers its confidence.
162
+
163
+ **Credentials never live in the profile.** It names environment variables:
164
+
165
+ ```yaml
166
+ auth:
167
+ mode: login
168
+ login_endpoint: POST /api/v1/session
169
+ roles:
170
+ admin: { username: qa-admin@example.com, password_env: APP_ADMIN_PASSWORD }
171
+ viewer: { username: qa-viewer@example.com, password_env: APP_VIEWER_PASSWORD }
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 🎫 File into Jira
177
+
178
+ ```bash
179
+ export JIRA_BASE_URL=https://you.atlassian.net
180
+ export JIRA_EMAIL=you@example.com
181
+ export JIRA_API_TOKEN=... # an API token, not a password
182
+ export JIRA_PROJECT_KEY=QA
183
+
184
+ QAAS_TRACKER=jira qaas tracker-check # auth, project, permissions, workflow — creates nothing
185
+ QAAS_TRACKER=jira qaas run --mode nightly
186
+ ```
187
+
188
+ `tracker-check` validates credentials, confirms the project and issue type exist,
189
+ maps your workflow statuses, and prints the exact JSON it *would* POST. **It
190
+ creates nothing.**
191
+
192
+ Tired of four exports in every new shell? Put them in a `.env` — `.qaas/.env` is
193
+ already gitignored — and every command reads it. **Anything you export wins over
194
+ the file**, so a stale `.env` can never redirect a run.
195
+
196
+ - 🔁 **Dedupe across runs** — tickets carry a `qaas-fp-<fingerprint>` label, so the next run recognises an already-filed defect and increments its occurrence count instead of filing again.
197
+ - 🔐 **Security findings are refused** unless `JIRA_SECURITY_PROJECT_KEY` is set. A vulnerability in a project the whole company can read is a disclosure with no undo.
198
+
199
+ > [!TIP]
200
+ > Keep the committed backend `local` — it writes tickets as JSON under
201
+ > `.qaas/tickets/` so you can read what *would* be filed. Switch per shell with
202
+ > `QAAS_TRACKER=jira`.
203
+
204
+ ### 📌 A view per repository, made for you
205
+
206
+ Point it at a new repository and it provisions that repository's own Jira view
207
+ before the first agent starts — so there is something to watch *during* the run,
208
+ not a report afterwards.
209
+
210
+ ```console
211
+ $ QAAS_TRACKER=jira qaas run --repo https://github.com/acme/checkout.git --mode nightly
212
+ target: checkout (none)
213
+ filter created — https://you.atlassian.net/issues/?filter=10001
214
+ every ticket from this run carries the label repo-checkout
215
+ ```
216
+
217
+ Every ticket the system files carries `repo-<target>`, stamped in code rather
218
+ than asked of an agent. A **saved filter** over exactly that label is the
219
+ per-repository view, and on a company-managed project a **board** is built over
220
+ the filter too.
221
+
222
+ ```bash
223
+ qaas board # find or create this target's view
224
+ qaas board --no-create # show the label and JQL, touch nothing
225
+ ```
226
+
227
+ > [!NOTE]
228
+ > **Not a project per repository.** Creating a Jira project needs administrator
229
+ > rights a bot account rarely has, and a project per repository is unmanageable
230
+ > by the tenth one. A filter needs no special grant.
231
+ >
232
+ > **Not always a board, either.** Team-managed (next-gen) projects own their own
233
+ > board and cannot have a second one built over a filter — Jira's API will
234
+ > happily create one and give it no page in the UI. So the project's style is
235
+ > checked first, and on a team-managed project you get the filter alone. You are
236
+ > told which you got, and the link always opens. Point `JIRA_PROJECT_KEY` at a
237
+ > **company-managed** project and you get a real board per repository, with
238
+ > To Do / In Progress / Done.
239
+
240
+ Run it twice on the same repository and it **reuses** what is there. A run is
241
+ never failed over this: a run that found nine defects and could not make a view
242
+ has still done its job.
243
+
244
+ ---
245
+
246
+ ## 🔌 Bring your own MCP servers
247
+
248
+ Declare them in `system.yaml`. No Python to edit.
249
+
250
+ ```yaml
251
+ mcp_servers:
252
+ house-lint:
253
+ type: stdio
254
+ command: ./tools/lint-mcp
255
+ args: ["--strict"]
256
+ env: { LINT_TOKEN: "${ACME_LINT_TOKEN}" } # from the environment, never a literal
257
+ remote-docs:
258
+ type: http
259
+ url: https://mcp.example/v1
260
+ ```
261
+
262
+ Then add the name to any agent's `mcp_servers:` list. **Declaring a server grants
263
+ nothing** — an agent receives it only by naming it.
264
+
265
+ ```console
266
+ $ qaas validate
267
+ Declared MCP servers
268
+ ┃ name ┃ kind ┃ what it runs ┃ used by ┃
269
+ │ house-lint │ stdio │ ./tools/lint-mcp --strict │ MAPPER │
270
+ │ remote-docs │ http │ https://mcp.example/v1 │ nobody │
271
+ ```
272
+
273
+ > [!WARNING]
274
+ > A server's tools are allowed **wholesale** once an agent names it. qaas checks
275
+ > that the agent declared the server; it cannot inspect what a third-party
276
+ > server's tools actually do. **A server you declare is a server you trust.**
277
+
278
+ There is deliberately **no in-process Python server type** — a module path from a
279
+ config file would mean importing arbitrary code into the process holding your
280
+ Anthropic, Jira and GitHub credentials. Wrap it in a stdio entry point instead.
281
+
282
+ Two limits worth knowing: **6 MCP servers per agent** (tool-selection accuracy
283
+ falls off past ~7), and **FIXER is already at the cap** — the agent people most
284
+ want to extend.
285
+
286
+ ---
287
+
288
+ ## ✏️ Make the prompts yours
289
+
290
+ Agents are **a prompt plus a YAML file**. Both are yours to change.
291
+
292
+ ```bash
293
+ qaas prompts list # which prompt is in force, and where it came from
294
+ qaas prompts eject API # copy it to .qaas/prompts/ and edit freely
295
+ qaas prompts diff # what you changed vs. what shipped
296
+ ```
297
+
298
+ Prefer **adding** to replacing — drop a `API.append.md` beside it:
299
+
300
+ ```markdown
301
+ ## Our conventions
302
+ - Never file a finding without a curl reproduction.
303
+ - Treat any 500 on a write path as blocker severity.
304
+ ```
305
+
306
+ That block is inserted between the agent's prompt and the shared house rules, so
307
+ you keep receiving improvements to the base prompt instead of forking it forever.
308
+
309
+ ---
310
+
311
+ ## 🔍 Full traceability
312
+
313
+ Every tool call, denial, verdict and escalation is on the record.
314
+
315
+ ```console
316
+ $ qaas trace run-20260908T182034-c6ed26
317
+ t+ agent kind detail
318
+ 0s - run_started mode=nightly agents=[7]
319
+ 0s MAPPER agent_started model=claude-sonnet-5
320
+ 4s MAPPER tool_call ×34 Read×25, Glob×6, ToolSearch×2
321
+ 6s MAPPER denial tool=Bash reason=Bash is not in MAPPER's
322
+ tool allowlist (Read, Grep, Glob).
323
+ 146s MAPPER system_map version=20260907T233530 sections=[12]
324
+ 156s MAPPER agent_finished subtype=success num_turns=45
325
+ ```
326
+
327
+ ```bash
328
+ qaas trace <run-id> --follow # watch a run as it happens
329
+ qaas trace <run-id> --quiet # decisions only, no file reads
330
+ qaas trace <run-id> --agent verifier --kind verdict # filter
331
+ qaas trace <run-id> --json # export
332
+ qaas show <run-id> # mode, commit, tickets, escalations
333
+ qaas runs # everything that ever ran
334
+ ```
335
+
336
+ **Watch a run live.** `--follow` tails the ledger of a run in progress — start it
337
+ in a second terminal the moment a run begins, or even before, and it waits.
338
+
339
+ ```console
340
+ $ qaas trace run-20260909T163240-83b11c --follow --quiet
341
+ following run-20260909T163240-83b11c — ctrl-c to stop
342
+ 16:32:40 - run_started mode=pr-check agents=[8] target_sha=da19f406
343
+ 16:32:40 MAPPER agent_started model=claude-sonnet-5
344
+ 16:32:46 MAPPER denial tool=Bash reason=Bash is not in MAPPER's
345
+ tool allowlist (Read, Grep, Glob).
346
+ 16:36:11 ARCHITECT envelope severity=major domain=architecture
347
+ 16:41:03 TRIAGE ticket action=created key=QA-118 severity=major
348
+ ```
349
+
350
+ Drop `--quiet` to see every file the agents read, one line each. Combine with
351
+ `--agent` and `--kind` to watch one agent, or only the verdicts.
352
+
353
+ Runs are pinned to the **commit of the target** they examined, so a finding can
354
+ be replayed against the tree that produced it.
355
+
356
+ ---
357
+
358
+ ## 🛡️ Safety rails
359
+
360
+ Enforced in code, not requested in a prompt:
361
+
362
+ | rail | what it does |
363
+ |---|---|
364
+ | 📁 **Path scoping** | Writes checked against that agent's `write_paths`. Most agents cannot write at all. |
365
+ | 🌿 **Branch scoping** | Git writes must match the agent's patterns (`qa/repro/*`, `fix/*`). `main` and force-push refused outright. |
366
+ | ⛔ **Forbidden classes** | Migrations, auth, payment, secrets, infrastructure, CI — stop at a human however small the change looks. |
367
+ | 🎟️ **Ticket rate limit** | Over the per-run cap the call is denied and the router escalates rather than filing. |
368
+ | 🧪 **Immutable test** | The agent fixing a defect may not edit the test that defines it. |
369
+ | 🚫 **No filesystem settings** | `setting_sources=[]` — a repository qaas is inspecting cannot inject settings, hooks or MCP servers into the process running it. |
370
+
371
+ Denials return a reason and are logged; they never kill the turn. The agent reads
372
+ the refusal and adapts.
373
+
374
+ ---
375
+
376
+ ## 📈 How you know it works
377
+
378
+ `qaas` ships with a **deliberately buggy demo app** and a golden ledger recording
379
+ every defect seeded into it — plus **planted non-defects**: correct-but-suspicious
380
+ code that a careless reader would report.
381
+
382
+ ```bash
383
+ cd target-app && docker compose up -d
384
+ qaas run --mode nightly && qaas score
385
+ ```
386
+
387
+ `qaas score` reports recall, precision and severity agreement against that
388
+ ledger. That matters more than any number this page could print: it means a
389
+ change to a prompt, a threshold or a model has **a measurement attached** rather
390
+ than an opinion.
391
+
392
+ > [!CAUTION]
393
+ > **Seeded defects are easier than real ones**, and this system was calibrated
394
+ > against them. A benchmark shows the loop works end to end and does not spray
395
+ > false positives. It does not show that it will find the hard bug in your
396
+ > codebase. Run it on something you know well and judge it on what it finds
397
+ > there.
398
+
399
+ ---
400
+
401
+ ## 🤝 Contributing
402
+
403
+ ```bash
404
+ git clone https://github.com/allaabdella2-us/qa-multi-agent-system
405
+ cd qa-multi-agent-system
406
+ uv venv && uv pip install -e ".[dev]"
407
+
408
+ pytest # 686 tests, offline, free — keep it that way
409
+ pytest -m docker # needs: cd target-app && docker compose up -d
410
+ qaas validate
411
+ ```
412
+
413
+ The `llm`, `docker`, `github` and `jira` markers are deselected by default.
414
+ **A CI run that costs money is a CI run people switch off.**
415
+
416
+ > [!IMPORTANT]
417
+ > If you change a seeded defect in `target-app/`, retire its ledger entry with
418
+ > `fixed_in:` in the same commit — a stale ledger silently corrupts every score.
419
+
420
+ New to the codebase? [`ARCHITECTURE.md`](ARCHITECTURE.md) explains the entry
421
+ point, the five phases, what moves between agents, and what the guardrails stop.
422
+
423
+ ---
424
+
425
+ <div align="center">
426
+
427
+ **MIT licensed** · [LICENSE](LICENSE)
428
+
429
+ </div>
@@ -0,0 +1,96 @@
1
+ qaas/cli.py,sha256=Zga6KkYUUzRYtq1GAvLl3CkEIrj7gzKzwYuDGVAKUDc,74066
2
+ qaas/config.py,sha256=1DvhwGJuA5Ute8rRKHYBBmYy82wmXrdTl1GxeZpW4To,17576
3
+ qaas/discover.py,sha256=0bfpIfgRlvcxVb2mAvcrcOK4MW5Q5RnbjspNMk-42rE,9311
4
+ qaas/envelope.py,sha256=Dh6h7MqktwOFlKswBqmQUOfCvwQCFNOJ4k8ACbCUtY8,10771
5
+ qaas/envfile.py,sha256=f3RD7UxACxJS_-NExExBCbvAe7v8QnD3EgvLaNl1zD4,4443
6
+ qaas/guardrails.py,sha256=RIupEr6VuH32DD6SpDAM-cIza1HgbUn0di6D2YI-QXU,26277
7
+ qaas/paths.py,sha256=98GZkN6KzAa-sTpbMcIpyMUM8Bh3H4JbI3tZLks7juc,12718
8
+ qaas/registry.py,sha256=qMmvAor0ARE-UkRWS6EJrN_XdZVdpfzQFDDNmCOMyJo,21275
9
+ qaas/router.py,sha256=roxGZXyb5TjBfnU24OozHZkJqb9NpU0Hawsg0zrNjOs,25893
10
+ qaas/runner.py,sha256=vZ1oJpfNN9L7DQhw8p8GzL8rYSM3uDnym-NM2gG2FV0,8496
11
+ qaas/scorecard.py,sha256=_IeG1iTIIk3M4o8ZT8eSY4BxbZPCSX_AmG3-22UxqFY,17065
12
+ qaas/sdk_compat.py,sha256=ftE6PK0jZY85zkYqS7UJTGYwRkYDlH4NspiKbKVfVXQ,1678
13
+ qaas/store.py,sha256=U998R3C8rZJSSFZmOxcMeEzAYseT5Du6AhJtYUKn5nY,12943
14
+ qaas/target.py,sha256=RGFRAKFl5Nqtnj5IwLl5delDIBaeUYjps4WmadbAlQ8,11770
15
+ qaas/tasks.py,sha256=YcGGZqoSrhXkxwXR8VVH7VMJ_TThsnPViIdIM3TJk98,18662
16
+ qaas/trace.py,sha256=xVN8OkXXgBpY1mQxHBmPS_89hCcFQX3dVjhkDeEpZ1o,14402
17
+ qaas/adapters/__init__.py,sha256=bw2pqtDqhZGP730gwV28BJ-8TF-rhanwCEjdIizjP6A,882
18
+ qaas/adapters/tracker.py,sha256=4qvDFKkFU-ICzmn10MIKjAr9XUAWUwGg9S2RrFt8-PE,74803
19
+ qaas/adapters/vcs.py,sha256=n-jVvugcH4uZ90ZwXllLmDRF7CmLe-gI1Y_fszI8NJU,23055
20
+ qaas/defaults/config/system.yaml,sha256=OnAIOmHOAYwd6vjjPgmPB-dRJLZaRtkC7dxjw1mncz8,2739
21
+ qaas/defaults/config/agents/api.yaml,sha256=GK_O3sffZoIWkL86kMXT9B0tGhTOYrTSjNtp2vyfrYE,700
22
+ qaas/defaults/config/agents/architect.yaml,sha256=L8oUF4kzUxEE63k0wJ7ieZnqZhw6bLMf3lJzdMl0Cww,968
23
+ qaas/defaults/config/agents/auditor.yaml,sha256=quprfnaC_QsxwTCl_fAEoRaWSdcL3RZQkWPqDOl5aqs,763
24
+ qaas/defaults/config/agents/browser.yaml,sha256=OQOo1mN9LBiKsH7d78Kon3J5fw7OwAz7UjodU8XtuiA,512
25
+ qaas/defaults/config/agents/dba.yaml,sha256=-VczoaI2TjfGaP2HP-rw9sX2aDpegftMGyFjikvkon0,771
26
+ qaas/defaults/config/agents/fixer.yaml,sha256=vRXawC3lVWDpyz6WiPjcT2tYn_BoitROE7jec-hDgaI,2164
27
+ qaas/defaults/config/agents/guide.yaml,sha256=pydlc5uNwPG8zSGUSc-vqDhMI0zY6easdLmvDXMBDSM,1022
28
+ qaas/defaults/config/agents/load.yaml,sha256=ralEW-NQhZtxid03Q03_eSMzPyN9kTQK8dgKSfM6uBI,1105
29
+ qaas/defaults/config/agents/mapper.yaml,sha256=tDXOd4xJogK6U8qRsOeMs1C-2hiiUYfurNmRj5d1P_8,740
30
+ qaas/defaults/config/agents/reporter.yaml,sha256=RqicXSQv19UuRLL5pAnJ_WBDNV7QHBdh8nlOBI1FbLM,672
31
+ qaas/defaults/config/agents/reproducer.yaml,sha256=aoW2oajiRJ_s2kiV2fhEslMmV-bK7Avjfq5CltQ6MwI,874
32
+ qaas/defaults/config/agents/reviewer.yaml,sha256=qOKIOXn64Gq5x3bV9bKYigSqMQx8pmRMAMYTN1iTJDI,719
33
+ qaas/defaults/config/agents/socket.yaml,sha256=GGGVx2_DPq7cnPwz4ta1-AhlThWCAtk4GHv2uUEdiTY,1051
34
+ qaas/defaults/config/agents/triage.yaml,sha256=jLjljOHG564-fLZzmYq1wSz10vW9AVmgdys_rSLgo3M,750
35
+ qaas/defaults/config/agents/verifier.yaml,sha256=urRQ2cGjUx99YFkKNg6wjGrlEGiFlliHLy0_qL3mkAU,839
36
+ qaas/mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ qaas/mcp/context.py,sha256=UtrJdG3USVbfzFzQVK9ZIdxz3CL0bHV9n8uH_IU6Juo,2951
38
+ qaas/mcp/contract_diff.py,sha256=HcSB991oRSh9Z9Aii1yQdx7ZRfv13zkb1tlnFsT_Zjc,47843
39
+ qaas/mcp/defect_memory.py,sha256=IFs6s0zYjUv6KvCaaXNgnQn9HAl8y-zDFVCxeWkEwuM,19829
40
+ qaas/mcp/env_control.py,sha256=prpmsseF9aHr8n9kI3f9ujLO4m9hUACR5uNz6Bcm4uY,39709
41
+ qaas/mcp/envelope_server.py,sha256=Ov_Srkr1GVYWfb9WSzuW5b4dYwyVF0cpO6yMm0wPZhE,20403
42
+ qaas/mcp/test_runner.py,sha256=b3sJft_JZ2nmnGjKvWSO-FNLykrC98T_M7C7csxlnzY,33875
43
+ qaas/mcp/tracker.py,sha256=W90TrlRTD7T7t9SDv0fCFRIe_hPfL8IZr5UGQtGoelM,18645
44
+ qaas/mcp/vcs.py,sha256=taQWXfT7k72SLeRmAETGb4z3t63uAn46CPib_ZALGVo,20945
45
+ qaas/plugin/.claude-plugin/plugin.json,sha256=XbzYID6aMD3dVPvJxOP9X_0iJR5isqIfKgGkZmn38BU,263
46
+ qaas/plugin/skills/a11y-audit/SKILL.md,sha256=hTpKJkKTYqxkl2kQRqHrsKU1YfhntilzCykkToBnWyY,2634
47
+ qaas/plugin/skills/adversarial-review/SKILL.md,sha256=uUnKy6xvNfse5EMlU072ycYN6c2rHA-LNXOOJW73PRI,8582
48
+ qaas/plugin/skills/api-surface-extraction/SKILL.md,sha256=5RHGdz4uh0Qez-pcGvCIeSwRAcNDo0KhITqg22pRawA,2349
49
+ qaas/plugin/skills/authz-matrix-check/SKILL.md,sha256=eObh1VTxGrASneSVBKVavIw7uRzWtnAluJRJyT0s8cY,2822
50
+ qaas/plugin/skills/console-error-triage/SKILL.md,sha256=mh5B7tEtLh--2XDdYZWsERE0ojBv8O0greZvr_RzBiI,2221
51
+ qaas/plugin/skills/contract-test-generation/SKILL.md,sha256=n31bPqI88LzOoGvNtyKA20r6qHRUwT69qAoP-LfA19U,2180
52
+ qaas/plugin/skills/dedupe-strategy/SKILL.md,sha256=mMJ1rcQJ88orWwscNQUFI4i3c830n2-d05C4AKF3y7U,2644
53
+ qaas/plugin/skills/environment-pinning/SKILL.md,sha256=NT0nrWiU6TCcmhP4RMre5UhSSP9bmWuTnfyJM03suEI,1890
54
+ qaas/plugin/skills/error-taxonomy/SKILL.md,sha256=ixnkavgU-br48vQwBhC8elc8nN4lNBQ7mtKzcveg3qY,2574
55
+ qaas/plugin/skills/exploratory-ui-walk/SKILL.md,sha256=NDJn3MQ1E-JgLd09PKhUkCxHo8amFtmEJ2YLYpgDzBI,2454
56
+ qaas/plugin/skills/failing-test-authoring/SKILL.md,sha256=QGPZGDrRR1yvhFk2rokegtDdWtnCTkouFhuMaktwQF8,2158
57
+ qaas/plugin/skills/flake-detection/SKILL.md,sha256=2iDjsfc4xHpgpBfOYx9zbubDoX6XdBJAB0U1W8budOg,2333
58
+ qaas/plugin/skills/form-state-probe/SKILL.md,sha256=IocxBbUr0ATjwWbmTQVN8LU5oBelLJLlLJaGsBRDDQ8,2124
59
+ qaas/plugin/skills/minimal-diff-discipline/SKILL.md,sha256=_e-mhkhBv5j2_FY3XjwtO5dP-aVsWtU-sGcua907gt8,5896
60
+ qaas/plugin/skills/openapi-diff/SKILL.md,sha256=aaJmSGxbLlPy8JI9w09P67p0AzlQbM3lAjYNh3gFi4I,2641
61
+ qaas/plugin/skills/ownership-resolution/SKILL.md,sha256=s1gFLr3ItSKqlN6pN01QaxaXduXxWx5BXdr1CqMRlRY,1897
62
+ qaas/plugin/skills/product-task-graph/SKILL.md,sha256=7Q_3fdx4FCKG9qcFLaukOT6QWzs95OTe5ESFZBCXp7g,2349
63
+ qaas/plugin/skills/regression-risk-scoring/SKILL.md,sha256=ILhCKakqcJym_EtZWC3bFMnmnrEpLRVZk-MJfyh4dfc,6149
64
+ qaas/plugin/skills/regression-suite-selection/SKILL.md,sha256=c23I-9DZiP5zRozPitSJe_ekBSkfwL-krbTbnPoUs_U,2241
65
+ qaas/plugin/skills/repo-cartography/SKILL.md,sha256=CIK0Vr9rCuW74og-X8Tsc9bJYW_zOgQS4rGqFP3OMnI,2343
66
+ qaas/plugin/skills/repro-minimisation/SKILL.md,sha256=U-I380BAaiQ-qfXjPUy0j0zTEcNr5WI1iVgj8t7UF4Q,2418
67
+ qaas/plugin/skills/rollback-plan-authoring/SKILL.md,sha256=6kJ2i2ujSQBiu1IR7yKK2gkBV5JyTvSbRIrzOZfHkDM,5640
68
+ qaas/plugin/skills/root-cause-vs-symptom/SKILL.md,sha256=BcEwV9295gWmX0XIeJFL3lxy7ME1tLXQlW24wJxmbwA,7319
69
+ qaas/plugin/skills/routing-rules/SKILL.md,sha256=8v8pJZLGPyM8rXIWpfXpSb5JDCdDNLk5TxLtIt0KSqI,2306
70
+ qaas/plugin/skills/severity-rubric/SKILL.md,sha256=xR9UuClh8tDY9mEGapP6Uagnn-PqQuRX3YsCSZRaki4,3399
71
+ qaas/plugin/skills/test-first-fix/SKILL.md,sha256=7dfTBNJfi9qCGxhGVtsUCMVgAp8MiNWMn1xGHj4-2uM,5748
72
+ qaas/plugin/skills/test-quality-audit/SKILL.md,sha256=hbmzFq57j8g2qa4I4Vp8RHxwQv-BZMYsBRIjPg-fu7k,6434
73
+ qaas/plugin/skills/ticket-writer/SKILL.md,sha256=Ira6tvQDgdQ5rY-ggauE03DZFwhFkaNp1xMHXJ541a4,2414
74
+ qaas/plugin/skills/verdict-reporting/SKILL.md,sha256=y3un7-yns_dojK1YYpGaQhXyid44M8Zb8vCwgGSH9gA,1998
75
+ qaas/plugin/skills/verification-protocol/SKILL.md,sha256=6ixQO7GBbyA_fK8CCeyUmPr2Tu_b3avoSG8WfzIyGFs,2455
76
+ qaas/prompts/API.md,sha256=JiucVPX48qNtzXaIPXD3l7e6S5l01vO5I-WuNXbEjlQ,2245
77
+ qaas/prompts/ARCHITECT.md,sha256=vbIt6M375EBiS8vvXWyccccVzDaWsfhFaJluoyDJB5c,4308
78
+ qaas/prompts/AUDITOR.md,sha256=L2zxAf83l0yemmJMWyaRkU1H3kKwfCFPsLHKkS1HQ_E,2945
79
+ qaas/prompts/BROWSER.md,sha256=0LY0KhKNSbL29ytSgtEgFDIn5Ga8exB1jTyfom-BJDY,2220
80
+ qaas/prompts/DBA.md,sha256=DD9R6xaGRNdXMmzSd3yCAzPm01avdHLnV78IvmgfACw,2906
81
+ qaas/prompts/FIXER.md,sha256=6LtaKV2ub9II2eb-V9zsvOU_JIZYlblvS3x-FLotHyM,2920
82
+ qaas/prompts/GUIDE.md,sha256=4g59-7Oq0mutM7UTSpJ-N3pskka5xQ8fmkLVunTj7fk,5137
83
+ qaas/prompts/LOAD.md,sha256=C2GwDHHqGAqQqDe23IGpIjGn6qsZh_2bP7Tw98omgLA,5888
84
+ qaas/prompts/MAPPER.md,sha256=Lae1zNa9Hqpmqa2N1mO3VGOqi9rX9HN4DP-h15aqmcA,2220
85
+ qaas/prompts/REPORTER.md,sha256=HaPSHxIC89-lLjMtWfUhekhLdyb8tlLuXe8gNtnVIgY,3067
86
+ qaas/prompts/REPRODUCER.md,sha256=w9vDg6MH8-D1FQr46NpjSK7ejL1G8UTJVNW2WdLcpEc,2274
87
+ qaas/prompts/REVIEWER.md,sha256=A3MjFE7VQgDoc0TqjIQUgHAdKy5HBH9za3gU1wLAGpk,2523
88
+ qaas/prompts/SOCKET.md,sha256=3Wr7mt6t0zpj546ZCFXd4iC61SYh9Dlgi9St1bM4-n4,5488
89
+ qaas/prompts/TRIAGE.md,sha256=VSL7jc89wTrSY8SiX0zmRy9d9gunCBT4c2cE8Aoei_c,2112
90
+ qaas/prompts/VERIFIER.md,sha256=AwvggnzNbb3DiVjoaWNWzV593LY5_qYApENQpXGS938,2034
91
+ qaas/prompts/_shared.md,sha256=lN_s_rAmakhGuyRuWItC--iyy-Er6ohT_dzGeE_g-fo,2620
92
+ qaas_python-0.0.1.dist-info/METADATA,sha256=gTGbEtVxkE-nAnFD_6b0_J9ovsKCplW_o50gNAoDO0I,18909
93
+ qaas_python-0.0.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
94
+ qaas_python-0.0.1.dist-info/entry_points.txt,sha256=6UScfruyhP9N_xGx3tXJGkaoAiB36dkINuKyOH6OkK4,38
95
+ qaas_python-0.0.1.dist-info/licenses/LICENSE,sha256=pHWke5oMtv7PLjIQbN6hRa31J0AKj51VCd5TCTUbbX0,1069
96
+ qaas_python-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ qaas = qaas.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alla Abdella
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.