@amaster.ai/employee-runtime-connector 0.1.1-beta.61 → 0.1.1-beta.63

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.
@@ -333,6 +333,47 @@ function createPiOutputRetentionCompactor() {
333
333
  };
334
334
  }
335
335
 
336
+ // src/amaster-runtime-daemon/pi-run-exit-closure-guard.mjs
337
+ function readText(value) {
338
+ return typeof value === "string" && value.trim() ? value.trim() : null;
339
+ }
340
+ function parsePiEvent(line) {
341
+ const text = String(line ?? "").trim();
342
+ if (!text.startsWith("{")) return null;
343
+ try {
344
+ const parsed = JSON.parse(text);
345
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
346
+ } catch {
347
+ return null;
348
+ }
349
+ }
350
+ function createPiRunExitClosureToolErrorGuard() {
351
+ let stdoutBuffer = "";
352
+ let terminalDiagnostic = null;
353
+ return {
354
+ write(stream, chunk) {
355
+ if (terminalDiagnostic || stream !== "stdout") return terminalDiagnostic;
356
+ const combined = `${stdoutBuffer}${String(chunk ?? "")}`;
357
+ const lines = combined.split(/\r?\n/);
358
+ stdoutBuffer = lines.pop() ?? "";
359
+ if (stdoutBuffer.length > 256 * 1024) stdoutBuffer = stdoutBuffer.slice(-256 * 1024);
360
+ for (const line of lines) {
361
+ const event = parsePiEvent(line);
362
+ if (event?.type !== "tool_execution_end" || event.isError !== true) continue;
363
+ terminalDiagnostic = {
364
+ kind: "run_exit_closure_tool_error",
365
+ enforced: true,
366
+ reason: "first_closure_tool_error",
367
+ toolName: readText(event.toolName) ?? readText(event.tool),
368
+ toolCallId: readText(event.toolCallId) ?? readText(event.tool_call_id)
369
+ };
370
+ return terminalDiagnostic;
371
+ }
372
+ return null;
373
+ }
374
+ };
375
+ }
376
+
336
377
  // src/amaster-runtime-daemon/pi-executor-access.mjs
