qaas-python 0.3.2__tar.gz → 1.0.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 (168) hide show
  1. {qaas_python-0.3.2 → qaas_python-1.0.0}/ARCHITECTURE.md +10 -3
  2. {qaas_python-0.3.2 → qaas_python-1.0.0}/CLAUDE.md +40 -2
  3. {qaas_python-0.3.2 → qaas_python-1.0.0}/PKG-INFO +68 -17
  4. {qaas_python-0.3.2 → qaas_python-1.0.0}/README.md +67 -16
  5. {qaas_python-0.3.2 → qaas_python-1.0.0}/pyproject.toml +1 -1
  6. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/adapters/tracker.py +348 -1
  7. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/cli.py +183 -2
  8. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/discover.py +15 -0
  9. qaas_python-1.0.0/src/qaas/envfile.py +92 -0
  10. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/tracker.py +8 -0
  11. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/target.py +1 -0
  12. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/trace.py +74 -2
  13. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/adapters/test_jira_tracker.py +261 -0
  14. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/conftest.py +12 -0
  15. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_cli.py +1 -0
  16. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_discover.py +26 -0
  17. qaas_python-1.0.0/tests/test_envfile.py +101 -0
  18. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_trace.py +83 -0
  19. {qaas_python-0.3.2 → qaas_python-1.0.0}/.gitignore +0 -0
  20. {qaas_python-0.3.2 → qaas_python-1.0.0}/BUILD_PLAN.md +0 -0
  21. {qaas_python-0.3.2 → qaas_python-1.0.0}/LICENSE +0 -0
  22. {qaas_python-0.3.2 → qaas_python-1.0.0}/config/targets/corvid.yaml +0 -0
  23. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/adapters/__init__.py +0 -0
  24. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/adapters/vcs.py +0 -0
  25. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/conductor.py +0 -0
  26. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/config.py +0 -0
  27. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/arbiter.yaml +0 -0
  28. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/cartographer.yaml +0 -0
  29. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/chronicle.yaml +0 -0
  30. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/clerk.yaml +0 -0
  31. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/conduit.yaml +0 -0
  32. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/forge.yaml +0 -0
  33. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/gauge.yaml +0 -0
  34. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/keystone.yaml +0 -0
  35. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/mender.yaml +0 -0
  36. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/proof.yaml +0 -0
  37. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/pulse.yaml +0 -0
  38. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/surface.yaml +0 -0
  39. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/usher.yaml +0 -0
  40. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/vault.yaml +0 -0
  41. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/agents/warden.yaml +0 -0
  42. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/defaults/config/system.yaml +0 -0
  43. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/envelope.py +0 -0
  44. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/guardrails.py +0 -0
  45. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/__init__.py +0 -0
  46. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/context.py +0 -0
  47. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/contract_diff.py +0 -0
  48. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/defect_memory.py +0 -0
  49. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/env_control.py +0 -0
  50. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/envelope_server.py +0 -0
  51. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/test_runner.py +0 -0
  52. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/mcp/vcs.py +0 -0
  53. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/paths.py +0 -0
  54. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/.claude-plugin/plugin.json +0 -0
  55. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/a11y-audit/SKILL.md +0 -0
  56. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/adversarial-review/SKILL.md +0 -0
  57. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/api-surface-extraction/SKILL.md +0 -0
  58. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/authz-matrix-check/SKILL.md +0 -0
  59. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/console-error-triage/SKILL.md +0 -0
  60. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/contract-test-generation/SKILL.md +0 -0
  61. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/dedupe-strategy/SKILL.md +0 -0
  62. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/environment-pinning/SKILL.md +0 -0
  63. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/error-taxonomy/SKILL.md +0 -0
  64. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/exploratory-ui-walk/SKILL.md +0 -0
  65. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/failing-test-authoring/SKILL.md +0 -0
  66. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/flake-detection/SKILL.md +0 -0
  67. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/form-state-probe/SKILL.md +0 -0
  68. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/minimal-diff-discipline/SKILL.md +0 -0
  69. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/openapi-diff/SKILL.md +0 -0
  70. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/ownership-resolution/SKILL.md +0 -0
  71. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/product-task-graph/SKILL.md +0 -0
  72. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/regression-risk-scoring/SKILL.md +0 -0
  73. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/regression-suite-selection/SKILL.md +0 -0
  74. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/repo-cartography/SKILL.md +0 -0
  75. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/repro-minimisation/SKILL.md +0 -0
  76. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/rollback-plan-authoring/SKILL.md +0 -0
  77. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/root-cause-vs-symptom/SKILL.md +0 -0
  78. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/routing-rules/SKILL.md +0 -0
  79. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/severity-rubric/SKILL.md +0 -0
  80. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/test-first-fix/SKILL.md +0 -0
  81. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/test-quality-audit/SKILL.md +0 -0
  82. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/ticket-writer/SKILL.md +0 -0
  83. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/verdict-reporting/SKILL.md +0 -0
  84. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/plugin/skills/verification-protocol/SKILL.md +0 -0
  85. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/ARBITER.md +0 -0
  86. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/CARTOGRAPHER.md +0 -0
  87. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/CHRONICLE.md +0 -0
  88. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/CLERK.md +0 -0
  89. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/CONDUIT.md +0 -0
  90. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/FORGE.md +0 -0
  91. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/GAUGE.md +0 -0
  92. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/KEYSTONE.md +0 -0
  93. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/MENDER.md +0 -0
  94. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/PROOF.md +0 -0
  95. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/PULSE.md +0 -0
  96. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/SURFACE.md +0 -0
  97. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/USHER.md +0 -0
  98. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/VAULT.md +0 -0
  99. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/WARDEN.md +0 -0
  100. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/prompts/_shared.md +0 -0
  101. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/registry.py +0 -0
  102. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/runner.py +0 -0
  103. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/scorecard.py +0 -0
  104. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/sdk_compat.py +0 -0
  105. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/store.py +0 -0
  106. {qaas_python-0.3.2 → qaas_python-1.0.0}/src/qaas/tasks.py +0 -0
  107. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/CODEOWNERS +0 -0
  108. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/Dockerfile +0 -0
  109. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/__init__.py +0 -0
  110. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/auth.py +0 -0
  111. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/config.py +0 -0
  112. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/db.py +0 -0
  113. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/errors.py +0 -0
  114. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/main.py +0 -0
  115. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/models.py +0 -0
  116. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/routes/__init__.py +0 -0
  117. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/routes/auth.py +0 -0
  118. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/routes/invoices.py +0 -0
  119. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/routes/orders.py +0 -0
  120. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/routes/stream.py +0 -0
  121. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/app/schemas.py +0 -0
  122. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/migrations/001_init.sql +0 -0
  123. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/pyproject.toml +0 -0
  124. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/api/seed/fixtures.sql +0 -0
  125. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/defects.yaml +0 -0
  126. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/docker-compose.yml +0 -0
  127. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/openapi.yaml +0 -0
  128. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/.gitignore +0 -0
  129. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/Dockerfile +0 -0
  130. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/index.html +0 -0
  131. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/package-lock.json +0 -0
  132. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/package.json +0 -0
  133. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/api.ts +0 -0
  134. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/components/Button.tsx +0 -0
  135. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/components/Layout.tsx +0 -0
  136. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/components/SearchInput.tsx +0 -0
  137. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/main.tsx +0 -0
  138. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/routes/CheckoutReview.tsx +0 -0
  139. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/routes/Login.tsx +0 -0
  140. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/routes/NewOrder.tsx +0 -0
  141. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/routes/OrderDetail.tsx +0 -0
  142. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/routes/OrdersList.tsx +0 -0
  143. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/src/styles.css +0 -0
  144. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/tsconfig.json +0 -0
  145. {qaas_python-0.3.2 → qaas_python-1.0.0}/target-app/web/vite.config.ts +0 -0
  146. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/adapters/test_github_vcs.py +0 -0
  147. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/conftest.py +0 -0
  148. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/test_contract_diff.py +0 -0
  149. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/test_defect_memory.py +0 -0
  150. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/test_env_control.py +0 -0
  151. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/test_test_runner.py +0 -0
  152. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/test_tracker.py +0 -0
  153. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/mcp/test_vcs.py +0 -0
  154. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/support.py +0 -0
  155. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/target_app/test_seeded_defects.py +0 -0
  156. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_conductor.py +0 -0
  157. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_config.py +0 -0
  158. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_envelope.py +0 -0
  159. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_guardrails.py +0 -0
  160. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_hooks_and_skills.py +0 -0
  161. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_paths.py +0 -0
  162. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_prompt_overrides.py +0 -0
  163. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_registry.py +0 -0
  164. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_scorecard.py +0 -0
  165. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_skills_actually_load.py +0 -0
  166. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_store.py +0 -0
  167. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_target_profile_is_honoured.py +0 -0
  168. {qaas_python-0.3.2 → qaas_python-1.0.0}/tests/test_user_mcp_servers.py +0 -0
