bmad-method-test-architecture-enterprise 2.0.2-next.0 → 2.0.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.
@@ -31,7 +31,7 @@
31
31
  "name": "bmad-method-test-architecture-enterprise",
32
32
  "source": "./",
33
33
  "description": "Master Test Architect module for quality strategy, test generation in red and expand modes with automatic run-and-heal, combined framework and CI setup, CI/CD quality gates, and structured testing education. The CI and ATDD commands remain available with existing customizations. Part of the BMad Method ecosystem.",
34
- "version": "2.0.2-next.0",
34
+ "version": "2.0.2",
35
35
  "author": {
36
36
  "name": "Murat K Ozcan (TEA Creator) & Brian (BMad) Madison"
37
37
  },
@@ -291,9 +291,12 @@ function buildPrompt({
291
291
  'fragment set, Pact MCP) instead of inferring the flags.',
292
292
  'The two *_installed values above were read from the project manifest by the CLI. Do not re-derive them, and do',
293
293
  'not open package.json for them: they are the second half of each mandate gate, stated here for the same reason the flags are.',
294
- 'One read is allowed beyond the review set and the context list: when H10 turns on whether a static type checker',
295
- '(mypy, pyright, tsc) runs in CI, read the CI workflow files (.github/workflows) and the scripts they invoke',
296
- '(package.json scripts, a Makefile) for that one question. The row cannot be judged without it.',
294
+ 'One evidence check is allowed beyond the review set and the context list: when H10 turns on whether a static',
295
+ 'type checker (mypy, pyright, tsc) checks a type-assignability test, read the CI workflow files',
296
+ '(.github/workflows), scripts they invoke (package.json scripts, a Makefile), and the checker configuration',
297
+ '(such as pyproject.toml, mypy.ini, pyrightconfig.json, or tsconfig.json) for that question. Resolve the',
298
+ "checker's effective file scope: a CI command without file targets may use the config's files or include list.",
299
+ 'H10 fires if the checker never reads the reviewed test file, even when CI runs the checker.',
297
300
  'tea_execution_mode and tea_capability_probe are the orchestration pair step-03-quality-evaluation.md branches on,',
298
301
  'resolved the same way the fragment keys above are: an explicit CLI flag, then [modules.tea] in the project config,',
299
302
  'then the module default. Both are stated because step-03 reads both, and "auto" with probing off resolves to',
@@ -344,7 +347,8 @@ function buildPrompt({
344
347
  JSON.stringify(contextFiles, null, 2),
345
348
  '---END CONTEXT---',
346
349
  '',
347
- 'Read only the artifacts named above. Never go looking for a story, PRD, or test design that the context list did',
350
+ 'Read only the artifacts named above, except for the H10 checker evidence allowed earlier.',
351
+ 'Never go looking for a story, PRD, or test design that the context list did',
348
352
  'not name: with no human present to confirm what you found, an unrequested artifact is a nondeterministic input.',
349
353
  '',
350
354
  'Context may RAISE a finding — a test that contradicts its acceptance criteria, a changed code path no assertion',
@@ -38,6 +38,7 @@ const path = require('node:path');
38
38
  const { spawn, spawnSync } = require('node:child_process');
39
39
  const { AGENT_ADAPTERS, DEFAULT_CAPABILITIES, RUNNER_CAPABILITIES, bridgedArgsRefused, resolveModel } = require('./agent-adapters');
40
40
  const { launchPrefix } = require('./isolation-primitives');
41
+ const { neutralizeWorkflowCommands } = require('./safe-log');
41
42
 
42
43
  const STDERR_TAIL_LINES = 20;
43
44
  const DEFAULT_TIMEOUT_MS = 1_800_000; // 30 minutes
@@ -280,7 +281,7 @@ function agentAnswer({ outcome, stdout, stderr }, { command: spawned, agentComma
280
281
  if (outcome.status !== 0) {
281
282
  const stderrTail = (stderr || '').trim().split('\n').slice(-STDERR_TAIL_LINES).join('\n');
282
283
  if (stderrTail) {
283
- console.error(`Agent stderr (last ${STDERR_TAIL_LINES} lines):\n${stderrTail}`);
284
+ console.error(`Agent stderr (last ${STDERR_TAIL_LINES} lines):\n${neutralizeWorkflowCommands(stderrTail)}`);
284
285
  }
285
286
  // A signal-killed child (OOM, an external kill, anything outside the
286
287
  // ETIMEDOUT case already handled above) reports status as null; naming
@@ -0,0 +1,7 @@
1
+ /** Keep captured agent text from becoming a GitHub Actions workflow command. */
2
+ function neutralizeWorkflowCommands(value) {
3
+ // The runner recognizes legacy ##[ commands anywhere in a log line.
4
+ return String(value).replaceAll('##[', '# #[').replaceAll('::', ': :');
5
+ }
6
+
7
+ module.exports = { neutralizeWorkflowCommands };
@@ -80,6 +80,7 @@ const {
80
80
  const { computeConventionBaseline } = require('./lib/convention-baseline');
81
81
  const { loadRegistryRowSeverities } = require('./lib/registry-rows');
82
82
  const { runAgent } = require('./lib/run-agent');
83
+ const { neutralizeWorkflowCommands } = require('./lib/safe-log');
83
84
  const { AGENT_ADAPTERS, resolveModel, resolvedModelFromAnswer, agentAnswerText } = require('./lib/agent-adapters');
84
85
  const { withIsolation, selectBackend } = require('./lib/isolate');
85
86
  const { resolveTeaConfig, PACT_MCP_VALUES, EXECUTION_MODE_VALUES } = require('./lib/resolve-tea-config');
@@ -287,7 +288,8 @@ function boundedAgentOutputTail(value) {
287
288
  .split(/\r?\n/)
288
289
  .slice(-AGENT_OUTPUT_TAIL_LINES)
289
290
  .join('\n');
290
- return byLines.length > AGENT_OUTPUT_TAIL_CHARS ? byLines.slice(-AGENT_OUTPUT_TAIL_CHARS) : byLines;
291
+ const tail = byLines.length > AGENT_OUTPUT_TAIL_CHARS ? byLines.slice(-AGENT_OUTPUT_TAIL_CHARS) : byLines;
292
+ return neutralizeWorkflowCommands(tail);
291
293
  }
292
294
 
293
295
  function printMissingReportDiagnostics(agentResult, agent) {
@@ -302,6 +304,11 @@ function printMissingReportDiagnostics(agentResult, agent) {
302
304
  }
303
305
  }
304
306
 
307
+ function printAgentFailureDiagnostics(error, agent) {
308
+ const tail = boundedAgentOutputTail(agentAnswerText(agent, error.stdout));
309
+ if (tail) console.error(`Agent stdout on failure (bounded tail):\n${tail}`);
310
+ }
311
+
305
312
  /**
306
313
  * Validate a --waive-until value: it must be a real calendar date in YYYY-MM-DD
307
314
  * form, strictly after the local today (day granularity, local timezone).
@@ -1801,6 +1808,7 @@ async function runReview(session) {
1801
1808
  fail(EXIT.AGENT_OR_PARSE_ERROR, error.message);
1802
1809
  }
1803
1810
  if (error.code === 'AGENT_FAILED' || error.code === 'REPORT_MISSING' || error.code === 'REPORT_UNPARSEABLE') {
1811
+ if (error.code === 'AGENT_FAILED') printAgentFailureDiagnostics(error, options.agent);
1804
1812
  if (attempt < retries) {
1805
1813
  console.error(`tea-test-review: ${error.message}`);
1806
1814
  const retryNotice = `attempt ${attempt + 1} of ${retries + 1} failed (exit 3); retrying.`;
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": "2.0.2-next.0",
4
+ "version": "2.0.2",
5
5
  "description": "Master Test Architect for quality strategy, test automation, and release gates",
6
6
  "keywords": [
7
7
  "bmad",
@@ -2,7 +2,7 @@
2
2
 
3
3
  [bmod]
4
4
  code = "tea"
5
- version = "2.0.2-next.0"
5
+ version = "2.0.2"
6
6
  update_source = "github:bmad-code-org/bmad-method-test-architecture-enterprise/skills"
7
7
  skills = [
8
8
  "bmad-tea",