337
378
  import {
338
379
  chmodSync,
@@ -10397,7 +10438,7 @@ var source_acquisition_compatibility_default = {
10397
10438
  };
10398
10439
 
10399
10440
  // src/amaster-runtime-daemon.mjs
10400
- var CONNECTOR_VERSION = "0.1.1-beta.61";
10441
+ var CONNECTOR_VERSION = "0.1.1-beta.63";
10401
10442
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
10402
10443
  var SOURCE_ACQUISITION_CAPABILITY = source_acquisition_compatibility_default.profileVersion;
10403
10444
  var SOURCE_ACQUISITION_PROFILE_VERSION = source_acquisition_compatibility_default.profileVersion;
@@ -12785,6 +12826,7 @@ function runExecutor(command, args, options) {
12785
12826
  let completionOutputHasFinalAssistantText = null;
12786
12827
  let outputFlood = null;
12787
12828
  let argumentAmplification = null;
12829
+ let toolExecutionGuard = null;
12788
12830
  let memoryLimit = null;
12789
12831
  let timer = null;
12790
12832
  let rssTimer = null;
@@ -12841,6 +12883,7 @@ function runExecutor(command, args, options) {
12841
12883
  retainedOutputBytes: { ...retainedOutputBytes },
12842
12884
  outputFlood,
12843
12885
  argumentAmplification,
12886
+ toolExecutionGuard,
12844
12887
  memoryLimit,
12845
12888
  completionOutputType,
12846
12889
  completionOutputHasFinalAssistantText,
@@ -12970,6 +13013,11 @@ function runExecutor(command, args, options) {
12970
13013
  argumentAmplification = diagnostic;
12971
13014
  requestStop("tool_argument_amplification");
12972
13015
  };
13016
+ const killForToolExecutionGuard = (diagnostic) => {
13017
+ if (settled || outputFlood || toolExecutionGuard) return;
13018
+ toolExecutionGuard = diagnostic;
13019
+ requestStop("tool_execution_guard");
13020
+ };
12973
13021
  const killForMemoryLimit = (rssBytes) => {
12974
13022
  if (settled || memoryLimit) return;
12975
13023
  memoryLimit = {
@@ -13001,7 +13049,11 @@ function runExecutor(command, args, options) {
13001
13049
  const text = chunk.toString("utf8");
13002
13050
  outputBytes.stdout += chunk.length;
13003
13051
  const outputControl = options.onOutput?.("stdout", text, chunk.length);
13004
- if (outputControl?.enforced === true) killForArgumentAmplification(outputControl);
13052
+ if (outputControl?.kind === "run_exit_closure_tool_error") {
13053
+ killForToolExecutionGuard(outputControl);
13054
+ } else if (outputControl?.enforced === true) {
13055
+ killForArgumentAmplification(outputControl);
13056
+ }
13005
13057
  maybeSchedulePiCompletionDrain(text);
13006
13058
  const retainedText = piOutputRetentionCompactor?.write(text) ?? text;
13007
13059
  retainedOutputBytes.stdout += Buffer.byteLength(retainedText);
@@ -13398,6 +13450,9 @@ function runExitClosurePrompt(state) {
13398
13450
  const response = asRecord(state.completionResponse);
13399
13451
  const summary = truncateText(readString(asRecord(state.candidateResult).summary) ?? "", 1200);
13400
13452
  const issueId = commandIssueId(command) ?? "unknown";
13453
+ const runId = commandRunId(command) ?? "unknown";
13454
+ const closureStrategy = readString(response.closureStrategy) ?? "select_issue_disposition";
13455
+ const allowedActions = Array.isArray(response.allowedActions) ? response.allowedActions.filter((value) => typeof value === "string") : [];
13401
13456
  return [
13402
13457
  "# AMaster Run-Exit Disposition Closure",
13403
13458
  "This is a bounded status-only closure turn for the same command and heartbeat run.",
@@ -13405,8 +13460,10 @@ function runExitClosurePrompt(state) {
13405
13460
  `Completion reason: ${readString(response.reasonCode) ?? "successful_run_missing_state"}`,
13406
13461
  summary ? `Primary turn summary: ${summary}` : null,
13407
13462
  "Do not perform more business work, edit files, create artifacts/documents/children/plans, or mutate company/profile/milestone state.",
13408
- "Use exactly one runtime_action.submit mutation. Choose update_parent, create_interaction (not suggest_tasks), or add_comment only when a comment is truly the intended exit path.",
13409
- "A comment alone does not establish completion. Prefer update_parent with the truthful done, blocked, review/input, or todo-continuation state.",
13463
+ closureStrategy === "record_work_disposition" ? "Effective closure action for this turn: record_work_disposition only." : `Server-allowed closure actions: ${allowedActions.join(", ") || "none"}.`,
13464
+ "Use exactly one runtime_action.submit mutation.",
13465
+ closureStrategy === "record_work_disposition" ? "The Server selected record_work_disposition as the only closure strategy. For this already-productive source run, record execute_inline with truthful source-run evidence; do not also mutate issue status or create an interaction. After command terminalization, the Server writes the Business Outcome and owns the matching Board review or terminal-state transition." : "The Server selected an Issue disposition closure. Choose update_parent, create_interaction (not suggest_tasks), or add_comment only when a comment is truly the intended exit path. A comment alone does not establish completion.",
13466
+ closureStrategy === "record_work_disposition" ? `Use evidenceRefs ["run:${runId}", "command:${state.commandId}"], structure.deliverableType "runtime_command_result", structure.deliverableKey "runtime-command-${state.commandId}", and structure.acceptanceMethodCode "governed_business_outcome". Supply a concise truthful reason based only on the primary turn summary.` : null,
13410
13467
  `The idempotencyKey must be runtime-command-closure:${state.commandId}.`,
13411
13468
  "Do not call runtime_action.plan or runtime_action.commit. Stop immediately after the one allowed mutation returns."
13412
13469
  ].filter(Boolean).join("\n\n");
@@ -13580,6 +13637,7 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
13580
13637
  executorKind,
13581
13638
  protectedValues
13582
13639
  );
13640
+ const closureToolErrorGuard = executorKind === "pi" ? createPiRunExitClosureToolErrorGuard() : null;
13583
13641
  try {
13584
13642
  const managedMcpClosureBaseline = executorKind === "pi" ? restoreManagedPiRunExitClosureBaseline(
13585
13643
  executionConfig.runExitClosureBaseline,
@@ -13607,6 +13665,7 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
13607
13665
  onOutput: (stream, chunk, rawBytes) => {
13608
13666
  noteActiveRunOutput(command, stream, chunk, rawBytes);
13609
13667
  liveOutputLogger.write(stream, chunk);
13668
+ return closureToolErrorGuard?.write(stream, chunk) ?? null;
13610
13669
  }
13611
13670
  });
13612
13671
  } finally {
@@ -13618,6 +13677,8 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
13618
13677
  const hasOutputFlood = Boolean(readString(outputFlood.stream) && readNumber(outputFlood.bytes, 0) > 0);
13619
13678
  const memoryLimit = asRecord(execution.memoryLimit);
13620
13679
  const hasMemoryLimit = readNumber(memoryLimit.rssBytes, 0) > 0;
13680
+ const toolExecutionGuard = asRecord(execution.toolExecutionGuard);
13681
+ const hasToolExecutionGuard = toolExecutionGuard.enforced === true && readString(toolExecutionGuard.kind) === "run_exit_closure_tool_error";
13621
13682
  const parsed = parseExecutorTurnOutput(executorKind, execution, liveOutputLogger, hasOutputFlood);
13622
13683
  const mcpToolResults = dedupeGovernedMcpToolResults([
13623
13684
  ...Array.isArray(parsed.mcpToolResults) ? parsed.mcpToolResults.map(asRecord) : [],
@@ -13636,14 +13697,14 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
13636
13697
  allowMissingTurnEnd: completionOutputStopped || Boolean(cleanupDisposition),
13637
13698
  allowMissingAssistantOutput: false
13638
13699
  }) : null;
13639
- const parsedError = hasOutputFlood ? "Run-exit closure output exceeded the configured limit" : hasMemoryLimit ? "Run-exit closure exceeded the configured memory limit" : execution.timedOut ? "Run-exit closure timed out" : execution.spawnError ?? piInvalidOutputError ?? parsedForValidation.errorMessage ?? ((execution.exitCode ?? 0) === 0 || cleanupDisposition ? null : `Run-exit closure exited with code ${execution.exitCode ?? "unknown"}`);
13700
+ const parsedError = hasOutputFlood ? "Run-exit closure output exceeded the configured limit" : hasMemoryLimit ? "Run-exit closure exceeded the configured memory limit" : hasToolExecutionGuard ? "Run-exit closure stopped after the first rejected or invalid tool attempt" : execution.timedOut ? "Run-exit closure timed out" : execution.spawnError ?? piInvalidOutputError ?? parsedForValidation.errorMessage ?? ((execution.exitCode ?? 0) === 0 || cleanupDisposition ? null : `Run-exit closure exited with code ${execution.exitCode ?? "unknown"}`);
13640
13701
  const effectiveToolsAttestation = executorKind === "pi" ? inspectManagedPiRunExitClosureAttestation(
13641
13702
  executionConfig.runExitClosureBaseline,
13642
13703
  { commandId: state.commandId, runId: commandRunId(command) }
13643
13704
  ) : { status: "not_required" };
13644
13705
  const effectiveToolsError = executorKind === "pi" && executionConfig.runExitClosureBaseline && effectiveToolsAttestation.status !== "attested" ? `Run-exit closure effective-tools attestation ${effectiveToolsAttestation.status}` : null;
13645
13706
  const closureError = parsedError ?? effectiveToolsError;
13646
- const succeeded = execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && (execution.exitCode === 0 || completionOutputStopped || Boolean(cleanupDisposition)) && !execution.timedOut && !execution.spawnError && !closureError;
13707
+ const succeeded = execution.cancelled !== true && !hasOutputFlood && !hasMemoryLimit && !hasToolExecutionGuard && (execution.exitCode === 0 || completionOutputStopped || Boolean(cleanupDisposition)) && !execution.timedOut && !execution.spawnError && !closureError;
13647
13708
  await ingestLog(config, command, "system", succeeded ? "info" : "error", succeeded ? "Run-exit disposition closure turn completed" : `Run-exit disposition closure turn failed: ${closureError}`, {
13648
13709
  presentationKind: "run_exit_disposition_closure",
13649
13710
  closureAttempt: 1,
@@ -13666,6 +13727,7 @@ async function executeRunExitClosureTurn(config, inputState, options = {}) {
13666
13727
  outputTelemetry,
13667
13728
  cleanupDisposition,
13668
13729
  effectiveToolsAttestation,
13730
+ ...hasToolExecutionGuard ? { toolExecutionGuard } : {},
13669
13731
  toolResults: mcpToolResults.slice(0, 10).map((result3) => ({
13670
13732
  status: readString(result3.status),
13671
13733
  toolName: readString(result3.toolName) ?? readString(result3.name) ?? readString(asRecord(result3.runtimeAction).toolName),
@@ -6,7 +6,7 @@ import { basename, dirname, join, resolve } from "node:path";
6
6
  import { homedir, hostname } from "node:os";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
9
- const CONNECTOR_VERSION = "0.1.1-beta.61";
9
+ const CONNECTOR_VERSION = "0.1.1-beta.63";
10
10
 
11
11
  const CAPABILITIES = [
12
12
  "remote_registration",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/employee-runtime-connector",
3
- "version": "0.1.1-beta.61",
3
+ "version": "0.1.1-beta.63",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",