@ivorycanvas/qamap 0.3.0

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 (98) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/LICENSE +21 -0
  3. package/README.md +636 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +879 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +5 -0
  8. package/dist/config.js +114 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/context.d.ts +1 -0
  11. package/dist/context.js +126 -0
  12. package/dist/context.js.map +1 -0
  13. package/dist/doctor.d.ts +32 -0
  14. package/dist/doctor.js +200 -0
  15. package/dist/doctor.js.map +1 -0
  16. package/dist/domain-language.d.ts +25 -0
  17. package/dist/domain-language.js +655 -0
  18. package/dist/domain-language.js.map +1 -0
  19. package/dist/domains.d.ts +33 -0
  20. package/dist/domains.js +258 -0
  21. package/dist/domains.js.map +1 -0
  22. package/dist/e2e.d.ts +326 -0
  23. package/dist/e2e.js +6869 -0
  24. package/dist/e2e.js.map +1 -0
  25. package/dist/eval.d.ts +40 -0
  26. package/dist/eval.js +374 -0
  27. package/dist/eval.js.map +1 -0
  28. package/dist/flows.d.ts +32 -0
  29. package/dist/flows.js +246 -0
  30. package/dist/flows.js.map +1 -0
  31. package/dist/fs.d.ts +7 -0
  32. package/dist/fs.js +132 -0
  33. package/dist/fs.js.map +1 -0
  34. package/dist/github.d.ts +34 -0
  35. package/dist/github.js +183 -0
  36. package/dist/github.js.map +1 -0
  37. package/dist/history.d.ts +173 -0
  38. package/dist/history.js +247 -0
  39. package/dist/history.js.map +1 -0
  40. package/dist/index.d.ts +35 -0
  41. package/dist/index.js +20 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/manifest-suggestions.d.ts +67 -0
  44. package/dist/manifest-suggestions.js +673 -0
  45. package/dist/manifest-suggestions.js.map +1 -0
  46. package/dist/manifest.d.ts +212 -0
  47. package/dist/manifest.js +1607 -0
  48. package/dist/manifest.js.map +1 -0
  49. package/dist/qa.d.ts +53 -0
  50. package/dist/qa.js +361 -0
  51. package/dist/qa.js.map +1 -0
  52. package/dist/report.d.ts +5 -0
  53. package/dist/report.js +164 -0
  54. package/dist/report.js.map +1 -0
  55. package/dist/review.d.ts +31 -0
  56. package/dist/review.js +383 -0
  57. package/dist/review.js.map +1 -0
  58. package/dist/scanner.d.ts +3 -0
  59. package/dist/scanner.js +797 -0
  60. package/dist/scanner.js.map +1 -0
  61. package/dist/severity.d.ts +3 -0
  62. package/dist/severity.js +9 -0
  63. package/dist/severity.js.map +1 -0
  64. package/dist/test-evidence.d.ts +39 -0
  65. package/dist/test-evidence.js +303 -0
  66. package/dist/test-evidence.js.map +1 -0
  67. package/dist/test-plan.d.ts +35 -0
  68. package/dist/test-plan.js +573 -0
  69. package/dist/test-plan.js.map +1 -0
  70. package/dist/types.d.ts +60 -0
  71. package/dist/types.js +2 -0
  72. package/dist/types.js.map +1 -0
  73. package/dist/verify.d.ts +27 -0
  74. package/dist/verify.js +244 -0
  75. package/dist/verify.js.map +1 -0
  76. package/dist/version.d.ts +2 -0
  77. package/dist/version.js +3 -0
  78. package/dist/version.js.map +1 -0
  79. package/docs/adoption.md +166 -0
  80. package/docs/agent-skill.md +94 -0
  81. package/docs/api-contracts.md +30 -0
  82. package/docs/assets/qamap-30s-demo.gif +0 -0
  83. package/docs/configuration.md +277 -0
  84. package/docs/e2e-output-examples.md +464 -0
  85. package/docs/ecosystem.md +41 -0
  86. package/docs/eval.md +52 -0
  87. package/docs/github-action.md +89 -0
  88. package/docs/manifest.md +350 -0
  89. package/docs/quickstart-demo.md +268 -0
  90. package/docs/release-validation.md +247 -0
  91. package/docs/releasing.md +112 -0
  92. package/docs/roadmap.md +67 -0
  93. package/docs/rules.md +28 -0
  94. package/docs/verify.md +44 -0
  95. package/package.json +80 -0
  96. package/schema/qamap-manifest.schema.json +323 -0
  97. package/schema/qamap.schema.json +58 -0
  98. package/skills/qamap-pr-qa/SKILL.md +81 -0
