@ivorycanvas/qamap 0.3.4 → 0.4.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.
- package/CHANGELOG.md +43 -1
- package/README.md +19 -14
- package/dist/behavior-intent.d.ts +6 -0
- package/dist/behavior-intent.js +172 -0
- package/dist/behavior-intent.js.map +1 -0
- package/dist/behavior-manifest.d.ts +6 -0
- package/dist/behavior-manifest.js +221 -0
- package/dist/behavior-manifest.js.map +1 -0
- package/dist/behavior.d.ts +143 -0
- package/dist/behavior.js +458 -0
- package/dist/behavior.js.map +1 -0
- package/dist/change-intent.d.ts +71 -0
- package/dist/change-intent.js +744 -0
- package/dist/change-intent.js.map +1 -0
- package/dist/cli.js +6 -5
- package/dist/cli.js.map +1 -1
- package/dist/e2e.d.ts +16 -1
- package/dist/e2e.js +329 -24
- package/dist/e2e.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.js +138 -4
- package/dist/manifest.js.map +1 -1
- package/dist/qa.d.ts +1 -0
- package/dist/qa.js +73 -1
- package/dist/qa.js.map +1 -1
- package/dist/terminal.js +1 -1
- package/dist/terminal.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/adoption.md +11 -10
- package/docs/agent-format.md +9 -7
- package/docs/agent-skill.md +5 -2
- package/docs/architecture.md +131 -0
- package/docs/benchmarking.md +26 -4
- package/docs/commands.md +13 -7
- package/docs/e2e-output-examples.md +23 -9
- package/docs/manifest.md +4 -0
- package/docs/quickstart-demo.md +9 -2
- package/docs/release-validation.md +50 -37
- package/docs/releasing.md +13 -0
- package/docs/roadmap.md +20 -10
- package/package.json +4 -2
- package/schema/qamap-agent.schema.json +42 -1
- package/schema/qamap-behavior.schema.json +307 -0
- package/skills/qamap-pr-qa/SKILL.md +16 -11
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/IvoryCanvas/qamap/main/schema/qamap-behavior.schema.json",
|
|
4
|
+
"title": "QAMap Behavior Graph",
|
|
5
|
+
"description": "Framework-neutral, deterministic behavior evidence derived from a repository change.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["$schema", "schemaVersion", "root", "base", "head", "surface", "adapters", "nodes", "edges", "diagnostics", "summary"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"const": "https://raw.githubusercontent.com/IvoryCanvas/qamap/main/schema/qamap-behavior.schema.json"
|
|
12
|
+
},
|
|
13
|
+
"schemaVersion": {
|
|
14
|
+
"const": 1
|
|
15
|
+
},
|
|
16
|
+
"root": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"minLength": 1
|
|
19
|
+
},
|
|
20
|
+
"workspaceRoot": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1
|
|
23
|
+
},
|
|
24
|
+
"base": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"minLength": 1
|
|
27
|
+
},
|
|
28
|
+
"head": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"minLength": 1
|
|
31
|
+
},
|
|
32
|
+
"surface": {
|
|
33
|
+
"$ref": "#/$defs/surface"
|
|
34
|
+
},
|
|
35
|
+
"adapters": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": {
|
|
38
|
+
"$ref": "#/$defs/adapterRun"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"nodes": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"$ref": "#/$defs/node"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"edges": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": {
|
|
50
|
+
"$ref": "#/$defs/edge"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"diagnostics": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"$ref": "#/$defs/diagnostic"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"summary": {
|
|
60
|
+
"$ref": "#/$defs/summary"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"$defs": {
|
|
64
|
+
"confidence": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"enum": ["low", "medium", "high"]
|
|
67
|
+
},
|
|
68
|
+
"surface": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"enum": ["web", "mobile", "api", "cli", "artifact", "unknown"]
|
|
71
|
+
},
|
|
72
|
+
"nodeKind": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enum": ["domain", "flow", "surface", "action", "state", "effect", "contract", "assertion", "fixture", "locator", "source"]
|
|
75
|
+
},
|
|
76
|
+
"edgeKind": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"enum": ["contains", "enters-at", "precedes", "expects", "uses-fixture", "located-by", "implemented-by", "impacts"]
|
|
79
|
+
},
|
|
80
|
+
"evidenceKind": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"enum": ["commit", "diff", "source", "manifest", "selector", "fixture", "test", "inference"]
|
|
83
|
+
},
|
|
84
|
+
"evidence": {
|
|
85
|
+
"type": "object",
|
|
86
|
+
"additionalProperties": false,
|
|
87
|
+
"required": ["kind", "value"],
|
|
88
|
+
"properties": {
|
|
89
|
+
"kind": {
|
|
90
|
+
"$ref": "#/$defs/evidenceKind"
|
|
91
|
+
},
|
|
92
|
+
"value": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"minLength": 1
|
|
95
|
+
},
|
|
96
|
+
"file": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"minLength": 1
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"impact": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"additionalProperties": false,
|
|
105
|
+
"required": ["kind", "changedFiles"],
|
|
106
|
+
"properties": {
|
|
107
|
+
"kind": {
|
|
108
|
+
"type": "string",
|
|
109
|
+
"enum": ["direct", "propagated"]
|
|
110
|
+
},
|
|
111
|
+
"changedFiles": {
|
|
112
|
+
"type": "array",
|
|
113
|
+
"minItems": 1,
|
|
114
|
+
"uniqueItems": true,
|
|
115
|
+
"items": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"minLength": 1
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"attributeValue": {
|
|
123
|
+
"oneOf": [
|
|
124
|
+
{ "type": "string" },
|
|
125
|
+
{ "type": "number" },
|
|
126
|
+
{ "type": "boolean" },
|
|
127
|
+
{
|
|
128
|
+
"type": "array",
|
|
129
|
+
"items": {
|
|
130
|
+
"type": "string"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"node": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"additionalProperties": false,
|
|
138
|
+
"required": ["id", "kind", "label", "confidence", "evidence"],
|
|
139
|
+
"properties": {
|
|
140
|
+
"id": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"minLength": 1
|
|
143
|
+
},
|
|
144
|
+
"kind": {
|
|
145
|
+
"$ref": "#/$defs/nodeKind"
|
|
146
|
+
},
|
|
147
|
+
"label": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"minLength": 1
|
|
150
|
+
},
|
|
151
|
+
"confidence": {
|
|
152
|
+
"$ref": "#/$defs/confidence"
|
|
153
|
+
},
|
|
154
|
+
"evidence": {
|
|
155
|
+
"type": "array",
|
|
156
|
+
"items": {
|
|
157
|
+
"$ref": "#/$defs/evidence"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"attributes": {
|
|
161
|
+
"type": "object",
|
|
162
|
+
"additionalProperties": {
|
|
163
|
+
"$ref": "#/$defs/attributeValue"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"impact": {
|
|
167
|
+
"$ref": "#/$defs/impact"
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"edge": {
|
|
172
|
+
"type": "object",
|
|
173
|
+
"additionalProperties": false,
|
|
174
|
+
"required": ["id", "kind", "from", "to", "confidence", "evidence"],
|
|
175
|
+
"properties": {
|
|
176
|
+
"id": {
|
|
177
|
+
"type": "string",
|
|
178
|
+
"minLength": 1
|
|
179
|
+
},
|
|
180
|
+
"kind": {
|
|
181
|
+
"$ref": "#/$defs/edgeKind"
|
|
182
|
+
},
|
|
183
|
+
"from": {
|
|
184
|
+
"type": "string",
|
|
185
|
+
"minLength": 1
|
|
186
|
+
},
|
|
187
|
+
"to": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"minLength": 1
|
|
190
|
+
},
|
|
191
|
+
"confidence": {
|
|
192
|
+
"$ref": "#/$defs/confidence"
|
|
193
|
+
},
|
|
194
|
+
"evidence": {
|
|
195
|
+
"type": "array",
|
|
196
|
+
"items": {
|
|
197
|
+
"$ref": "#/$defs/evidence"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
"adapterRun": {
|
|
203
|
+
"type": "object",
|
|
204
|
+
"additionalProperties": false,
|
|
205
|
+
"required": ["id", "version", "status", "detection", "nodeCount", "edgeCount"],
|
|
206
|
+
"properties": {
|
|
207
|
+
"id": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"minLength": 1
|
|
210
|
+
},
|
|
211
|
+
"version": {
|
|
212
|
+
"type": "string",
|
|
213
|
+
"minLength": 1
|
|
214
|
+
},
|
|
215
|
+
"status": {
|
|
216
|
+
"type": "string",
|
|
217
|
+
"enum": ["used", "skipped", "failed"]
|
|
218
|
+
},
|
|
219
|
+
"detection": {
|
|
220
|
+
"type": "object",
|
|
221
|
+
"additionalProperties": false,
|
|
222
|
+
"required": ["confidence", "reason", "evidence"],
|
|
223
|
+
"properties": {
|
|
224
|
+
"confidence": {
|
|
225
|
+
"type": "string",
|
|
226
|
+
"enum": ["none", "low", "medium", "high"]
|
|
227
|
+
},
|
|
228
|
+
"reason": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"minLength": 1
|
|
231
|
+
},
|
|
232
|
+
"evidence": {
|
|
233
|
+
"type": "array",
|
|
234
|
+
"items": {
|
|
235
|
+
"type": "string"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"nodeCount": {
|
|
241
|
+
"type": "integer",
|
|
242
|
+
"minimum": 0
|
|
243
|
+
},
|
|
244
|
+
"edgeCount": {
|
|
245
|
+
"type": "integer",
|
|
246
|
+
"minimum": 0
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"diagnostic": {
|
|
251
|
+
"type": "object",
|
|
252
|
+
"additionalProperties": false,
|
|
253
|
+
"required": ["severity", "message"],
|
|
254
|
+
"properties": {
|
|
255
|
+
"severity": {
|
|
256
|
+
"type": "string",
|
|
257
|
+
"enum": ["info", "warning"]
|
|
258
|
+
},
|
|
259
|
+
"message": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"minLength": 1
|
|
262
|
+
},
|
|
263
|
+
"adapterId": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"minLength": 1
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
"summary": {
|
|
270
|
+
"type": "object",
|
|
271
|
+
"additionalProperties": false,
|
|
272
|
+
"required": ["nodes", "edges", "impactedNodes", "byKind"],
|
|
273
|
+
"properties": {
|
|
274
|
+
"nodes": {
|
|
275
|
+
"type": "integer",
|
|
276
|
+
"minimum": 0
|
|
277
|
+
},
|
|
278
|
+
"edges": {
|
|
279
|
+
"type": "integer",
|
|
280
|
+
"minimum": 0
|
|
281
|
+
},
|
|
282
|
+
"impactedNodes": {
|
|
283
|
+
"type": "integer",
|
|
284
|
+
"minimum": 0
|
|
285
|
+
},
|
|
286
|
+
"byKind": {
|
|
287
|
+
"type": "object",
|
|
288
|
+
"additionalProperties": false,
|
|
289
|
+
"required": ["domain", "flow", "surface", "action", "state", "effect", "contract", "assertion", "fixture", "locator", "source"],
|
|
290
|
+
"properties": {
|
|
291
|
+
"domain": { "type": "integer", "minimum": 0 },
|
|
292
|
+
"flow": { "type": "integer", "minimum": 0 },
|
|
293
|
+
"surface": { "type": "integer", "minimum": 0 },
|
|
294
|
+
"action": { "type": "integer", "minimum": 0 },
|
|
295
|
+
"state": { "type": "integer", "minimum": 0 },
|
|
296
|
+
"effect": { "type": "integer", "minimum": 0 },
|
|
297
|
+
"contract": { "type": "integer", "minimum": 0 },
|
|
298
|
+
"assertion": { "type": "integer", "minimum": 0 },
|
|
299
|
+
"fixture": { "type": "integer", "minimum": 0 },
|
|
300
|
+
"locator": { "type": "integer", "minimum": 0 },
|
|
301
|
+
"source": { "type": "integer", "minimum": 0 }
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qamap-pr-qa
|
|
3
|
-
description: Local-
|
|
3
|
+
description: Local zero-LLM PR QA workflow. Use when an agent is preparing, updating, or reviewing a pull request and needs to derive commit-backed change intent, behavior lifecycle, runner-independent QA scenarios, affected flows, automation drafts, missing evidence, and optional manifest repair guidance without calling a cloud service or LLM.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# QAMap PR QA
|
|
@@ -33,28 +33,30 @@ Use QAMap as a final local QA pass before presenting a pull request for human re
|
|
|
33
33
|
pnpm dlx @ivorycanvas/qamap qa <package-path> --workspace-root . --base <base> --head HEAD
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
4.
|
|
36
|
+
4. Read and verify intent before generating code. In agent format:
|
|
37
|
+
- `intents[]` — commit/diff evidence, confidence, `reviewRequired`, ordered lifecycle, and primary/failure/boundary/state-transition scenarios.
|
|
38
|
+
- If `reviewRequired` is true or the lifecycle conflicts with the PR, ask a human to confirm the intended behavior before promoting a draft.
|
|
39
|
+
- `flows[]` — affected flows with `draft` path, `runnable` status, entry route, capped steps, and selectors.
|
|
40
|
+
- `requiredEvidence[]` — evidence that must exist before the PR can be trusted; `recommendedEvidenceCount` for the rest.
|
|
41
|
+
- `requiredBootstrap[]` — setup steps that block trusting generated drafts.
|
|
42
|
+
- `prChecklist[]` and `commands[]` — checklist lines and validation commands for the handoff.
|
|
43
|
+
|
|
44
|
+
5. If the intent is credible and QAMap prints `First E2E Draft Bootstrap`, create the starter draft instead of stopping at broad QA notes:
|
|
37
45
|
|
|
38
46
|
```sh
|
|
39
47
|
pnpm exec qamap e2e setup . --runner <runner>
|
|
40
48
|
```
|
|
41
49
|
|
|
42
50
|
Use the exact create command from the output when it differs.
|
|
43
|
-
|
|
44
|
-
- `flows[]` — affected flows with `draft` path, `runnable` status, `entry` route, capped `steps` and `selectors`.
|
|
45
|
-
- `requiredEvidence[]` — evidence that must exist before the PR can be trusted; `recommendedEvidenceCount` for the rest.
|
|
46
|
-
- `requiredBootstrap[]` — setup steps that block trusting generated drafts.
|
|
47
|
-
- `firstDraftCommand` — present only when the repo has no test suite; run it to create the first starter draft.
|
|
48
|
-
- `prChecklist[]` and `commands[]` — checklist lines and validation commands for the handoff.
|
|
49
|
-
In markdown format, start from `At a Glance` (affected flows, the single next command, blocking items), then read the `PR Comment Draft`, `Missing Evidence Before Trusting This PR`, and `PR Checklist` sections.
|
|
51
|
+
`firstDraftCommand` is present only when the repo has no test suite; run it to create the first starter draft. In markdown format, start from `At a Glance` and `Change Intent Evidence`, then read the PR comment, missing evidence, and checklist sections.
|
|
50
52
|
6. Include the useful parts in the PR body, review note, or handoff summary.
|
|
51
53
|
|
|
52
54
|
## Output Rules
|
|
53
55
|
|
|
54
56
|
- Treat QAMap output as QA planning evidence, not proof that browser, device, API, or manual QA passed.
|
|
55
|
-
- Preserve
|
|
57
|
+
- Preserve change intent, confidence, lifecycle, QA scenarios, affected flow, suggested E2E/checklist path, missing evidence, and validation command in the handoff.
|
|
56
58
|
- Prefer creating the suggested starter E2E draft over only reporting that a draft is needed.
|
|
57
|
-
-
|
|
59
|
+
- Treat Playwright, Maestro, and manual output as adapters after QA design. Do not let runner selection replace review of the inferred intent and scenarios.
|
|
58
60
|
- If the output is `review only` or `near runnable`, explain what blocks it from becoming trusted regression evidence.
|
|
59
61
|
- If `qamap qa` says no manifest was found, do not stop. The first run is allowed to be manifest-free.
|
|
60
62
|
|
|
@@ -74,6 +76,9 @@ Then humans should review `.qamap/manifest.yaml` and keep only durable team QA l
|
|
|
74
76
|
|
|
75
77
|
```txt
|
|
76
78
|
QAMap QA
|
|
79
|
+
- Change intent and confidence:
|
|
80
|
+
- Behavior lifecycle:
|
|
81
|
+
- Required QA scenarios:
|
|
77
82
|
- Affected flow:
|
|
78
83
|
- Suggested E2E/checklist:
|
|
79
84
|
- Missing evidence:
|