Merge pull request #4614 from open-gsd/test/4518-batch7-loop-hook-point-e2e
This commit is contained in:
@@ -15,10 +15,8 @@
|
||||
"tests/capability-writer.test.cjs",
|
||||
"tests/changeset-new.test.cjs",
|
||||
"tests/check-env.test.cjs",
|
||||
"tests/check-gap-analysis-plan-post-e2e.test.cjs",
|
||||
"tests/check-glossary-refs.test.cjs",
|
||||
"tests/check-predicate.test.cjs",
|
||||
"tests/check-tdd-review-checkpoint-e2e.test.cjs",
|
||||
"tests/cjs-command-router-adapter.test.cjs",
|
||||
"tests/code-review-pipeline-regression.test.cjs",
|
||||
"tests/code-review.test.cjs",
|
||||
@@ -28,7 +26,6 @@
|
||||
"tests/effort-surface-axis.test.cjs",
|
||||
"tests/emitted-ack-trailer.test.cjs",
|
||||
"tests/emitted-attribution.test.cjs",
|
||||
"tests/execute-wave-post-gate-pipeline-e2e.test.cjs",
|
||||
"tests/federated-config.test.cjs",
|
||||
"tests/gate-predicate-evaluator.test.cjs",
|
||||
"tests/gen-context-index.test.cjs",
|
||||
@@ -43,11 +40,6 @@
|
||||
"tests/init.test.cjs",
|
||||
"tests/lint-docs-command-form.test.cjs",
|
||||
"tests/locking-bugs-1909-1916-1925-1927.test.cjs",
|
||||
"tests/loop-hooks-empty-points-e2e.test.cjs",
|
||||
"tests/loop-hooks-ship-pre-e2e.test.cjs",
|
||||
"tests/loop-hooks-verify-post-e2e.test.cjs",
|
||||
"tests/loop-render-hooks.test.cjs",
|
||||
"tests/loop-walk.qa.test.cjs",
|
||||
"tests/milestone-lock.test.cjs",
|
||||
"tests/no-pending-3212-markers.test.cjs",
|
||||
"tests/pattern.test.cjs",
|
||||
@@ -57,12 +49,10 @@
|
||||
"tests/phase6-capstone-conformance.test.cjs",
|
||||
"tests/pi-config-dir-env-override.test.cjs",
|
||||
"tests/plan-phase-stall-detection.test.cjs",
|
||||
"tests/plan-pre-hook-e2e.test.cjs",
|
||||
"tests/plan-review-convergence.test.cjs",
|
||||
"tests/policy-160-route0-resume.test.cjs",
|
||||
"tests/prohibition-enforcement.test.cjs",
|
||||
"tests/prompt-injection-scan.security.test.cjs",
|
||||
"tests/qa/tdd-walk.cjs",
|
||||
"tests/quick-batch.test.cjs",
|
||||
"tests/read-injection-scanner.property.test.cjs",
|
||||
"tests/read-injection-scanner.security.test.cjs",
|
||||
|
||||
@@ -23,6 +23,7 @@ const path = require('path');
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
const GSD_TOOLS = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
@@ -74,7 +75,7 @@ function spawnRenderHooks(point, cwd) {
|
||||
const result = spawnSync(process.execPath, [GSD_TOOLS, 'loop', 'render-hooks', point, '--raw'], {
|
||||
cwd,
|
||||
encoding: 'utf8',
|
||||
timeout: 60000,
|
||||
timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
env: { ...process.env, GSD_SESSION_KEY: '', CODEX_THREAD_ID: '', CLAUDE_SESSION_ID: '' },
|
||||
});
|
||||
return {
|
||||
|
||||
@@ -32,6 +32,7 @@ const { execFileSync } = require('node:child_process');
|
||||
|
||||
const { cleanup, TEST_ENV_BASE } = require('./helpers.cjs');
|
||||
const { gitOrThrow } = require('./helpers/git-fixture.cjs');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
const TOOLS_PATH = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
@@ -147,7 +148,7 @@ function runTools(args, cwd) {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
env: { ...process.env, ...TEST_ENV_BASE },
|
||||
timeout: 60000,
|
||||
timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
});
|
||||
return { success: true, output: stdout.trim(), exitCode: 0, error: '' };
|
||||
} catch (err) {
|
||||
|
||||
@@ -31,6 +31,7 @@ const { spawnSync } = require('node:child_process');
|
||||
|
||||
const { cleanup } = require('./helpers.cjs');
|
||||
const { gitOrThrow } = require('./helpers/git-fixture.cjs');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
const GSD_TOOLS = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
@@ -72,7 +73,7 @@ function runTool(args, { cwd, env = {} } = {}) {
|
||||
cwd: cwd || os.tmpdir(),
|
||||
encoding: 'utf8',
|
||||
env: childEnv,
|
||||
timeout: 60000,
|
||||
timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
});
|
||||
const result = { status: r.status, stdout: r.stdout || '', stderr: r.stderr || '' };
|
||||
if (r.stdout && r.stdout.trim().startsWith('{')) {
|
||||
|
||||
@@ -159,6 +159,35 @@ const FIXTURE_HOOK_TIMEOUT_SECONDS = 5;
|
||||
*/
|
||||
const STAGED_HOOK_SCRIPT_TIMEOUT_MS = 20000;
|
||||
|
||||
/**
|
||||
* A single `gsd-tools.cjs` CLI subcommand invocation, spawned directly (never
|
||||
* via an intermediate shell script), used by a loop/hook-point e2e test. The
|
||||
* command does real in-process work -- capability/config resolution, project
|
||||
* scaffolding, or (for the `check` verbs that inspect git-tracked state) real
|
||||
* git plumbing calls -- but as ONE process with no confirmed nested-subprocess
|
||||
* fan-out, verified per-site by reading each file's own runner function, not
|
||||
* assumed from "hook" in the filename. Representative verbs seen at this
|
||||
* norm's 7 sites: `loop render-hooks <point>`, `check <check-id>`,
|
||||
* `execute <hook-point>`, and `init new-project` (tests/loop-walk.qa.test.cjs's
|
||||
* concurrency test) -- the norm describes the CALL SHAPE (single direct
|
||||
* gsd-tools.cjs spawn, no fan-out), not one specific verb family, so this list
|
||||
* is illustrative, not exhaustive.
|
||||
*
|
||||
* Distinct from `HOOK_FANOUT_TIMEOUT_MS` (a bash-hosted script that itself
|
||||
* shells out to further subprocesses) despite the coincidentally-matching
|
||||
* value: this norm's sites spawn `gsd-tools.cjs` and nothing beneath it.
|
||||
* Distinct from `PROBE_TIMEOUT_MS`: the same underlying `loop render-hooks`
|
||||
* command is ALSO called at `PROBE_TIMEOUT_MS` (15000ms) elsewhere in the
|
||||
* suite against lighter temp-project fixtures -- the two bounds are kept
|
||||
* separate rather than equalized, since this migration never raises or
|
||||
* lowers a value without a fresh bench citation.
|
||||
*
|
||||
* Shared across 7 files in batch #4518 of the ad hoc timeout literal
|
||||
* migration, epic #4445 -- every site independently arrived at this exact
|
||||
* value -- that is why it lives here rather than as a file-local constant.
|
||||
*/
|
||||
const LOOP_HOOK_POINT_CLI_TIMEOUT_MS = 60000;
|
||||
|
||||
module.exports = {
|
||||
PROBE_TIMEOUT_MS,
|
||||
HOOK_FANOUT_TIMEOUT_MS,
|
||||
@@ -170,4 +199,5 @@ module.exports = {
|
||||
QUICK_SPAWN_TIMEOUT_MS,
|
||||
FIXTURE_HOOK_TIMEOUT_SECONDS,
|
||||
STAGED_HOOK_SCRIPT_TIMEOUT_MS,
|
||||
LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@ const path = require('node:path');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
|
||||
const { cleanup, installSpawnEnv } = require('./helpers.cjs');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
const GSD_TOOLS = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
const realRegistry = require('../gsd-core/bin/lib/capability-registry.cjs');
|
||||
@@ -68,7 +69,7 @@ function spawnGsd(args, cwd) {
|
||||
return spawnSync(process.execPath, [GSD_TOOLS, ...args], {
|
||||
cwd: cwd || os.tmpdir(),
|
||||
encoding: 'utf8',
|
||||
timeout: 60000,
|
||||
timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
env: installSpawnEnv(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ const path = require('node:path');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
|
||||
const { cleanup, installSpawnEnv } = require('./helpers.cjs');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
const GSD_TOOLS = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
@@ -55,7 +56,7 @@ const realRegistry = require('../gsd-core/bin/lib/capability-registry.cjs');
|
||||
function runTools(args, opts = {}) {
|
||||
const result = spawnSync(process.execPath, [GSD_TOOLS, ...args], {
|
||||
encoding: 'utf8',
|
||||
timeout: 60000,
|
||||
timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
cwd: opts.cwd || process.cwd(),
|
||||
env: installSpawnEnv(opts.env),
|
||||
});
|
||||
|
||||
@@ -29,6 +29,7 @@ const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
// ── Real modules under test ────────────────────────────────────────────────────
|
||||
const {
|
||||
@@ -57,7 +58,7 @@ function runCli(args, cwd) {
|
||||
cwd,
|
||||
encoding: 'utf8',
|
||||
env: installSpawnEnv(),
|
||||
timeout: 60000,
|
||||
timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -963,6 +963,7 @@ describe('renderLoopHooks', () => {
|
||||
// ─── 9. End-to-end cmdLoopRenderHooks (via gsd-tools subprocess) ─────────────
|
||||
|
||||
const { runNode } = require('./helpers/process-seam.cjs');
|
||||
const { PROBE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
const ROOT = path.resolve(__dirname, '..');
|
||||
const GSD_TOOLS = path.join(ROOT, 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
@@ -970,7 +971,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
test('loop render-hooks plan:pre returns JSON envelope with ui-phase step active', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
const envelope = JSON.parse(result.stdout.trim());
|
||||
@@ -987,7 +988,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
test('loop render-hooks plan:pre with no config.json → ui-phase step active by schema default', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpEmptyProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
const envelope = JSON.parse(result.stdout.trim());
|
||||
@@ -1011,7 +1012,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
'--config-dir',
|
||||
tmpUiDisabledConfigDir,
|
||||
],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
const envelope = JSON.parse(result.stdout.trim());
|
||||
@@ -1027,7 +1028,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
test('loop render-hooks plan:pre with ui_phase=false in config.json → ui-phase step absent', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:pre', '--cwd', tmpFalseConfigProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
const envelope = JSON.parse(result.stdout.trim());
|
||||
@@ -1042,7 +1043,7 @@ describe('cmdLoopRenderHooks end-to-end (via gsd-tools)', () => {
|
||||
test('loop render-hooks invalid-point exits non-zero', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'plan:mid', '--cwd', tmpProjectDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.notStrictEqual(result.exitCode, 0, 'Expected non-zero exit for invalid point');
|
||||
assert.match(result.stderr, /plan:mid|Invalid loop point/);
|
||||
@@ -1085,7 +1086,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
test('--active-cap tdd with tdd_mode=true → stdout trimmed === "true", exit 0', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOnDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
assert.strictEqual(result.stdout.trim(), 'true', 'Expected stdout "true" when tdd_mode=true');
|
||||
@@ -1094,7 +1095,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
test('--active-cap tdd with tdd_mode=false → stdout trimmed === "false", exit 0', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOffDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
assert.strictEqual(result.stdout.trim(), 'false', 'Expected stdout "false" when tdd_mode=false');
|
||||
@@ -1103,7 +1104,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
test('--active-cap <nonexistent-cap> → stdout trimmed === "false", exit 0', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'no-such-capability-xyz', '--cwd', tddOffDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0 for unknown capId. stderr: ' + (result.stderr || ''));
|
||||
assert.strictEqual(result.stdout.trim(), 'false', 'Expected stdout "false" for unknown capId');
|
||||
@@ -1112,7 +1113,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
test('--active-cap with no value → non-zero exit and error message', () => {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', '--cwd', tddOffDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.notStrictEqual(result.exitCode, 0, 'Expected non-zero exit when --active-cap has no value');
|
||||
assert.match(result.stderr, /active-cap/i, 'Expected error message referencing --active-cap');
|
||||
@@ -1122,7 +1123,7 @@ describe('--active-cap flag (loop render-hooks)', () => {
|
||||
// The entire stdout must be just "true" or "false" + newline — no envelope object
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', 'execute:post', '--active-cap', 'tdd', '--cwd', tddOnDir],
|
||||
{ cwd: ROOT, timeoutMs: 15000 },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, 'Expected exit 0. stderr: ' + (result.stderr || ''));
|
||||
// Must be exactly "true" or "false" — not a JSON object/envelope
|
||||
@@ -1251,7 +1252,7 @@ describe('ADR-1244 D2: load-failed capability gates fail OPEN with a loud warnin
|
||||
function renderHooks(overlayHome, point, extraArgs = []) {
|
||||
const result = runNode(
|
||||
[GSD_TOOLS, 'loop', 'render-hooks', point, '--cwd', overlayHome, ...extraArgs],
|
||||
{ cwd: ROOT, timeoutMs: 15000, env: { ...process.env, GSD_HOME: overlayHome } },
|
||||
{ cwd: ROOT, timeoutMs: PROBE_TIMEOUT_MS, env: { ...process.env, GSD_HOME: overlayHome } },
|
||||
);
|
||||
assert.strictEqual(result.exitCode, 0, `Expected exit 0 at ${point}. stderr: ` + (result.stderr || ''));
|
||||
return result;
|
||||
|
||||
@@ -21,6 +21,16 @@ const { promisify } = require('node:util');
|
||||
|
||||
const { createTempDir, cleanup } = require('./helpers.cjs');
|
||||
const { getLiveCommandTokens } = require('./helpers/live-command-registry.cjs');
|
||||
const { LOOP_HOOK_POINT_CLI_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
||||
|
||||
// Bounds a full run of scripts/qa-smell-ratchet.cjs against the real repo
|
||||
// tree (a static-analysis scan, not an installer or a CLI subcommand). The
|
||||
// value numerically coincides with INSTALL_TIMEOUT_MS in
|
||||
// tests/helpers/timeouts.cjs, but describes a different class of work, so
|
||||
// it is kept local rather than reusing that constant. No fresh bench data
|
||||
// justifies a different number, so the pre-existing 120000ms literal is
|
||||
// preserved exactly under this name.
|
||||
const QA_SMELL_RATCHET_SCAN_TIMEOUT_MS = 120000;
|
||||
|
||||
const { KIND, classify } = require('./qa/result.cjs');
|
||||
const { ORACLES, runOracles, SEVERITY } = require('./qa/oracles.cjs');
|
||||
@@ -1617,7 +1627,7 @@ describe('worktree-concurrency (dedicated — trajectory 9 is not expressible as
|
||||
const { stdout } = await execFileAsync(
|
||||
process.execPath,
|
||||
[TOOLS_PATH, '--json-errors', ...argv],
|
||||
{ cwd: dir, encoding: 'utf-8', env, timeout: 60000 },
|
||||
{ cwd: dir, encoding: 'utf-8', env, timeout: LOOP_HOOK_POINT_CLI_TIMEOUT_MS },
|
||||
);
|
||||
return { stdout: stdout.trim(), startedAtMs, finishedAtMs: Date.now() };
|
||||
}
|
||||
@@ -1849,7 +1859,7 @@ describe('qa-smell-ratchet gate (#3597)', () => {
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
['-e', `require(${JSON.stringify(scriptPath)})`],
|
||||
{ cwd: repoRoot, timeout: 120000, encoding: 'utf-8' },
|
||||
{ cwd: repoRoot, timeout: QA_SMELL_RATCHET_SCAN_TIMEOUT_MS, encoding: 'utf-8' },
|
||||
);
|
||||
assert.strictEqual(
|
||||
result.status,
|
||||
|
||||
@@ -33,6 +33,16 @@ const { cleanup } = require('./helpers.cjs');
|
||||
|
||||
const GSD_TOOLS = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
/**
|
||||
* Bounds a single gsd-tools.cjs CLI subcommand invocation — the same call
|
||||
* shape as the shared LOOP_HOOK_POINT_CLI_TIMEOUT_MS constant in
|
||||
* tests/helpers/timeouts.cjs. This file's pre-existing bound (30000ms) is
|
||||
* half that shared norm's value (60000ms) — kept as its own file-local
|
||||
* constant rather than folded into the shared one, since no fresh bench
|
||||
* data justifies raising this file's bound to match.
|
||||
*/
|
||||
const PLAN_PRE_HOOK_CLI_TIMEOUT_MS = 30000;
|
||||
|
||||
// ─── Subprocess helper (isolated env, no ambient GSD_ vars) ───────────────────
|
||||
|
||||
const CLEAN_ENV = {
|
||||
@@ -65,7 +75,7 @@ function runTools(args, cwd, envOverrides = {}) {
|
||||
{
|
||||
cwd: cwd || process.cwd(),
|
||||
encoding: 'utf8',
|
||||
timeout: 30000,
|
||||
timeout: PLAN_PRE_HOOK_CLI_TIMEOUT_MS,
|
||||
env: { ...process.env, ...CLEAN_ENV, ...envOverrides },
|
||||
},
|
||||
);
|
||||
|
||||
@@ -190,6 +190,19 @@ function parseResultSentinel(stdout) {
|
||||
return lineEndIdx === -1 ? stdout.slice(valueStart) : stdout.slice(valueStart, lineEndIdx);
|
||||
}
|
||||
|
||||
// Bounds `bash -c` execution (below) of a REAL fenced bash block extracted
|
||||
// from a workflow markdown file's resolution/dispatch step — a bash-hosted
|
||||
// script that may itself shell out further (e.g. via a `gsd_run` shim), not
|
||||
// a bare `gsd-tools.cjs` CLI subcommand invocation. Numerically coincides
|
||||
// with tests/helpers/timeouts.cjs's `BUILD_TIMEOUT_MS` (hooks-bundle build
|
||||
// via scripts/build-hooks.js, an unrelated operation) and with this batch's
|
||||
// other file-local `PLAN_PRE_HOOK_CLI_TIMEOUT_MS` (a different file, a
|
||||
// different command), but matches neither class — kept local, both
|
||||
// coincidences disclosed rather than silently reusing an unrelated existing
|
||||
// constant. No fresh bench data justifies a different number, so the
|
||||
// pre-existing 30000ms literal is preserved exactly under this name.
|
||||
const TDD_BACKEND_SCRIPT_TIMEOUT_MS = 30000;
|
||||
|
||||
/**
|
||||
* Execute a backend's extracted script for real, via `bash -c`, against
|
||||
* `cwd`. Never throws: a non-zero exit is captured and returned as a normal
|
||||
@@ -217,7 +230,7 @@ function executeBackendScript(script, cwd) {
|
||||
cwd,
|
||||
env: { ...process.env, ...TEST_ENV_BASE, RUNTIME_DIR: REPO_ROOT, GSD_TEST_MODE: '1' },
|
||||
encoding: 'utf8',
|
||||
timeout: 30000,
|
||||
timeout: TDD_BACKEND_SCRIPT_TIMEOUT_MS,
|
||||
});
|
||||
return { success: true, value: parseResultSentinel(stdout), stdout, stderr: '' };
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user