@@ -0,0 +1,464 @@
1
+ # E2E Output Examples
2
+
3
+ These examples show the shape of QAMap output that should be good enough for the current public release. They are intentionally short snippets, not full generated files. The important property is that they are derived from repository structure, git changes, manifests, and test evidence without an LLM call.
4
+
5
+ ## PR QA Skill Preview
6
+
7
+ First contact should work without a manifest:
8
+
9
+ ```sh
10
+ pnpm dlx @ivorycanvas/qamap qa . --base origin/main --head HEAD
11
+ ```
12
+
13
+ The output should be specific enough to paste into a PR comment:
14
+
15
+ ```txt
16
+ # QAMap QA Draft
17
+
18
+ Summary
19
+ - Project: Web
20
+ - Recommended runner: Playwright
21
+ - Manifest: not found; using repo signals and PR diff only
22
+ - Readiness: near-runnable
23
+
24
+ PR Comment Draft
25
+ - Affected flow: Checkout UI smoke flow
26
+ - User journey: Customer -> Open route /checkout -> Complete checkout with realistic form data
27
+ - Success signal: confirmation state is visible after submit
28
+ - Changed files: src/pages/checkout/index.tsx
29
+
30
+ Suggested E2E / QA Draft
31
+ - tests/e2e/checkout-ui-smoke-flow.spec.ts: near runnable
32
+ - Open route /checkout.
33
+ - Fill checkout email.
34
+ - Submit checkout.
35
+ - Assert confirmation state is visible after submit.
36
+
37
+ Missing evidence before trusting this PR
38
+ - [required] fixture: Add deterministic fixture or mock data.
39
+ - [recommended] selector: Confirm stable selectors.
40
+
41
+ PR checklist
42
+ - [ ] Review the generated draft path.
43
+ - [ ] Answer the reviewer question for the affected flow.
44
+ - [ ] Run local validation: pnpm run test:e2e
45
+ ```
46
+
47
+ If this recommendation is useful but slightly wrong, the next step is not another long AI prompt. Generate and correct repo-local QA memory:
48
+
49
+ ```sh
50
+ pnpm exec qamap manifest init .
51
+ ```
52
+
53
+ Then future `qamap qa` runs can use `.qamap/manifest.yaml` to produce more precise flow names, checks, anchors, and repair paths.
54
+
55
+ ## Verification Manifest Feedback
56
+
57
+ When a repository has `.qamap/manifest.yaml`, QAMap should explain why a recommendation happened and how a maintainer can correct it:
58
+
59
+ ```txt
60
+ Manifest recommendations: 3
61
+
62
+ Campaign Application Complete `campaign-application-complete`
63
+ - Kind: flow
64
+ - Confidence: high
65
+ - Why this was recommended: Changed files match anchors for the Campaign Application Complete flow.
66
+ - Evidence sources: product-qa
67
+ - Manifest evidence: .qamap/manifest.yaml > flows.campaign-application-complete.anchors
68
+ - If this is wrong: update .qamap/manifest.yaml > flows.campaign-application-complete.anchors
69
+ - Next actions:
70
+ - Draft or review E2E coverage for the Campaign Application Complete flow.
71
+ - Cover the declared checks: Submit content URL successfully; Show validation error for invalid content URL.
72
+ - Repair hints:
73
+ - If these files do not belong to this flow, update .qamap/manifest.yaml > flows.campaign-application-complete.anchors.
74
+ - If the recommended assertions feel vague, rewrite .qamap/manifest.yaml > flows.campaign-application-complete.checks in team language.
75
+ ```
76
+
77
+ This is the feedback loop: static analysis proposes a baseline, humans correct durable manifest entries, and future E2E recommendations become more specific without spending another LLM prompt on the same explanation.
78
+
79
+ `qamap manifest validate .` checks whether that repo-local knowledge is usable:
80
+
81
+ ```txt
82
+ QAMap Manifest Validate
83
+ Status: valid
84
+ Manifest: .qamap/manifest.yaml
85
+ Issues: 0 errors, 0 warnings, 0 info
86
+ ```
87
+
88
+ `qamap manifest explain . --base origin/main --head HEAD` makes a single branch debuggable:
89
+
90
+ ```txt
91
+ QAMap Manifest Explain
92
+ Changed files: 1
93
+ Matches: 3
94
+
95
+ Matches:
96
+ - Campaign Application Complete (flow, high)
97
+ Why: Changed files match anchors for the Campaign Application Complete flow.
98
+ Evidence: .qamap/manifest.yaml > flows.campaign-application-complete.anchors
99
+ If wrong: update .qamap/manifest.yaml > flows.campaign-application-complete.anchors
100
+ Checks: Submit content URL successfully; Show validation error for invalid content URL
101
+ ```
102
+
103
+ When that flow includes an entry route and checks, `qamap e2e draft` promotes it ahead of heuristic drafts:
104
+
105
+ ```ts
106
+ // Verification manifest evidence:
107
+ // - Flow: Campaign Application Complete (campaign-application-complete)
108
+ // - Entry route: /campaign/official/applicationComplete
109
+ // - Required checks:
110
+ // - [ ] Submit content URL successfully
111
+ // - [ ] Show validation error for invalid content URL
112
+
113
+ test("Campaign Application Complete", async ({ page }) => {
114
+ await test.step("Open route /campaign/official/applicationComplete.", async () => {
115
+ await page.goto("/campaign/official/applicationComplete");
116
+ });
117
+ });
118
+ ```
119
+
120
+ ## Web Core Flow
121
+
122
+ When a web app declares a core flow:
123
+
124
+ ```yaml
125
+ flows:
126
+ - id: checkout-purchase
127
+ name: Checkout purchase
128
+ priority: critical
129
+ files:
130
+ - src/pages/checkout/**
131
+ routes:
132
+ - /checkout
133
+ checks:
134
+ - Complete checkout with a valid payment method.
135
+ - Verify declined payment recovery.
136
+ ```
137
+
138
+ `qamap e2e plan` should prefer the team-approved name:
139
+
140
+ ```txt
141
+ Project: Web
142
+ Recommended runner: Playwright
143
+ Execution profile: high
144
+ Start command: pnpm run dev
145
+ Test command: pnpm run test:e2e
146
+ Base URL: http://127.0.0.1:4173
147
+ Matched core flows: 1
148
+
149
+ Flow: Checkout purchase UI smoke flow
150
+ Actor: Customer
151
+ Trigger: Open route /checkout.
152
+ Success signal: Verify declined payment recovery
153
+ ```
154
+
155
+ The Playwright draft should read like the product journey:
156
+
157
+ ```ts
158
+ test("Checkout purchase", async ({ page }) => {
159
+ await test.step("Open route /checkout.", async () => {
160
+ await page.goto("/checkout");
161
+ });
162
+
163
+ await test.step("Complete checkout with a valid payment method.", async () => {
164
+ await page.getByTestId("checkout-submit").click();
165
+ });
166
+ });
167
+ ```
168
+
169
+ When QAMap can infer durable browser controls, the draft should prefer executable Playwright locators over placeholder text:
170
+
171
+ ```ts
172
+ await test.step("Fill profile email.", async () => {
173
+ // Step intent: Fill profile email.
174
+ await page.getByPlaceholder("Profile email").fill("qamap@example.com");
175
+ });
176
+
177
+ await test.step("Save settings.", async () => {
178
+ // Step intent: Save settings.
179
+ await page.getByRole("button", { name: "Save settings" }).click();
180
+ });
181
+ ```
182
+
183
+ The draft result should also explain whether the generated file passed static runner checks:
184
+
185
+ ```txt
186
+ Draft self-check: pass
187
+ Command: pnpm run test:e2e
188
+ Summary: Playwright draft passed static runner checks.
189
+ ```
190
+
191
+ Before writing files, `--dry-run` should expose the same readiness data with preview status:
192
+
193
+ ```txt
194
+ Mode: dry run (no files were written)
195
+ Files: 0 created, 1 previewed, 0 skipped
196
+
197
+ - preview: `tests/e2e/checkout-purchase.spec.ts` (Checkout purchase)
198
+ - source: core-flow
199
+ - runnable status: near-runnable
200
+ - self-check: pass
201
+ ```
202
+
203
+ For framework-native routing, QAMap should preserve the route a user can actually open rather than framework-only folder syntax. A Next App Router file such as `src/app/(shop)/products/[productId]/page.tsx` should become `/products/:productId`, and a concrete link such as `/products/demo-product` can seed the generated route params:
204
+
205
+ ```ts
206
+ const routeParams = {
207
+ productId: "demo-product",
208
+ };
209
+
210
+ await page.goto(`/products/${routeParams.productId}`);
211
+ ```
212
+
213
+ React Router config should work similarly when route objects expose path values:
214
+
215
+ ```ts
216
+ createBrowserRouter([
217
+ { path: "/reports/:reportId", element: <ReportPage /> },
218
+ ]);
219
+ ```
220
+
221
+ ## Expo / React Native Flow
222
+
223
+ For an Expo or React Native change, QAMap should recommend Maestro and carry mobile selectors into the draft:
224
+
225
+ ```txt
226
+ Project: Expo / React Native
227
+ Recommended runner: Maestro
228
+
229
+ Flow: Ink Drawing UI smoke flow
230
+ Actor: User
231
+ Trigger: Open the Ink Drawing screen.
232
+ Selectors: testID=ink-save-button, testID=record-mode-ink
233
+ ```
234
+
235
+ Example Maestro draft shape:
236
+
237
+ ```yaml
238
+ appId: ${APP_ID}
239
+ ---
240
+ - launchApp
241
+ - tapOn: { id: "record-mode-ink" }
242
+ - tapOn: { id: "ink-save-button" }
243
+ ```
244
+
245
+ When the changed file name exposes a narrower user action, the generated flow should use that action instead of stopping at a broad domain journey:
246
+
247
+ ```txt
248
+ Changed file: src/features/offer/components/ContentUrlSubmitModal.tsx
249
+ Domain term: Offer
250
+ Generated scenario: Offer Content URL Submit
251
+ Generated draft path: .maestro/offer-content-url-submit.yaml
252
+ ```
253
+
254
+ The draft should then carry the same product-action wording into the runnable skeleton:
255
+
256
+ ```yaml
257
+ # Flow: Offer Content URL Submit
258
+ # Domain scenario: Offer Content URL Submit
259
+ # Intent: Verify the changed "Content URL Submit" behavior inside Offer instead of stopping at a generic primary journey.
260
+ appId: ${APP_ID}
261
+ ---
262
+ - launchApp
263
+ - tapOn: { id: "offer-content-url-submit" }
264
+ ```
265
+
266
+ ## API / Service Contract
267
+
268
+ For backend changes such as `src/v1/offer/utils.ts`, QAMap should not invent a browser journey. It should infer the domain word and stay contract-focused:
269
+
270
+ ```txt
271
+ Project: API / service
272
+ Recommended runner: Manual
273
+
274
+ Flow: Offer API contract smoke checklist
275
+ Actor: API consumer or upstream service
276
+ Trigger: Call the endpoint, handler, or service path affected by src/v1/offer/utils.ts.
277
+ Success signal: the changed contract returns the expected status, response shape, auth behavior, and failure handling
278
+ ```
279
+
280
+ The manual draft should stay actionable:
281
+
282
+ ```md
283
+ # Offer API contract
284
+
285
+ ## Steps
286
+
287
+ - [ ] Call the changed endpoint, client, command, or handler with a valid request.
288
+ - [ ] Verify the response shape, status, and parsed data match the public contract.
289
+ - [ ] Verify invalid input, authorization failure, timeout, and server-error handling.
290
+ - [ ] Check backward compatibility for existing callers.
291
+ ```
292
+
293
+ ## CLI Command Verification
294
+
295
+ For an npm package that exposes `package.json` bin entries, QAMap should not invent a UI journey. It should stay focused on the command contract users run in terminals, scripts, and CI:
296
+
297
+ ```txt
298
+ Project: CLI
299
+ Recommended runner: Manual
300
+
301
+ Flow: CLI command verification checklist
302
+ Actor: CLI user or maintainer
303
+ Trigger: Run the CLI command path affected by src/cli.ts.
304
+ Success signal: the command returns the expected stdout, stderr, generated files, and exit code for valid and invalid inputs
305
+ ```
306
+
307
+ The manual draft should name concrete command evidence:
308
+
309
+ ```md
310
+ # CLI command verification checklist
311
+
312
+ ## Steps
313
+
314
+ - [ ] Build or install the package in a clean local environment.
315
+ - [ ] Run the changed command with a representative valid argument set.
316
+ - [ ] Verify stdout, stderr, generated files, and exit code match the intended behavior.
317
+ - [ ] Run one invalid, missing-argument, or unsupported-input path and verify the failure message and exit code.
318
+ ```
319
+
320
+ ## Test-Light Project
321
+
322
+ When a project has little or no E2E setup, QAMap should move the user toward a concrete starter draft, not just a task list:
323
+
324
+ ```txt
325
+ ## First E2E Draft Bootstrap
326
+
327
+ QAMap did not find committed test files for this target. The next step is to create the first runnable starter draft, not to stop at a checklist.
328
+
329
+ - Recommended first runner: Playwright
330
+ - Create command: `qamap e2e setup . --runner playwright`
331
+ - Install command: `pnpm add -D @playwright/test`
332
+ - Draft files QAMap can create:
333
+ - `playwright.config.ts`
334
+ - `tests/e2e/`
335
+ - `tests/e2e/checkout-primary-journey.spec.ts`
336
+ - Files to update: `package.json`
337
+
338
+ Bootstrap summary:
339
+ 4 required bootstrap steps must be resolved before generated E2E drafts should be treated as regression coverage.
340
+
341
+ Required:
342
+ - Configure Playwright before making drafts required
343
+ - Create the first changed-flow E2E draft
344
+ - Add deterministic fixture or mock responses
345
+ - Add stable selectors for changed UI surfaces
346
+ ```
347
+
348
+ Draft action items should make the next developer action explicit:
349
+
350
+ ```txt
351
+ Action summary:
352
+ - readiness score: 64/100 (needs-work)
353
+ - runnable status: near-runnable
354
+ - self-check: pass or warning based on generated starter code and execution profile
355
+ - top blocker: No Playwright config file was detected.
356
+ - required runner: Create `playwright.config.ts` with `testDir`, `use.baseURL`, and `webServer.command` when QAMap inferred the dev URL from scripts.
357
+ - required fixture: Add deterministic fixture or mock data
358
+ - required validation: Resolve missing validation evidence
359
+ - recommended manifest: Promote durable product language
360
+ ```
361
+
362
+ ## API-Dependent Client Flow
363
+
364
+ When a client-side change calls an API path but the branch does not include backend or fixture evidence, QAMap should name that as a readiness gap and still give the tester a concrete mock slot:
365
+
366
+ If reusable repo-local evidence already exists, the PR QA output should point at it instead of only saying "add a fixture":
367
+
368
+ ```txt
369
+ Missing evidence before trusting this PR
370
+ - [recommended] fixture: Confirm fixture coverage - Reuse or extend existing fixture/mock evidence for this flow: src/services/devSeedService.ts, src/services/reportMockService.ts.
371
+ ```
372
+
373
+ ```ts
374
+ const mockApiResponses = {
375
+ "**/api/orders/fixture-order-id": {
376
+ status: 200,
377
+ body: {
378
+ ok: true,
379
+ source: "qamap-draft",
380
+ },
381
+ },
382
+ };
383
+
384
+ // Replace sample responses with deterministic fixtures from the target domain before promoting this draft.
385
+ for (const [urlPattern, response] of Object.entries(mockApiResponses)) {
386
+ await page.route(urlPattern, async (route) => {
387
+ await route.fulfill({
388
+ status: response.status,
389
+ contentType: "application/json",
390
+ body: JSON.stringify(response.body),
391
+ });
392
+ });
393
+ }
394
+ ```
395
+
396
+ This is useful for PRs where the UI can be built against mockdata before the server implementation is available. The generated file should still report fixture readiness as missing or partial until a reviewer replaces the sample response with domain-correct success, empty, unauthorized, timeout, or server-error fixtures.
397
+
398
+ When the PR changes the endpoint implementation itself, QAMap should not hide that contract behind a synthetic response. In that case the Playwright draft records the endpoint as an observed API pattern instead of adding a response mock:
399
+
400
+ ```ts
401
+ const changedApiEndpointPatterns = [
402
+ "**/api/checkout",
403
+ ];
404
+ const observedChangedApiResponses: Array<{ url: string; status: number }> = [];
405
+ page.on("response", (response) => {
406
+ if (changedApiEndpointPatterns.some((pattern) => response.url().includes(pattern.replace(/^\*\*/, "")))) {
407
+ observedChangedApiResponses.push({ url: response.url(), status: response.status() });
408
+ }
409
+ });
410
+ ```
411
+
412
+ ## Monorepo Package
413
+
414
+ When run at the workspace root, QAMap should identify changed package targets before asking the maintainer to choose a final runner:
415
+
416
+ ```sh
417
+ qamap e2e plan . --base main --head HEAD
418
+ ```
419
+
420
+ Expected root-level behavior:
421
+
422
+ ```txt
423
+ Changed App/Package Targets
424
+
425
+ | Target | Package | Project | Runner | Scoped Command |
426
+ | services/offer | offer | Web | Playwright | qamap e2e plan services/offer --workspace-root . --base main --head HEAD |
427
+ | apps/mobile | @acme/mobile | Expo / React Native | Maestro | qamap e2e plan apps/mobile --workspace-root . --base main --head HEAD |
428
+ ```
429
+
430
+ For package scans, QAMap should use workspace policy without leaking workspace-root paths into package-local drafts:
431
+
432
+ ```sh
433
+ qamap e2e plan services/offer --workspace-root . --base main --head HEAD
434
+ ```
435
+
436
+ Expected behavior:
437
+
438
+ ```txt
439
+ Workspace root: .
440
+ Package root: services/offer
441
+ Matched core flow: Offer submit
442
+ Changed files: src/features/offer/submit.ts
443
+ Generated draft path: docs/e2e/offer-submit.md
444
+ ```
445
+
446
+ The draft should mention package-local files:
447
+
448
+ ```md
449
+ Related Changed Files
450
+
451
+ - `src/features/offer/submit.ts`
452
+ ```
453
+
454
+ ## What Good Output Feels Like
455
+
456
+ Good QAMap output should answer these questions quickly:
457
+
458
+ - What behavior did this branch probably change?
459
+ - What does the team call that behavior?
460
+ - Who or what exercises it?
461
+ - Which runner or checklist is the right first shape?
462
+ - Which setup, selector, fixture, or validation gap blocks this from becoming real regression coverage?
463
+
464
+ If the output only says "make an E2E test" without these answers, it is not ready for the current release bar.
@@ -0,0 +1,41 @@
1
+ # Agent Ecosystem Coverage
2
+
3
+ AI coding agents now read repository instructions, connect to MCP servers, run tool hooks, and prepare pull requests. QAMap tracks the repository files that shape those behaviors without executing project code.
4
+
5
+ ## Instruction Surfaces
6
+
7
+ QAMap treats these files as agent instruction surfaces:
8
+
9
+ | Ecosystem | Files |
10
+ | --- | --- |
11
+ | Shared / Codex-style | `AGENTS.md`, `AGENTS.override.md` |
12
+ | Claude Code | `CLAUDE.md`, `.claude/CLAUDE.md`, `.claude/rules/*.md` |
13
+ | Cursor | `.cursorrules`, `.cursor/rules/*.md`, `.cursor/rules/*.mdc` |
14
+ | GitHub Copilot | `.github/copilot-instructions.md`, `.github/instructions/*.instructions.md` |
15
+ | Gemini CLI | `GEMINI.md` |
16
+
17
+ These files are scanned for missing guidance, conflicting guidance, and suspicious instruction text.
18
+
19
+ ## Tool And Settings Surfaces
20
+
21
+ QAMap statically inspects committed MCP and agent settings files:
22
+
23
+ | Surface | Files | Checks |
24
+ | --- | --- | --- |
25
+ | MCP config | `.mcp.json`, `mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`, `claude_desktop_config.json` | unreadable JSON, risky commands, committed secret-like env values |
26
+ | Agent settings | `.claude/settings.json`, `.claude/settings.local.json`, `.gemini/settings.json` | MCP servers, risky hooks, broad shell permissions |
27
+
28
+ The scanner does not run MCP servers, hooks, package scripts, or project code.
29
+
30
+ ## Source Signals
31
+
32
+ These references guide the current coverage:
33
+
34
+ - [OpenAI Codex AGENTS.md](https://developers.openai.com/codex/cloud/agents-md/) and the community [AGENTS.md](https://agents.md/) convention.
35
+ - [Claude Code memory](https://docs.anthropic.com/en/docs/claude-code/memory), [settings](https://docs.anthropic.com/en/docs/claude-code/settings), and [hooks](https://docs.anthropic.com/en/docs/claude-code/hooks).
36
+ - [GitHub Copilot custom instructions](https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot).
37
+ - [Cursor rules](https://cursor.com/docs/rules) and [Cursor MCP](https://cursor.com/docs/mcp).
38
+ - [Gemini CLI configuration](https://google-gemini.github.io/gemini-cli/docs/get-started/configuration.html) and [Gemini MCP servers](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html).
39
+ - [Model Context Protocol security best practices](https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices).
40
+
41
+ QAMap should keep this list practical rather than exhaustive: add a surface when it is common enough that maintainers would reasonably expect a repo preflight check to notice it.
package/docs/eval.md ADDED
@@ -0,0 +1,52 @@
1
+ # QAMap Eval
2
+
3
+ `qamap eval` scores whether a branch is ready for human review in an AI-assisted workflow.
4
+
5
+ It does not try to prove that the code is correct. Instead, it checks whether reviewers have enough evidence to trust, challenge, and verify the change without absorbing unnecessary cognitive load.
6
+
7
+ For a complete PR-facing report that also includes QAMap review findings and suggested domain tests, use `qamap verify`.
8
+
9
+ ## Usage
10
+
11
+ ```sh
12
+ qamap verify . --base origin/main --head HEAD --pr-body-file pr-body.md
13
+ qamap eval . --base origin/main --head HEAD --format markdown
14
+ qamap eval . --base origin/main --head HEAD --pr-body-file pr-body.md
15
+ qamap eval services/offer --workspace-root . --base origin/main --head HEAD --include-working-tree
16
+ ```
17
+
18
+ The GitHub Action can append the same report to the PR comment. On pull request events it reads the PR body from `GITHUB_EVENT_PATH`.
19
+
20
+ ## Gates
21
+
22
+ Each gate is scored from `0` to `2`.
23
+
24
+ | Gate | What it checks |
25
+ | --- | --- |
26
+ | Validation commands | The project exposes a real test command and supporting commands such as typecheck, lint, build, e2e, tox, Ruff, mypy, `go vet`, clippy, or Maven verify. |
27
+ | Changed test coverage | Source changes are paired with changed test files, or at least a runnable test command exists. |
28
+ | Intent capture | The PR body, decision docs, or PR template capture the problem, rationale, context, alternatives, or tradeoffs. |
29
+ | Risk explanation | Risky surfaces such as config, workflows, API contracts, auth, billing, migrations, and env files include risk or rollback context. |
30
+ | Domain test plan | Changed files can be mapped to focused domain verification scenarios. |
31
+ | Review size | The branch is small enough to review without unnecessary verification tax. |
32
+
33
+ `validationCommands` in `qamap.config.json` can supply commands for custom stacks or monorepos when standard project files are not enough.
34
+
35
+ ## Ratings
36
+
37
+ | Rating | Meaning |
38
+ | --- | --- |
39
+ | `strong` | The branch has clear verification evidence and should be easy to review. |
40
+ | `ready` | The branch is probably reviewable, with some follow-up still useful. |
41
+ | `needs-work` | Reviewers should ask for more tests, context, risk notes, or a smaller diff. |
42
+ | `high-risk` | The branch is expensive or risky to verify; add evidence before relying on it. |
43
+
44
+ ## Why This Exists
45
+
46
+ AI-assisted code often looks plausible before it is truly understood. That creates verification tax, cognitive debt, and intent debt:
47
+
48
+ - verification tax: humans must spend extra time proving the generated result is safe
49
+ - cognitive debt: reviewers receive more code than they can meaningfully understand
50
+ - intent debt: the reason for a change disappears into a prompt or chat session
51
+
52
+ `qamap eval` turns those risks into a small, static, explainable checklist that can run locally or in CI.
@@ -0,0 +1,89 @@
1
+ # GitHub Action
2
+
3
+ QAMap ships a composite GitHub Action that can run `scan` or branch-aware `review` inside pull request workflows.
4
+
5
+ The action writes:
6
+
7
+ - a Markdown report file
8
+ - a sticky PR comment body
9
+ - an optional suggested domain test plan
10
+ - an optional verification readiness evaluation
11
+ - GitHub workflow annotations
12
+ - a GitHub step summary
13
+
14
+ ## Pull Request Review
15
+
16
+ ```yaml
17
+ name: QAMap
18
+
19
+ on:
20
+ pull_request:
21
+
22
+ permissions:
23
+ contents: read
24
+ pull-requests: write
25
+
26
+ jobs:
27
+ qamap:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v7
31
+ with:
32
+ fetch-depth: 0
33
+ - uses: IvoryCanvas/qamap@main
34
+ with:
35
+ mode: review
36
+ base: ${{ github.event.pull_request.base.sha }}
37
+ head: HEAD
38
+ fail-on: high
39
+ github-token: ${{ secrets.GITHUB_TOKEN }}
40
+ ```
41
+
42
+ Use `fetch-depth: 0` so QAMap can compare the pull request branch with the base ref.
43
+ For production workflows, pin to a version tag such as `IvoryCanvas/qamap@v0.3.0` after that tag is published. Use `@main` only when intentionally testing unreleased behavior.
44
+
45
+ ## Monorepo Package
46
+
47
+ ```yaml
48
+ - uses: IvoryCanvas/qamap@main
49
+ with:
50
+ mode: review
51
+ path: services/offer
52
+ workspace-root: .
53
+ base: ${{ github.event.pull_request.base.sha }}
54
+ head: HEAD
55
+ fail-on: high
56
+ github-token: ${{ secrets.GITHUB_TOKEN }}
57
+ ```
58
+
59
+ ## Inputs
60
+
61
+ | Input | Default | Description |
62
+ | --- | --- | --- |
63
+ | `mode` | `auto` | `auto`, `scan`, or `review`. `auto` uses review mode on pull request events. |
64
+ | `path` | `.` | Repository path to scan. |
65
+ | `workspace-root` | | Optional monorepo workspace root. |
66
+ | `base` | | Base ref or SHA for review mode. |
67
+ | `head` | `HEAD` | Head ref or SHA for review mode. |
68
+ | `config` | | Optional QAMap config path. |
69
+ | `max-files` | | Optional maximum file count. |
70
+ | `fail-on` | `high` | Severity threshold that fails the action. |
71
+ | `report-file` | `qamap-report.md` | Markdown report output path. |
72
+ | `comment-file` | `qamap-pr-comment.md` | PR comment body output path. |
73
+ | `test-plan` | `true` | Append suggested domain tests for changed files. |
74
+ | `test-plan-file` | `qamap-test-plan.md` | Markdown test plan output path. |
75
+ | `eval` | `true` | Append a verification readiness evaluation. |
76
+ | `eval-file` | `qamap-eval.md` | Markdown evaluation output path. |
77
+ | `annotations` | `true` | Emit GitHub workflow annotations. |
78
+ | `step-summary` | `true` | Append the report to the GitHub step summary. |
79
+ | `comment` | `true` | Create or update a sticky pull request comment. |
80
+ | `github-token` | | Token for PR comments. Required when `comment` is `true`. |
81
+
82
+ ## Notes
83
+
84
+ - Set `pull-requests: write` only when PR comments are enabled.
85
+ - Set `comment: false` for advisory runs that should only use annotations and step summaries.
86
+ - Set `test-plan: false` when the PR comment should contain only QAMap findings.
87
+ - Set `eval: false` when the PR comment should not include readiness scoring.
88
+ - Pass `github-token: ${{ secrets.GITHUB_TOKEN }}` when `comment` is enabled.
89
+ - QAMap still does not execute scanned project code; the action only installs and builds QAMap itself before scanning the checked-out repository.