[GH-ISSUE #4653] [Bug] GDB close labels a valid session ID invalid when inferior disposition is required #2424

Closed
opened 2026-10-17 21:04:27 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4653

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Process capture or runtime observation

Observed behavior

With a simulated MI provider, start_gdb_session {} succeeds and gdb_console runs a simulated inferior that stops at a breakpoint. close_gdb_session then returns invalid_request / invalid_input, assigns invalid_value to the returned session_id, and recommends "Correct the listed arguments and retry." The session remains ready. After a simulated kill, close succeeds with the identical ID.

Refusing close while a live inferior lacks a verified durable TTY is correct. The defect is classifying that lifecycle precondition as a rejected caller argument. The nested message already explains the disposition requirement, but the canonical classification and remediation point at argument correction. This was executed through the production MCP registration, manager, MI parser and error projection on both tested builds. Real GNU GDB and a real inferior were not tested.

Reproduction

Prepare either the source checkout with its pinned toolchain, locked dependencies (npm ci) and compiled runtime (npm run build:cached), or the published npm tarball extracted into a directory with its production dependencies installed. Run the following from that build's package root using the Node executable named below. It uses an isolated HOME and a disposable Node process that emits MI3; it does not execute a target program. The explicit Linux manager option exercises REA's Linux-only GDB lifecycle on the macOS test host.

The check starts three sessions per build, attempts close twice per session while a live group is reported, verifies the session remains ready, applies simulated disposition, and verifies same-ID close succeeds. Each build produced six incorrect diagnostics and three successful same-ID recoveries.

REA_REPRO_DIR="$(mktemp -d)"
REA_NODE="$(node -p process.execPath)"
mkdir "$REA_REPRO_DIR/home"
env -i HOME="$REA_REPRO_DIR/home" PATH="$(dirname "$REA_NODE"):/usr/bin:/bin" REA_REPRO_DIR="$REA_REPRO_DIR" "$REA_NODE" --input-type=module <<'JS'
import assert from 'node:assert/strict';
import { createRequire } from 'node:module';
import { pathToFileURL } from 'node:url';
import { writeFile, rm } from 'node:fs/promises';
const root = process.env.REA_REPRO_DIR;
const provider = `${root}/fake-gdb.mjs`;
await writeFile(provider, `#!${process.execPath}\nimport { createInterface } from 'node:readline';
let live = false;
process.stdout.write('(gdb)\\n');
createInterface({input: process.stdin}).on('line', line => {
  const token = /^(\\d+)/.exec(line)?.[1];
  if (!token) return;
  if (line.includes('console "run"')) {
    live = true;
    process.stdout.write(\`\${token}^running\\n*stopped,reason="breakpoint-hit",thread-id="1"\\n(gdb)\\n\`);
    return;
  }
  if (line.includes('console "kill"')) live = false;
  const result = line.includes('list-thread-groups')
    ? (live ? 'done,groups=[{id="i1",type="process",pid="4242"}]' : 'done,groups=[]')
    : 'done';
  process.stdout.write(\`\${token}^\${result}\\n(gdb)\\n\`);
  if (line.includes('-gdb-exit')) process.exit(0);
});
`, { mode: 0o700 });
const require = createRequire(`${process.cwd()}/package.json`);
const { Client, InMemoryTransport } = await import(require.resolve('@modelcontextprotocol/client'));
const { McpServer } = await import(require.resolve('@modelcontextprotocol/server'));
const load = p => import(pathToFileURL(`${process.cwd()}/dist/${p}.js`).href);
const { GdbSessionManager, commandMayChangeInferiorOutput } = await load('gdb/GdbSessionManager');
const { registerGdbTools } = await load('server/registerGdbTools');
const { createToolResultDelivery } = await load('server/toolResult');
const { silentLogger } = await load('logger');
const manager = new GdbSessionManager({ platform: 'linux', environment: { ...process.env, REA_GDB_COMMAND: provider } });
const server = new McpServer({ name: 'close-repro', version: '1' });
registerGdbTools(server, manager, silentLogger, createToolResultDelivery(undefined));
const client = new Client({ name: 'close-repro', version: '1' });
const [ct, st] = InMemoryTransport.createLinkedPair();
const ids = [];
const call = (name, args) => client.callTool({ name, arguments: args });
try {
  await server.connect(st); await client.connect(ct);
  assert.equal(commandMayChangeInferiorOutput('run'), false);
  for (let iteration = 0; iteration < 3; iteration++) {
    const start = await call('start_gdb_session', {});
    assert(!start.isError);
    const session_id = start.structuredContent.session_id; ids.push(session_id);
    for (const command of ['file ./program', 'run']) assert(!(await call('gdb_console', { session_id, command })).isError);
    for (let attempt = 0; attempt < 2; attempt++) {
      const close = await call('close_gdb_session', { session_id });
      assert(close.isError);
      const error = JSON.parse(close.content.find(c => c.type === 'text').text).error;
      assert.equal(error.code, 'invalid_request'); assert.equal(error.category, 'invalid_input');
      assert.deepEqual(error.details.issues[0].path, ['session_id']);
      assert.equal(error.details.issues[0].reason, 'invalid_value');
      assert.equal(error.remediation.action, 'Correct the listed arguments and retry.');
      if (!iteration && !attempt) console.log(JSON.stringify(error));
    }
    const status = await call('gdb_session_status', { session_id });
    assert.equal(status.structuredContent.state, 'ready');
    assert.equal(status.structuredContent.inferior_tty_verified, false);
    assert(!(await call('gdb_console', { session_id, command: 'kill' })).isError);
    const recovered = await call('close_gdb_session', { session_id });
    assert(!recovered.isError); assert.equal(recovered.structuredContent.target_state, 'none_observed');
    assert.equal(manager.status(session_id), undefined);
  }
  console.log('PASS: 3 sessions, 6 incorrect close diagnostics, 3 same-ID recoveries');
} finally {
  for (const id of ids) { await manager.execute(id, 'kill'); await manager.close(id); }
  await Promise.allSettled([client.close(), server.close()]);
  await manager.closeAll(); await rm(provider, { force: true });
}
JS
rmdir "$REA_REPRO_DIR/home" "$REA_REPRO_DIR"

Expected behavior

Preserve the session and report that inferior disposition is required before close, with guidance to apply an appropriate disposition through gdb_console and retry using the unchanged ID. The lifecycle guide documents that recovery, and the close tool contract describes a disposition-required outcome. The input-error contract defines issue entries as correction metadata for rejected caller arguments; this accepted, still-usable identifier is not invalid. No particular replacement error code is required.

Impact and scope

The typed diagnostic directs clients following its code, category, issue path or remediation toward correcting an accepted identifier instead of resolving inferior state. The nested message provides useful recovery guidance, ownership stays retained, and simulated recovery succeeded. No target termination or data loss was observed. Frequency with real GNU GDB and downstream client behavior are unmeasured.

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: A bounded state-dependent failure misclassifies a still-usable identifier as invalid input, giving machine-readable recovery guidance for the wrong cause.
  • Workaround status: available
  • Workaround basis: Follow the documented inferior-disposition recovery through gdb_console and retry close with the same ID. Simulated kill and retry succeeded in all six sessions across both builds; callers must choose a disposition appropriate for their actual target.

REA version

Current main source commit 150e996a86, package version 6.5.0; separately tested the published npm rea-agents@6.5.0 tarball (SHA-1 7ea5e6f669bc18c45dbf5dba653edaa1ada07ab3), which the registry reports as latest.

Runtime and platform

Node v24.18.0; Darwin arm64. The source build used pinned npm 11.16.0. No GDB executable was installed. The manager's explicit platform: 'linux' option enabled the Linux-only code path for the synthetic provider; this does not establish native macOS support or real-provider output generation.

Target and artifact context

Synthetic MI3 for one stopped, live inferior represented by fixture PID 4242. No real target process, executable artifact, TTY or remote service is used. Only the disposable Node provider process is spawned.

Interface

MCP

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

  • Expected source: docs/reverse-engineering-tools.md:33 (disposition then retry); src/contracts/gdbToolContracts.ts:100 (close outcome); src/domain/analysisErrorCore.ts:79 (rejected-argument metadata), in the source build above.
  • Failure source: Executed MCP results below; src/gdb/GdbSessionManager.ts:1317-1327 selects the input error after the valid session lookup and live-group inventory.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Both runs exited 0 with the same first error and aggregate result. Completeness here concerns the synthetic production-boundary check; real-provider incidence remains untested.

{
  "code": "invalid_request",
  "category": "invalid_input",
  "message": "Analysis input is invalid. Check the arguments and try again.",
  "retryable": true,
  "remediation": {"action": "Correct the listed arguments and retry."},
  "details": {
    "operation": "close_gdb_session",
    "issues": [{
      "path": ["session_id"],
      "reason": "invalid_value",
      "message": "Live GDB thread groups remain and no verified durable inferior TTY is configured. Select a safe disposition through the GDB console or restart with inferior_tty before closing."
    }]
  }
}
PASS: 3 sessions, 6 incorrect close diagnostics, 3 same-ID recoveries

Typed outcome or recovery expected

Keep refusing close while inferior disposition is unresolved and retain the ready session, but return a lifecycle or target-state diagnostic with disposition recovery, without an invalid_value issue for session_id. A repeated close with unchanged state must remain refused. After appropriate disposition, close with the same ID must succeed. The current same-ID recovery control demonstrates that argument correction is unnecessary.

Analysis or suspected cause

Source-derived reasoning: the manager finds the retained session, parses a complete untruncated live-group inventory, then constructs AnalysisInputError when live groups remain and inferiorTtyVerified is false. The standard projection consequently supplies invalid-input classification and argument-correction remediation. Production server composition creates this manager and the registered close handler forwards the accepted ID to it after mutation admission. Starting without inferior_tty leaves verification false. The synthetic fixture uses ^running followed by a breakpoint *stopped event while keeping a live group; a run that exits naturally or times out is a different condition.

Additional context

Open and closed issues and pull requests were searched. Related #3993 concerns quoted inferior-inventory parsing, #4011 concerns recorded-crash launcher identity, and #3656 concerns provider scope; none reports this valid-ID classification error. No known-good version was established.

Originally created by @coygeek on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4653 ### Before submitting - [X] I searched the open and closed issues for a related report. - [X] I removed credentials, tokens, private paths, and sensitive target data. ### Area Process capture or runtime observation ### Observed behavior With a simulated MI provider, `start_gdb_session {}` succeeds and `gdb_console` runs a simulated inferior that stops at a breakpoint. `close_gdb_session` then returns `invalid_request` / `invalid_input`, assigns `invalid_value` to the returned `session_id`, and recommends "Correct the listed arguments and retry." The session remains ready. After a simulated `kill`, close succeeds with the identical ID. Refusing close while a live inferior lacks a verified durable TTY is correct. The defect is classifying that lifecycle precondition as a rejected caller argument. The nested message already explains the disposition requirement, but the canonical classification and remediation point at argument correction. This was executed through the production MCP registration, manager, MI parser and error projection on both tested builds. Real GNU GDB and a real inferior were not tested. ### Reproduction Prepare either the source checkout with its pinned toolchain, locked dependencies (`npm ci`) and compiled runtime (`npm run build:cached`), or the published npm tarball extracted into a directory with its production dependencies installed. Run the following from that build's package root using the Node executable named below. It uses an isolated HOME and a disposable Node process that emits MI3; it does not execute a target program. The explicit Linux manager option exercises REA's Linux-only GDB lifecycle on the macOS test host. The check starts three sessions per build, attempts close twice per session while a live group is reported, verifies the session remains ready, applies simulated disposition, and verifies same-ID close succeeds. Each build produced six incorrect diagnostics and three successful same-ID recoveries. ```sh REA_REPRO_DIR="$(mktemp -d)" REA_NODE="$(node -p process.execPath)" mkdir "$REA_REPRO_DIR/home" env -i HOME="$REA_REPRO_DIR/home" PATH="$(dirname "$REA_NODE"):/usr/bin:/bin" REA_REPRO_DIR="$REA_REPRO_DIR" "$REA_NODE" --input-type=module <<'JS' import assert from 'node:assert/strict'; import { createRequire } from 'node:module'; import { pathToFileURL } from 'node:url'; import { writeFile, rm } from 'node:fs/promises'; const root = process.env.REA_REPRO_DIR; const provider = `${root}/fake-gdb.mjs`; await writeFile(provider, `#!${process.execPath}\nimport { createInterface } from 'node:readline'; let live = false; process.stdout.write('(gdb)\\n'); createInterface({input: process.stdin}).on('line', line => { const token = /^(\\d+)/.exec(line)?.[1]; if (!token) return; if (line.includes('console "run"')) { live = true; process.stdout.write(\`\${token}^running\\n*stopped,reason="breakpoint-hit",thread-id="1"\\n(gdb)\\n\`); return; } if (line.includes('console "kill"')) live = false; const result = line.includes('list-thread-groups') ? (live ? 'done,groups=[{id="i1",type="process",pid="4242"}]' : 'done,groups=[]') : 'done'; process.stdout.write(\`\${token}^\${result}\\n(gdb)\\n\`); if (line.includes('-gdb-exit')) process.exit(0); }); `, { mode: 0o700 }); const require = createRequire(`${process.cwd()}/package.json`); const { Client, InMemoryTransport } = await import(require.resolve('@modelcontextprotocol/client')); const { McpServer } = await import(require.resolve('@modelcontextprotocol/server')); const load = p => import(pathToFileURL(`${process.cwd()}/dist/${p}.js`).href); const { GdbSessionManager, commandMayChangeInferiorOutput } = await load('gdb/GdbSessionManager'); const { registerGdbTools } = await load('server/registerGdbTools'); const { createToolResultDelivery } = await load('server/toolResult'); const { silentLogger } = await load('logger'); const manager = new GdbSessionManager({ platform: 'linux', environment: { ...process.env, REA_GDB_COMMAND: provider } }); const server = new McpServer({ name: 'close-repro', version: '1' }); registerGdbTools(server, manager, silentLogger, createToolResultDelivery(undefined)); const client = new Client({ name: 'close-repro', version: '1' }); const [ct, st] = InMemoryTransport.createLinkedPair(); const ids = []; const call = (name, args) => client.callTool({ name, arguments: args }); try { await server.connect(st); await client.connect(ct); assert.equal(commandMayChangeInferiorOutput('run'), false); for (let iteration = 0; iteration < 3; iteration++) { const start = await call('start_gdb_session', {}); assert(!start.isError); const session_id = start.structuredContent.session_id; ids.push(session_id); for (const command of ['file ./program', 'run']) assert(!(await call('gdb_console', { session_id, command })).isError); for (let attempt = 0; attempt < 2; attempt++) { const close = await call('close_gdb_session', { session_id }); assert(close.isError); const error = JSON.parse(close.content.find(c => c.type === 'text').text).error; assert.equal(error.code, 'invalid_request'); assert.equal(error.category, 'invalid_input'); assert.deepEqual(error.details.issues[0].path, ['session_id']); assert.equal(error.details.issues[0].reason, 'invalid_value'); assert.equal(error.remediation.action, 'Correct the listed arguments and retry.'); if (!iteration && !attempt) console.log(JSON.stringify(error)); } const status = await call('gdb_session_status', { session_id }); assert.equal(status.structuredContent.state, 'ready'); assert.equal(status.structuredContent.inferior_tty_verified, false); assert(!(await call('gdb_console', { session_id, command: 'kill' })).isError); const recovered = await call('close_gdb_session', { session_id }); assert(!recovered.isError); assert.equal(recovered.structuredContent.target_state, 'none_observed'); assert.equal(manager.status(session_id), undefined); } console.log('PASS: 3 sessions, 6 incorrect close diagnostics, 3 same-ID recoveries'); } finally { for (const id of ids) { await manager.execute(id, 'kill'); await manager.close(id); } await Promise.allSettled([client.close(), server.close()]); await manager.closeAll(); await rm(provider, { force: true }); } JS rmdir "$REA_REPRO_DIR/home" "$REA_REPRO_DIR" ``` ### Expected behavior Preserve the session and report that inferior disposition is required before close, with guidance to apply an appropriate disposition through `gdb_console` and retry using the unchanged ID. The lifecycle guide documents that recovery, and the close tool contract describes a disposition-required outcome. The input-error contract defines issue entries as correction metadata for rejected caller arguments; this accepted, still-usable identifier is not invalid. No particular replacement error code is required. ### Impact and scope The typed diagnostic directs clients following its code, category, issue path or remediation toward correcting an accepted identifier instead of resolving inferior state. The nested message provides useful recovery guidance, ownership stays retained, and simulated recovery succeeded. No target termination or data loss was observed. Frequency with real GNU GDB and downstream client behavior are unmeasured. - Impact level: P2 - Assessment status: supported - Impact basis: A bounded state-dependent failure misclassifies a still-usable identifier as invalid input, giving machine-readable recovery guidance for the wrong cause. - Workaround status: available - Workaround basis: Follow the documented inferior-disposition recovery through `gdb_console` and retry close with the same ID. Simulated kill and retry succeeded in all six sessions across both builds; callers must choose a disposition appropriate for their actual target. ### REA version Current main source commit 150e996a86f2bec4982ba87f37bf502a8d5e8214, package version 6.5.0; separately tested the published npm `rea-agents@6.5.0` tarball (SHA-1 `7ea5e6f669bc18c45dbf5dba653edaa1ada07ab3`), which the registry reports as latest. ### Runtime and platform Node v24.18.0; Darwin arm64. The source build used pinned npm 11.16.0. No GDB executable was installed. The manager's explicit `platform: 'linux'` option enabled the Linux-only code path for the synthetic provider; this does not establish native macOS support or real-provider output generation. ### Target and artifact context Synthetic MI3 for one stopped, live inferior represented by fixture PID 4242. No real target process, executable artifact, TTY or remote service is used. Only the disposable Node provider process is spawned. ### Interface MCP ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence - Expected source: `docs/reverse-engineering-tools.md:33` (disposition then retry); `src/contracts/gdbToolContracts.ts:100` (close outcome); `src/domain/analysisErrorCore.ts:79` (rejected-argument metadata), in the source build above. - Failure source: Executed MCP results below; `src/gdb/GdbSessionManager.ts:1317-1327` selects the input error after the valid session lookup and live-group inventory. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Both runs exited 0 with the same first error and aggregate result. Completeness here concerns the synthetic production-boundary check; real-provider incidence remains untested. ```json { "code": "invalid_request", "category": "invalid_input", "message": "Analysis input is invalid. Check the arguments and try again.", "retryable": true, "remediation": {"action": "Correct the listed arguments and retry."}, "details": { "operation": "close_gdb_session", "issues": [{ "path": ["session_id"], "reason": "invalid_value", "message": "Live GDB thread groups remain and no verified durable inferior TTY is configured. Select a safe disposition through the GDB console or restart with inferior_tty before closing." }] } } ``` ```text PASS: 3 sessions, 6 incorrect close diagnostics, 3 same-ID recoveries ``` ### Typed outcome or recovery expected Keep refusing close while inferior disposition is unresolved and retain the ready session, but return a lifecycle or target-state diagnostic with disposition recovery, without an `invalid_value` issue for `session_id`. A repeated close with unchanged state must remain refused. After appropriate disposition, close with the same ID must succeed. The current same-ID recovery control demonstrates that argument correction is unnecessary. ### Analysis or suspected cause Source-derived reasoning: the manager finds the retained session, parses a complete untruncated live-group inventory, then constructs `AnalysisInputError` when live groups remain and `inferiorTtyVerified` is false. The standard projection consequently supplies invalid-input classification and argument-correction remediation. Production server composition creates this manager and the registered close handler forwards the accepted ID to it after mutation admission. Starting without `inferior_tty` leaves verification false. The synthetic fixture uses `^running` followed by a breakpoint `*stopped` event while keeping a live group; a run that exits naturally or times out is a different condition. ### Additional context Open and closed issues and pull requests were searched. Related [#3993](https://github.com/morluto/rea/issues/3993) concerns quoted inferior-inventory parsing, [#4011](https://github.com/morluto/rea/issues/4011) concerns recorded-crash launcher identity, and [#3656](https://github.com/morluto/rea/issues/3656) concerns provider scope; none reports this valid-ID classification error. No known-good version was established.
Author
Owner

@morluto commented on GitHub (Oct 18, 2026):

Fixed in 847472acf5 on main. Adapted Luigi Pinna's classification proposal #4732 (e3a3734f7a), with verified co-author attribution.

A live-inferior/no-durable-TTY refusal now uses capability_unavailable / unavailable with canonical gnu.gdb identity. The session remains retained and ready; no detach, termination or owned-debugger shutdown is introduced by this change. The producing error supplies the action: use gdb_console with the same session_id to explicitly dispose of each remaining inferior, then retry close. retryable=true uses the existing contract meaning that the same request can succeed after the condition clears; it is not an instruction to repeat before disposition. Unknown IDs still produce invalid_request / invalid_input.

Structural cleanup: added optional producer-owned remediationAction to AnalysisCapabilityUnavailableError and its existing presentation boundary. This preserves contextual recovery without downstream inspection of reason text or a GDB-specific projection branch. Default capability classification/remediation remains unchanged when the option is omitted. Replaced the superseded manager substring assertion with stronger registered-MCP repeated-refusal/recovery checks; other MI, TTY, capacity, permission and ownership coverage remains.

Executed evidence: both new SDK recovery cases failed on the original main diagnostic. Final 235 tests across seven files passed: GDB manager coverage, review regressions, command queue/capacity, cancellation MCP, real owned Node MI fixture close/recovery, and domain error projection (including explicit remediation under both retry dispositions). Each new MCP case refuses close twice, retains the same ready session, executes caller-selected simulated kill/detach, then closes with the identical ID; an unknown UUID remains invalid. The fixture now rejects unmodeled commands and flushes its final MI response before exiting.

Typecheck/lint, docs check with five conformance tests, discovery of all 1,574 test files, source reviews and commit/push hooks passed. One legacy text-only assertion initially failed after diagnostic wording changed; it was superseded by the stronger MCP tests described above, then the complete selected run passed.

Limits: the registered tools, manager, MI parser/projection and owned Node process are real; GNU GDB, a real inferior, native Linux/Windows behavior and natural occurrence frequency were not exercised. No performance or actual host/model token measurements or optimization claim. Heavy CPU/string-limit stress and profiling stayed stopped. PR #4732 itself was not merged or declared human-ready; the broader audit remains incomplete.

Publication update: rebased over the unrelated signed-64-bit TOML repair #4937; all 235 selected tests and typecheck/lint reran successfully on the final rebased tree. GDB/error-contract/test file contents match the previously reviewed tree.

<!-- gh-comment-id:6244539635 --> @morluto commented on GitHub (Oct 18, 2026): Fixed in 847472acf5cf4a28379e828dcd0fe55ac99d7c07 on main. Adapted Luigi Pinna's classification proposal #4732 (e3a3734f7a1a66f4f6fe89a95f540d76afa14608), with verified co-author attribution. A live-inferior/no-durable-TTY refusal now uses capability_unavailable / unavailable with canonical gnu.gdb identity. The session remains retained and ready; no detach, termination or owned-debugger shutdown is introduced by this change. The producing error supplies the action: use gdb_console with the same session_id to explicitly dispose of each remaining inferior, then retry close. retryable=true uses the existing contract meaning that the same request can succeed after the condition clears; it is not an instruction to repeat before disposition. Unknown IDs still produce invalid_request / invalid_input. Structural cleanup: added optional producer-owned remediationAction to AnalysisCapabilityUnavailableError and its existing presentation boundary. This preserves contextual recovery without downstream inspection of reason text or a GDB-specific projection branch. Default capability classification/remediation remains unchanged when the option is omitted. Replaced the superseded manager substring assertion with stronger registered-MCP repeated-refusal/recovery checks; other MI, TTY, capacity, permission and ownership coverage remains. Executed evidence: both new SDK recovery cases failed on the original main diagnostic. Final 235 tests across seven files passed: GDB manager coverage, review regressions, command queue/capacity, cancellation MCP, real owned Node MI fixture close/recovery, and domain error projection (including explicit remediation under both retry dispositions). Each new MCP case refuses close twice, retains the same ready session, executes caller-selected simulated kill/detach, then closes with the identical ID; an unknown UUID remains invalid. The fixture now rejects unmodeled commands and flushes its final MI response before exiting. Typecheck/lint, docs check with five conformance tests, discovery of all 1,574 test files, source reviews and commit/push hooks passed. One legacy text-only assertion initially failed after diagnostic wording changed; it was superseded by the stronger MCP tests described above, then the complete selected run passed. Limits: the registered tools, manager, MI parser/projection and owned Node process are real; GNU GDB, a real inferior, native Linux/Windows behavior and natural occurrence frequency were not exercised. No performance or actual host/model token measurements or optimization claim. Heavy CPU/string-limit stress and profiling stayed stopped. PR #4732 itself was not merged or declared human-ready; the broader audit remains incomplete. Publication update: rebased over the unrelated signed-64-bit TOML repair #4937; all 235 selected tests and typecheck/lint reran successfully on the final rebased tree. GDB/error-contract/test file contents match the previously reviewed tree.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2424
No description provided.