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.1",
15
+ "version": "1.21.2",
16
16
  "author": {
17
17
  "name": "Murat K Ozcan (TEA Creator) & Brian (BMad) Madison"
18
18
  },
@@ -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 "**Recommendation**:" line in BOTH the "## Executive Summary" and the
8
- * "## Decision" section; the two must agree (case-insensitively) and the
9
- * value must be one of the legal enum, to which it is normalized.
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 = /\*\*Recommendation:?\*\*:?[ \t]*([^\n]+)/;
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 "**Recommendation**:" line in the "## ${heading}" section`);
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 "**Recommendation**:" lines (${executive} in Executive Summary vs ${decision} in Decision)`);
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.1",
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));