@@ -301,21 +301,28 @@ wrong:
301
301
  **Nothing in `tasks.py` or a prompt may name a specific application.** A prompt
302
302
  that mentions one repo's layout or one app's seeded users works exactly once.
303
303
 
304
- ### The eight agents
304
+ ### The sixteen agents
305
305
 
306
306
  | agent | layer | does |
307
307
  |---|---|---|
308
308
  | CARTOGRAPHER | map | services, routes, schema, ownership → `system-map.json` |
309
+ | KEYSTONE | discovery | circular deps, layering violations, god modules, dead code |
309
310
  | CONDUIT | discovery | API contract drift; ships a failing contract test |
310
311
  | SURFACE | discovery | drives the UI through real journeys |
312
+ | VAULT | discovery | schema constraints the code assumes and the database does not enforce |
313
+ | WARDEN | discovery | missing authorization, secrets, vulnerable dependencies, leaked internals |
314
+ | PULSE | discovery | WebSocket auth, reconnect, ordering, backpressure |
315
+ | USHER | discovery | whether a person can *find* a feature, not just whether it works |
316
+ | GAUGE | discovery | N+1 queries, unindexed hot paths, unbounded results, bundle outliers |
311
317
  | FORGE | triage | reproduces, minimises, measures flake, commits a failing test |
