mtech-ai-local-runner 0.1.40 → 0.1.41

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.
package/README.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.1.41: confirm a cleanup the guardian finished before a late terminate
2
+
3
+ When Codex exits by itself, the owned guardian confirms the cleanup and exits. A busy daemon could then write its
4
+ terminate request to the closed control socket before reading `cleaned`. That write error turned a confirmed cleanup
5
+ into an unconfirmed one and suspended the job. A control socket error alone no longer does that: cleanup is
6
+ confirmed by `cleaned` or by the guardian's exit code 0, which it uses only after sending `cleaned`. Timeouts,
7
+ liveness errors, malformed messages and `unconfirmed` reports still fail closed.
8
+
1
9
  ## 0.1.40: say why the owned guardian could not confirm cleanup
2
10
 
3
11
  When the owned guardian reports an unconfirmed cleanup, the `executor_cleanup` diagnostic now carries fixed
@@ -78,14 +78,18 @@ export function spawnOwnedGuardian(command, args, options) {
78
78
  // Hosts can attach observers after spawn returns without unhandled rejection.
79
79
  void started.catch(() => { });
80
80
  let confirmed = false, spawnFailed = false, protocolFailed = false, buffer = '';
81
- let terminateWritten = false, hostTimeout = false, detail;
81
+ let terminateWritten = false, hostTimeout = false, controlFailed = false, detail;
82
82
  let outcome;
83
83
  let closePromise;
84
84
  const closed = new Promise(resolve => child.once('close', () => { liveness.destroy(); resolve(); }));
85
+ // A guardian that has confirmed and exited closes its control socket; a terminate written late by a
86
+ // busy host then fails, possibly before "cleaned" is read. That write error alone is not a protocol
87
+ // failure: the guardian exits 0 only after it sent "cleaned" (or after a spawn failure owned nothing).
85
88
  control.on('error', () => { if (!confirmed && !spawnFailed)
86
- protocolFailed = true; });
89
+ controlFailed = true; });
87
90
  liveness.on('error', () => { if (!confirmed && !spawnFailed)
88
91
  protocolFailed = true; });
92
+ const cleanedByExit = () => controlFailed && !protocolFailed && child.exitCode === 0 && child.signalCode === null;
89
93
  control.on('data', (chunk) => {
90
94
  buffer += chunk;
91
95
  if (buffer.length > 8192) {
@@ -140,7 +144,7 @@ export function spawnOwnedGuardian(command, args, options) {
140
144
  this.signal(immediate);
141
145
  closePromise = new Promise((resolve, reject) => {
142
146
  const timer = setTimeout(() => { protocolFailed = true; hostTimeout = true; liveness.destroy(); reject(new Error('Provider process group cleanup could not be confirmed')); }, 5500);
143
- void closed.then(() => { clearTimeout(timer); if (protocolFailed || !confirmed)
147
+ void closed.then(() => { clearTimeout(timer); if (protocolFailed || !(confirmed || cleanedByExit()))
144
148
  reject(new Error('Provider process group cleanup could not be confirmed'));
145
149
  else
146
150
  resolve(); });
@@ -149,15 +153,17 @@ export function spawnOwnedGuardian(command, args, options) {
149
153
  },
150
154
  /** Fixed cleanup observations after an unconfirmed cleanup; empty once cleanup is confirmed. */
151
155
  cleanupObservations() {
152
- if (confirmed && !protocolFailed)
156
+ if ((confirmed || cleanedByExit()) && !protocolFailed)
153
157
  return [];
154
- if (!protocolFailed && !hostTimeout)
158
+ if (!protocolFailed && !hostTimeout && !controlFailed)
155
159
  return [];
156
160
  const observed = [terminateWritten ? 'cleanup_guardian_terminate_written' : 'cleanup_guardian_terminate_not_written'];
157
161
  if (hostTimeout)
158
162
  observed.push('cleanup_guardian_host_timeout');
163
+ if (controlFailed)
164
+ observed.push('cleanup_guardian_control_failed');
159
165
  if (!detail) {
160
- if (!hostTimeout)
166
+ if (!hostTimeout && protocolFailed)
161
167
  observed.push('cleanup_guardian_protocol_failed');
162
168
  return observed;
163
169
  }
@@ -20,7 +20,7 @@ export const STARTUP_OBSERVATIONS = Object.freeze([
20
20
  'cleanup_exec_tools_revoke_failed', 'cleanup_job_tools_revoke_failed', 'cleanup_stdin_end_failed', 'cleanup_process_terminate_failed',
21
21
  'cleanup_tool_server_close_failed', 'cleanup_timeout',
22
22
  // The owned guardian's own account of an unconfirmed cleanup (fixed words, no PIDs or paths).
23
- 'cleanup_guardian_terminate_written', 'cleanup_guardian_terminate_not_written', 'cleanup_guardian_host_timeout', 'cleanup_guardian_protocol_failed',
23
+ 'cleanup_guardian_terminate_written', 'cleanup_guardian_terminate_not_written', 'cleanup_guardian_host_timeout', 'cleanup_guardian_control_failed', 'cleanup_guardian_protocol_failed',
24
24
  'cleanup_guardian_trigger_terminate', 'cleanup_guardian_trigger_root_exit', 'cleanup_guardian_trigger_lost', 'cleanup_guardian_trigger_output_error', 'cleanup_guardian_trigger_spawn_error',
25
25
  'cleanup_guardian_term_sent', 'cleanup_guardian_term_eperm', 'cleanup_guardian_term_esrch', 'cleanup_guardian_term_not_needed',
26
26
  'cleanup_guardian_kill_sent', 'cleanup_guardian_kill_eperm', 'cleanup_guardian_kill_esrch', 'cleanup_guardian_kill_not_needed',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mtech-ai-local-runner",
3
- "version": "0.1.40",
3
+ "version": "0.1.41",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "bin": {