valent-pipeline 0.19.61 → 0.19.63
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/package.json
CHANGED
|
@@ -1951,7 +1951,7 @@ async function runStory(story) {
|
|
|
1951
1951
|
// reworks via the QA-B re-execution alone, then falls through to JUDGE at the cap as usual.
|
|
1952
1952
|
const evGate = await runEvidenceGate(storyId, [])
|
|
1953
1953
|
recordStage('evidence', evGate)
|
|
1954
|
-
const visual = await runVisualGate(storyId, profiles)
|
|
1954
|
+
const visual = await runVisualGate(storyId, profiles, itemType)
|
|
1955
1955
|
recordStage('visual', visual)
|
|
1956
1956
|
phase('Judge')
|
|
1957
1957
|
const decision = await runJudgeGate(storyId, visual, evGate)
|
|
@@ -2234,8 +2234,9 @@ async function runStory(story) {
|
|
|
2234
2234
|
recordStage('evidence', evGate)
|
|
2235
2235
|
|
|
2236
2236
|
// Visual validation (revived PMCP): for ui-profile stories, produce pmcp-evidence.md so JUDGE's
|
|
2237
|
-
// evidence pass has the visual artifact it requires. No-op (returns null) for non-ui stories
|
|
2238
|
-
|
|
2237
|
+
// evidence pass has the visual artifact it requires. No-op (returns null) for non-ui stories, and a
|
|
2238
|
+
// non-blocking N/A for itemType:bug (the QA-A-less bug-fix path mints no checklist — M-192).
|
|
2239
|
+
const visual = await runVisualGate(storyId, profiles, itemType)
|
|
2239
2240
|
recordStage('visual', visual)
|
|
2240
2241
|
|
|
2241
2242
|
phase('Judge')
|
|
@@ -2826,11 +2827,23 @@ async function runStory(story) {
|
|
|
2826
2827
|
// exact trigger QA-A uses to produce the checklist (qa-a/write-spec.md Step 9: `ui` in profiles).
|
|
2827
2828
|
// The agent starts its own dev server: unlike the old always-on topology where QA-B triggered an
|
|
2828
2829
|
// idle PMCP while QA-B's server was up, here the stages are sequential, so PMCP owns its server.
|
|
2829
|
-
async function runVisualGate(sid, storyProfiles) {
|
|
2830
|
+
async function runVisualGate(sid, storyProfiles, sidItemType = 'story') {
|
|
2830
2831
|
if (!storyProfiles.includes('ui')) {
|
|
2831
2832
|
log(`${sid}: no ui profile — visual validation N/A (QA-A wrote no checklist; nothing for PMCP to run)`)
|
|
2832
2833
|
return null
|
|
2833
2834
|
}
|
|
2835
|
+
// QA-A-less bug-fix path (owner-ruled M-192): a bug-fix item runs bug-intake -> Build -> CRITIC ->
|
|
2836
|
+
// QA-B -> Judge and STRUCTURALLY SKIPS the Spec phase, so QA-A never mints a
|
|
2837
|
+
// visual-validation-checklist.md. Running PMCP against a checklist that can NEVER exist yields a
|
|
2838
|
+
// 0/0 block-fail (onMissingMcp inherited from the parent story) on a path with no checklist to
|
|
2839
|
+
// drive — a config contradiction, not a real visual defect. Treat it as a non-blocking N/A: no
|
|
2840
|
+
// visual coverage is lost because the parent story's `revalidate` re-drives the FULL visual gate
|
|
2841
|
+
// on the merged fix (its checklist exists). A FULL story always runs QA-A, so a missing checklist
|
|
2842
|
+
// THERE stays a real, blocking fault — this scopes the gate down ONLY for itemType:bug.
|
|
2843
|
+
if (sidItemType === 'bug') {
|
|
2844
|
+
log(`${sid}: ui profile but itemType:bug — the QA-A-less bug-fix path mints no visual-validation-checklist.md; visual validation N/A (owner-ruled M-192). The parent story's revalidate re-drives the full visual gate on the merged fix.`)
|
|
2845
|
+
return { schema: 1, agent: 'pmcp', story: sid, verdict: 'na', skipped: true, mcpAvailable: null, totalCheckpoints: 0, passed: 0, failed: 0, naCheckpoints: 0, files: [], notes: 'QA-A-less bug-fix path: no visual-validation-checklist.md minted (Spec phase skipped for itemType:bug); visual gate N/A (owner-ruled M-192). The parent story revalidate re-drives the full visual gate on the merged fix.' }
|
|
2846
|
+
}
|
|
2834
2847
|
phase('Visual')
|
|
2835
2848
|
const naMode = visualOnMissingMcp === 'na'
|
|
2836
2849
|
const result = await spawn('PMCP', 'pmcp.md',
|
|
@@ -2920,7 +2933,13 @@ async function runStory(story) {
|
|
|
2920
2933
|
: ''
|
|
2921
2934
|
// A ui story has a PMCP visual pass; tell the evidence agent the result so Step 9 (Verify PMCP
|
|
2922
2935
|
// Evidence) is grounded rather than guessing whether visual evidence should exist.
|
|
2923
|
-
const visualNote = visual
|
|
2936
|
+
const visualNote = visual && visual.skipped
|
|
2937
|
+
? `\n\nThis is a UI-profile BUG-FIX item: the QA-A-less bug-fix path mints no ` +
|
|
2938
|
+
`visual-validation-checklist.md, so PMCP did NOT run and there is NO pmcp-evidence.md. Treat ` +
|
|
2939
|
+
`PMCP evidence as N/A in Step 9 (no checklist ⟹ visual N/A) — do NOT flag its absence as a ` +
|
|
2940
|
+
`missing required file (owner-ruled M-192). The parent story's revalidate re-drives the full ` +
|
|
2941
|
+
`visual gate on the merged fix.`
|
|
2942
|
+
: visual
|
|
2924
2943
|
? `\n\nThis is a UI story: a visual-validation (PMCP) pass already ran and wrote ` +
|
|
2925
2944
|
`pmcp-evidence.md (verdict: ${visual.verdict}, ${visual.passed || 0}/${visual.totalCheckpoints || 0} ` +
|
|
2926
2945
|
`checkpoint(s) passed${visual.mcpAvailable === false ? `, browser MCP unavailable` : ''}). ` +
|
package/pipeline/prompts/pmcp.md
CHANGED
|
@@ -63,7 +63,25 @@ Follow the on-missing-MCP behavior the orchestrator passed in your trigger:
|
|
|
63
63
|
`mcpAvailable: false`, and return — the story proceeds without visual evidence.
|
|
64
64
|
|
|
65
65
|
### Step 3: Execute checkpoints (MCP available)
|
|
66
|
-
Start the dev server.
|
|
66
|
+
Start the dev server.
|
|
67
|
+
|
|
68
|
+
**Pre-flight — assert an INTEGER `devicePixelRatio` before driving any interaction.** Once the server
|
|
69
|
+
is up and you have navigated to the app, evaluate `window.devicePixelRatio`. If it is NOT an integer
|
|
70
|
+
(commonly `1.5` when the host display runs Windows/macOS scaling at 150%), the browser's
|
|
71
|
+
coordinate-based `click()`/`fill()` land OFF-TARGET: Playwright reports the click succeeded but the
|
|
72
|
+
app's `onClick`/`onInput` handlers never fire, so you can screenshot STATIC renders yet can NEVER
|
|
73
|
+
drive an interaction or a multi-step / WS flow. **Do NOT misread this as "the browser MCP cannot drive
|
|
74
|
+
WS events," and do NOT FAIL or `na` the interaction checkpoints** — it is an infrastructure config
|
|
75
|
+
bug, not an app or reachability defect (the e2e test runner pins the scale factor, which is why an
|
|
76
|
+
acceptance e2e can drive the same flow the MCP cannot). STOP and record an **infrastructure blocker**
|
|
77
|
+
in `pmcp-evidence.md` (`verdict: fail`, `mcpAvailable: true`) naming the cause and the fix: the
|
|
78
|
+
browser MCP must launch with **`deviceScaleFactor: 1`** (passing a fixed `--viewport-size` defaults
|
|
79
|
+
the scale factor to 1), a project `.mcp.json` / browser-MCP-config change that needs an MCP/session
|
|
80
|
+
**RESTART** to take effect. Static render-only checkpoints may still be captured; mark every
|
|
81
|
+
interaction-dependent checkpoint blocked-by-DPR, not FAIL. A non-integer DPR is the single most common
|
|
82
|
+
cause of "PMCP can render but can't drive."
|
|
83
|
+
|
|
84
|
+
For each checkpoint: navigate to its route, establish the required state (seed
|
|
67
85
|
data, auth, form values), wait for the expected state using element/network conditions — **never hard
|
|
68
86
|
waits** — capture a screenshot into `{story_output_dir}` using the checklist's filename convention,
|
|
69
87
|
and evaluate it against the pass criteria. Record PASS or FAIL per checkpoint. Stop the server when done.
|
|
@@ -6,7 +6,7 @@ Runs after bug review (Steps 1-4) approves with no P4->P1-P3 escalations.
|
|
|
6
6
|
|
|
7
7
|
Read all inputs, record in `inputsRead`. If any REQUIRED file missing, set blocker and STOP.
|
|
8
8
|
|
|
9
|
-
Required: `execution-report.md`, `traceability-matrix.md`, `bugs.md`, `qa-test-spec.md` — all in `{story_output_dir}/`. Also `pmcp-evidence.md` **if this is a UI story** — i.e. `ui` is in `{testing_profiles}`
|
|
9
|
+
Required: `execution-report.md`, `traceability-matrix.md`, `bugs.md`, `qa-test-spec.md` — all in `{story_output_dir}/`. Also `pmcp-evidence.md` **if this is a UI story** — i.e. `ui` is in `{testing_profiles}` **AND** `visual-validation-checklist.md` exists. The checklist's existence is the operative trigger: a `ui`-profile item with **no** `visual-validation-checklist.md` has PMCP **N/A** — do NOT treat the absence of `pmcp-evidence.md` as a missing required file. This is exactly the **QA-A-less bug-fix path** (an `itemType:bug` fix runs bug-intake → Build → CRITIC → QA-B → Judge and structurally skips the Spec phase, so QA-A mints no checklist); its visual coverage is re-driven in full by the parent story's `revalidate` on the merged fix (owner-ruled M-192). If there is no `ui` profile at all, PMCP evidence is likewise N/A.
|
|
10
10
|
|
|
11
11
|
**Machine evidence (when `stories/{story_id}/evidence/` exists — required in that case):** the newest JSON under `evidence/asserts/` (the deterministic green-gate's verdict), `evidence/pins.jsonl` (which commit each gate reviewed), and the run records under `evidence/runs/` (frozen junit reports + hashes, written only by the CLI). **ATDD stories add** `evidence/atdd-red.json` (the pre-implementation failing run: per-case statuses, the pre-dev SHA, the acceptance-source snapshot hashes) and — for a proven story — `evidence/proof.json` (red run + green run + the CLI-hashed diff between: the story's headline evidence). These are the authoritative numbers — the markdown artifacts are the human-readable companion. If the evidence directory does not exist, this is a LEGACY story: apply the legacy fallbacks below and flag every count as self-reported.
|
|
12
12
|
|