312
318
  | CLERK | triage | dedupes, scores severity, routes, files — the only tracker writer |
313
319
  | MENDER | remediation | the minimal fix, on a `fix/*` branch |
314
320
  | ARBITER | remediation | adversarial review: APPROVE / REQUEST_CHANGES / ESCALATE |
315
321
  | PROOF | verify | re-runs the original test → VERIFIED / NOT_FIXED / REGRESSED |
322
+ | CHRONICLE | reporting | what the run found, what recurred, and what it could not reach |
316
323
 
317
- (The design doc names 16. Eight are built; CONDUCTOR is the Python state machine
318
- rather than an agent; seven Phase-2 agents are not built.)
324
+ CONDUCTOR is the sixteenth. It is the Python state machine in `conductor.py`
325
+ rather than an agent, because a model cannot enforce a budget it is spending.
319
326
 
320
327
  ---
321
328
 
@@ -17,7 +17,7 @@ first, and update the plan's milestone table when work lands.
17
17
  uv venv && uv pip install -e ".[dev]" # setup
18
18
  npx playwright install chromium # only for UI (SURFACE) runs
19
19
 
20
- pytest # 649 tests, no API calls, no network
20
+ pytest # 686 tests, no API calls, no network
21
21
  pytest tests/test_guardrails.py::test_name -x
22
22
  pytest -m docker # needs target-app running
23
23
  pytest -m 'llm or github or jira' # tiers excluded by default in pyproject
@@ -27,6 +27,8 @@ qaas doctor --target corvid # what a target makes possible
27
27
  qaas run --mode pr-check --dry-run # renders each agent's options, no API call
28
28
  qaas run --mode nightly --only CONDUIT # real run, costs money
29
29
  qaas runs / qaas show <run-id> / qaas map
