bmad-method-test-architecture-enterprise 1.21.1 → 1.21.2
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.
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "bmad-method-test-architecture-enterprise",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Master Test Architect module for quality strategy, test automation, CI/CD quality gates, and structured testing education. Part of the BMad Method ecosystem.",
|
|
15
|
-
"version": "1.21.
|
|
15
|
+
"version": "1.21.2",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "Murat K Ozcan (TEA Creator) & Brian (BMad) Madison"
|
|
18
18
|
},
|
package/cli/lib/parse-report.js
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* Strict, section-aware schema (every element is mandatory):
|
|
5
5
|
* - YAML frontmatter declaring workflowType: testarch-test-review and a
|
|
6
6
|
* non-empty stepsCompleted list.
|
|
7
|
-
* - A "
|
|
8
|
-
* "## Decision" section; the two must agree
|
|
9
|
-
* value must be one of the legal enum, to which
|
|
7
|
+
* - A "Recommendation:" line, with or without Markdown bolding, in BOTH the
|
|
8
|
+
* "## Executive Summary" and the "## Decision" section; the two must agree
|
|
9
|
+
* (case-insensitively) and the value must be one of the legal enum, to which
|
|
10
|
+
* it is normalized.
|
|
10
11
|
* - "**Quality Score**: N/100" with N an integer in 0-100.
|
|
11
12
|
* - A "**Total Violations**:" line with all four severity counts.
|
|
12
13
|
* - A "## Quality Score Breakdown" ledger whose arithmetic reproduces the
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
const path = require('node:path');
|
|
42
43
|
|
|
43
44
|
const RECOMMENDATION_ENUM = ['Approve', 'Approve with Comments', 'Request Changes', 'Block'];
|
|
44
|
-
const RECOMMENDATION_LINE =
|
|
45
|
+
const RECOMMENDATION_LINE = /^[ \t]*(?:\*\*Recommendation\*\*:|\*\*Recommendation:\*\*|Recommendation:)[ \t]*([^\r\n]+?)[ \t]*$/m;
|
|
45
46
|
const CONTEXT_BASIS_ENUM = ['none', 'pr_diff', 'pr_diff_truncated'];
|
|
46
47
|
const CONTEXT_BASIS_LINE_SOURCE = String.raw`^[ \t]*\*\*Context Basis:?\*\*:?[ \t]*([^\r\n]+)[ \t]*$`;
|
|
47
48
|
const CONTEXT_WAIVERS_LINE_SOURCE = String.raw`^[ \t]*\*\*Context Waivers Applied:?\*\*:?[ \t]*([^\r\n]+)[ \t]*$`;
|
|
@@ -148,7 +149,7 @@ function recommendationFromSection(text, heading) {
|
|
|
148
149
|
}
|
|
149
150
|
const match = section.match(RECOMMENDATION_LINE);
|
|
150
151
|
if (!match) {
|
|
151
|
-
unparseable(`Report is missing the "
|
|
152
|
+
unparseable(`Report is missing the "Recommendation:" line in the "## ${heading}" section`);
|
|
152
153
|
}
|
|
153
154
|
return normalizeRecommendation(match[1], `"## ${heading}"`);
|
|
154
155
|
}
|
|
@@ -514,7 +515,7 @@ function parseReport(reportText, runContract = {}) {
|
|
|
514
515
|
const executive = recommendationFromSection(text, 'Executive Summary');
|
|
515
516
|
const decision = recommendationFromSection(text, 'Decision');
|
|
516
517
|
if (executive !== decision) {
|
|
517
|
-
unparseable(`Report has conflicting "
|
|
518
|
+
unparseable(`Report has conflicting "Recommendation:" lines (${executive} in Executive Summary vs ${decision} in Decision)`);
|
|
518
519
|
}
|
|
519
520
|
|
|
520
521
|
const scoreMatch = text.match(SCORE_PATTERN);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-method-test-architecture-enterprise",
|
|
4
|
-
"version": "1.21.
|
|
4
|
+
"version": "1.21.2",
|
|
5
5
|
"description": "Master Test Architect for quality strategy, test automation, and release gates",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bmad",
|
|
@@ -592,6 +592,28 @@ async function runTests() {
|
|
|
592
592
|
assert(false, 'colon-in-bold fixture parses', error.message);
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
+
// Regression: a live Codex CI run produced the correct Decision value but
|
|
596
|
+
// omitted Markdown bolding from that one label. Styling cannot invalidate
|
|
597
|
+
// an otherwise complete verdict whose two Recommendation values agree.
|
|
598
|
+
try {
|
|
599
|
+
const source = readFixture('reports', 'request-changes.md');
|
|
600
|
+
const liveCodexShape = source.replace(
|
|
601
|
+
'## Decision\n\n**Recommendation**: Request Changes',
|
|
602
|
+
'## Decision\n\nRecommendation: Request Changes',
|
|
603
|
+
);
|
|
604
|
+
if (liveCodexShape === source) {
|
|
605
|
+
throw new Error('plain Recommendation regression setup did not modify the fixture');
|
|
606
|
+
}
|
|
607
|
+
const plainDecision = parseReport(liveCodexShape);
|
|
608
|
+
assert(
|
|
609
|
+
plainDecision.recommendation === 'Request Changes' && plainDecision.qualityScore === 63,
|
|
610
|
+
'plain Decision Recommendation from live Codex output parses',
|
|
611
|
+
JSON.stringify(plainDecision),
|
|
612
|
+
);
|
|
613
|
+
} catch (error) {
|
|
614
|
+
assert(false, 'plain Decision Recommendation from live Codex output parses', error.message);
|
|
615
|
+
}
|
|
616
|
+
|
|
595
617
|
try {
|
|
596
618
|
const lowercase = parseReport(readFixture('reports', 'lowercase.md'));
|
|
597
619
|
assert(lowercase.recommendation === 'Approve', 'lowercase fixture: "approve" normalizes to Approve', JSON.stringify(lowercase));
|