30
+ qaas trace <run-id> --follow --quiet # watch a live run's decisions
31
+ qaas board # find-or-create this target's Jira board
30
32
  qaas trace <run-id> [--agent NAME] [--kind KIND] [--json] # the ledger, readably
31
33
  qaas score [<run-id>] # recall/precision against the golden ledger
32
34
  qaas sweep # run + score + fail below the precision gate
@@ -139,6 +141,39 @@ one stdio subprocess, declared in `registry.STDIO_SERVERS`.
139
141
  Tool results use `ok()`/`err()` from `mcp/context.py`: errors are **returned, not
140
142
  raised**, so the agent reads the reason and corrects itself.
141
143
 
144
+ ### One Jira view per repository, not one project
145
+
146
+ Every ticket carries `repo-<target>`, stamped by `mcp/tracker.py` rather than
147
+ asked of CLERK. `JiraTracker.ensure_repo_board` finds-or-creates a saved filter
148
+ over exactly that label, plus a board over the filter **only where one can
149
+ render**; `cli._ensure_board` calls it at the top of every Jira-backed run. A
150
+ *project* per repo would need admin rights a bot account rarely has; a filter
151
+ needs none.
152
+
153
+ **A 200 from the board API is not a working board.** Team-managed (next-gen)
154
+ projects own their board; `POST /rest/agile/1.0/board` over a filter still
155
+ returns 201, and the UI has no page for the result — every candidate URL 404s.
156
+ `is_team_managed` is the authoritative gate and skips the attempt there.
157
+ `_board_is_reachable` (no `location` -> unusable) is a *second, weaker* check
158
+ applied **only to a board that already existed**: Jira populates `location`
159
+ asynchronously, so a board read back immediately after creation reports None
160
+ whatever its project, and gating a fresh board on it rejected good boards.
161
+ Location is necessary, not sufficient — a team-managed board eventually reports
162
+ one and still will not render.
163
+
164
+ `board_url` never assembles a URL: `/secure/RapidBoard.jspa?rapidView=<id>` is
165
+ followed and whatever Jira resolves it to is the answer (a company-managed
166
+ board's path carries a `/c/` segment that a hand-built URL missed).
167
+
168
+ **A reused filter is only the right filter if its JQL still matches.** Filters
169
+ are found by name and the name does not encode the project, so repointing
170
+ `JIRA_PROJECT_KEY` left the filter scoped to the old project — tickets filed
171
+ correctly and were invisible on the view. `ensure_repo_board` repairs the JQL;
172
+ `filter/search` is expanded with `jql` so the check costs no extra round trip.
173
+
174
+ None of this can fail a run — the filter is the fallback and the findings matter
175
+ more than the view.
176
+
142
177
  ### Targets make it portable
143
178
 
144
179
  `target.py` / `config/targets/*.yaml`. `environment.mode` is the load-bearing
@@ -164,7 +199,10 @@ two sets of rules about where someone else's code lands on disk.
164
199
 
165
200
  ### Runtime state
166
201
 
167
- `.qaas/` (gitignored): `runs/<id>/ledger.jsonl` (append-only audit trail —
202
+ `.qaas/` (gitignored): `.env` (credentials, read before every command; anything
203
+ already exported wins, and `QAAS_ENV_FILE=` disables the whole mechanism — the
204
+ test suite sets that so a developer's `.env` cannot make the suite pass);
205
+ `runs/<id>/ledger.jsonl` (append-only audit trail —
168
206
  every tool call, denial and escalation), `envelopes/`, `artifacts/`, `results/`;
169
207
  plus a versioned `system-map/` shared across runs and pinned per run so a bad map
170
208
  cannot half-propagate. Evidence is referenced by `artifact://<run>/<name>` uris;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: qaas-python
3
- Version: 0.3.2
3
+ Version: 1.0.0
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
@@ -40,7 +40,7 @@ Description-Content-Type: text/markdown
40
40
  [![Python](https://img.shields.io/pypi/pyversions/qaas-python?color=3776AB&logo=python&logoColor=white)](https://pypi.org/project/qaas-python/)
41
41
  [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
42
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-649%20offline-success)](#-contributing)
43
+ [![Tests](https://img.shields.io/badge/tests-686%20offline-success)](#-contributing)
44
44
  [![Built on](https://img.shields.io/badge/built%20on-Claude%20Agent%20SDK-D97757)](https://docs.claude.com/en/api/agent-sdk/overview)
45
45
 
46
46
  [Quickstart](#-quickstart-in-60-seconds) · [Your repo](#-point-it-at-your-repository) · [Jira](#-file-into-jira) · [Architecture](ARCHITECTURE.md)
@@ -51,7 +51,7 @@ Description-Content-Type: text/markdown
51
51
 
52
52
  Most "AI QA" tools generate tests. **This one behaves like a QA team.**
53
53
 
54
- Ten agents, each with its own context, tool allowlist and budget, coordinated by
54
+ Fifteen agents, each with its own context, tool allowlist and budget, coordinated by
55
55
  a state machine that is ordinary Python — because a model cannot enforce a budget
56
56
  it is itself spending.
57
57
 
@@ -75,7 +75,7 @@ Nothing crosses between the loops except a ticket — which is also the audit tr
75
75
 
76
76
  | | |
77
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 `conductor.py`. That is also why **649 tests run offline, free, with no API key.** |
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 `conductor.py`. That is also why **686 tests run offline, free, with no API key.** |
79
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
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
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. |
@@ -189,6 +189,10 @@ QAAS_TRACKER=jira qaas run --mode nightly
189
189
  maps your workflow statuses, and prints the exact JSON it *would* POST. **It
190
190
  creates nothing.**
191
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
+
192
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.
193
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.
194
198
 
@@ -197,6 +201,46 @@ creates nothing.**
197
201
  > `.qaas/tickets/` so you can read what *would* be filed. Switch per shell with
198
202
  > `QAAS_TRACKER=jira`.
199
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
+
200
244
  ---
201
245
 
202
246
  ## 🔌 Bring your own MCP servers
@@ -281,12 +325,31 @@ $ qaas trace run-20260908T182034-c6ed26
281
325
  ```
282
326
 
283
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
284
330
  qaas trace <run-id> --agent proof --kind verdict # filter
285
331
  qaas trace <run-id> --json # export
286
332
  qaas show <run-id> # mode, commit, tickets, escalations
287
333
  qaas runs # everything that ever ran
288
334
  ```
289
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 CARTOGRAPHER agent_started model=claude-sonnet-5
344
+ 16:32:46 CARTOGRAPHER denial tool=Bash reason=Bash is not in CARTOGRAPHER's
345
+ tool allowlist (Read, Grep, Glob).
346
+ 16:36:11 KEYSTONE envelope severity=major domain=architecture
347
+ 16:41:03 CLERK 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
+
290
353
  Runs are pinned to the **commit of the target** they examined, so a finding can
291
354
  be replayed against the tree that produced it.
292
355
 
@@ -335,18 +398,6 @@ than an opinion.
335
398
 
336
399
  ---
337
400
 
338
- ## 📋 Status
339
-
340
- Honest about what exists:
341
-
342
- - ✅ **All 16 agents in the design are built.**
343
- - ✅ **Adding one needs a prompt file and a YAML file — no Python.** Six were added that way, which is how the claim got tested.
344
- - ✅ The fix loop has closed end to end on a real defect: `NOT_FIXED → MENDER → ARBITER APPROVE → VERIFIED`.
345
- - ✅ 30 skills, 7 in-process MCP servers, 649 offline tests.
346
- - ⚠️ Running the bundled demo needs `export CORVID_PASSWORD=password123` — credentials come from the environment, including the demo's.
347
-
348
- ---
349
-
350
401
  ## 🤝 Contributing
351
402
 
352
403
  ```bash
@@ -354,7 +405,7 @@ git clone https://github.com/allaabdella2-us/qa-multi-agent-system
354
405
  cd qa-multi-agent-system
355
406
  uv venv && uv pip install -e ".[dev]"
356
407
 
357
- pytest # 649 tests, offline, free — keep it that way
408
+ pytest # 686 tests, offline, free — keep it that way
358
409
  pytest -m docker # needs: cd target-app && docker compose up -d
359
410
  qaas validate
360
411
  ```
@@ -10,7 +10,7 @@
10
10
  [![Python](https://img.shields.io/pypi/pyversions/qaas-python?color=3776AB&logo=python&logoColor=white)](https://pypi.org/project/qaas-python/)
11
11
  [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
12
12
  [![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)
13
- [![Tests](https://img.shields.io/badge/tests-649%20offline-success)](#-contributing)
13
+ [![Tests](https://img.shields.io/badge/tests-686%20offline-success)](#-contributing)
14
14
  [![Built on](https://img.shields.io/badge/built%20on-Claude%20Agent%20SDK-D97757)](https://docs.claude.com/en/api/agent-sdk/overview)
15
15
 
16
16
  [Quickstart](#-quickstart-in-60-seconds) · [Your repo](#-point-it-at-your-repository) · [Jira](#-file-into-jira) · [Architecture](ARCHITECTURE.md)
@@ -21,7 +21,7 @@
21
21
 
22
22
  Most "AI QA" tools generate tests. **This one behaves like a QA team.**
23
23
 
24
- Ten agents, each with its own context, tool allowlist and budget, coordinated by
24
+ Fifteen agents, each with its own context, tool allowlist and budget, coordinated by
25
25
  a state machine that is ordinary Python — because a model cannot enforce a budget
26
26
  it is itself spending.
27
27
 
@@ -45,7 +45,7 @@ Nothing crosses between the loops except a ticket — which is also the audit tr
45
45
 
46
46
  | | |
47
47
  |---|---|
48
- | 🧠 **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 `conductor.py`. That is also why **649 tests run offline, free, with no API key.** |
48
+ | 🧠 **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 `conductor.py`. That is also why **686 tests run offline, free, with no API key.** |
49
49
  | 🧱 **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. |
50
50
  | 🔬 **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. |
51
51
  | 📊 **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. |
@@ -159,6 +159,10 @@ QAAS_TRACKER=jira qaas run --mode nightly
159
159
  maps your workflow statuses, and prints the exact JSON it *would* POST. **It
160
160
  creates nothing.**
161
161
 
162
+ Tired of four exports in every new shell? Put them in a `.env` — `.qaas/.env` is
163
+ already gitignored — and every command reads it. **Anything you export wins over
164
+ the file**, so a stale `.env` can never redirect a run.
165
+
162
166
  - 🔁 **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.
163
167
  - 🔐 **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.
164
168
 
@@ -167,6 +171,46 @@ creates nothing.**
167
171
  > `.qaas/tickets/` so you can read what *would* be filed. Switch per shell with
168
172
  > `QAAS_TRACKER=jira`.
169
173
 
174
+ ### 📌 A view per repository, made for you
175
+
176
+ Point it at a new repository and it provisions that repository's own Jira view
177
+ before the first agent starts — so there is something to watch *during* the run,
178
+ not a report afterwards.
179
+
180
+ ```console
181
+ $ QAAS_TRACKER=jira qaas run --repo https://github.com/acme/checkout.git --mode nightly
182
+ target: checkout (none)
183
+ filter created — https://you.atlassian.net/issues/?filter=10001
184
+ every ticket from this run carries the label repo-checkout
185
+ ```
186
+
187
+ Every ticket the system files carries `repo-<target>`, stamped in code rather
188
+ than asked of an agent. A **saved filter** over exactly that label is the
189
+ per-repository view, and on a company-managed project a **board** is built over
190
+ the filter too.
191
+
192
+ ```bash
193
+ qaas board # find or create this target's view
194
+ qaas board --no-create # show the label and JQL, touch nothing
195
+ ```
196
+
197
+ > [!NOTE]
198
+ > **Not a project per repository.** Creating a Jira project needs administrator
199
+ > rights a bot account rarely has, and a project per repository is unmanageable
200
+ > by the tenth one. A filter needs no special grant.
201
+ >
202
+ > **Not always a board, either.** Team-managed (next-gen) projects own their own
203
+ > board and cannot have a second one built over a filter — Jira's API will
204
+ > happily create one and give it no page in the UI. So the project's style is
205
+ > checked first, and on a team-managed project you get the filter alone. You are
206
+ > told which you got, and the link always opens. Point `JIRA_PROJECT_KEY` at a
207
+ > **company-managed** project and you get a real board per repository, with
208
+ > To Do / In Progress / Done.
209
+
210
+ Run it twice on the same repository and it **reuses** what is there. A run is
211
+ never failed over this: a run that found nine defects and could not make a view
212
+ has still done its job.
213
+
170
214
  ---
171
215
 
172
216
  ## 🔌 Bring your own MCP servers
@@ -251,12 +295,31 @@ $ qaas trace run-20260908T182034-c6ed26
251
295
  ```
252
296
 
253
297
  ```bash
298
+ qaas trace <run-id> --follow # watch a run as it happens
299
+ qaas trace <run-id> --quiet # decisions only, no file reads
254
300
  qaas trace <run-id> --agent proof --kind verdict # filter
255
301
  qaas trace <run-id> --json # export
256
302
  qaas show <run-id> # mode, commit, tickets, escalations
257
303
  qaas runs # everything that ever ran
258
304
  ```
259
305
 
306
+ **Watch a run live.** `--follow` tails the ledger of a run in progress — start it
307
+ in a second terminal the moment a run begins, or even before, and it waits.
308
+
309
+ ```console
310
+ $ qaas trace run-20260909T163240-83b11c --follow --quiet
311
+ following run-20260909T163240-83b11c — ctrl-c to stop
312
+ 16:32:40 - run_started mode=pr-check agents=[8] target_sha=da19f406
313
+ 16:32:40 CARTOGRAPHER agent_started model=claude-sonnet-5
314
+ 16:32:46 CARTOGRAPHER denial tool=Bash reason=Bash is not in CARTOGRAPHER's
315
+ tool allowlist (Read, Grep, Glob).
316
+ 16:36:11 KEYSTONE envelope severity=major domain=architecture
317
+ 16:41:03 CLERK ticket action=created key=QA-118 severity=major
318
+ ```
319
+
320
+ Drop `--quiet` to see every file the agents read, one line each. Combine with
321
+ `--agent` and `--kind` to watch one agent, or only the verdicts.
322
+
260
323
  Runs are pinned to the **commit of the target** they examined, so a finding can
261
324
  be replayed against the tree that produced it.
262
325
 
@@ -305,18 +368,6 @@ than an opinion.
305
368
 
306
369
  ---
307
370
 
308
- ## 📋 Status
309
-
310
- Honest about what exists:
311
-
312
- - ✅ **All 16 agents in the design are built.**
313
- - ✅ **Adding one needs a prompt file and a YAML file — no Python.** Six were added that way, which is how the claim got tested.
314
- - ✅ The fix loop has closed end to end on a real defect: `NOT_FIXED → MENDER → ARBITER APPROVE → VERIFIED`.
315
- - ✅ 30 skills, 7 in-process MCP servers, 649 offline tests.
316
- - ⚠️ Running the bundled demo needs `export CORVID_PASSWORD=password123` — credentials come from the environment, including the demo's.
317
-
318
- ---
319
-
320
371
  ## 🤝 Contributing
321
372
 
322
373
  ```bash
@@ -324,7 +375,7 @@ git clone https://github.com/allaabdella2-us/qa-multi-agent-system
324
375
  cd qa-multi-agent-system
325
376
  uv venv && uv pip install -e ".[dev]"
326
377
 
327
- pytest # 649 tests, offline, free — keep it that way
378
+ pytest # 686 tests, offline, free — keep it that way
328
379
  pytest -m docker # needs: cd target-app && docker compose up -d
329
380
  qaas validate
330
381
  ```
@@ -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.3.2"
5
+ version = "1.0.0"
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"