@amaster.ai/employee-runtime-connector 0.1.1-beta.15 → 0.1.1-beta.16

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.
@@ -1913,12 +1913,12 @@ function syncAmasterProviderSettings(agentDir, executorEnv) {
1913
1913
  const settings = readJsonFile(settingsPath);
1914
1914
  const baseUrl = readString(executorEnv.AMASTER_PROVIDER_BASE_URL);
1915
1915
  const imageGenBaseUrl = imageGenBaseUrlFromProviderBaseUrl(baseUrl);
1916
+ const managedApiKey = managedApiKeyConfigValue(executorEnv, apiKey);
1916
1917
  let changed = false;
1917
1918
  const imageGen = settings["pi-image-gen"];
1918
1919
  if (isRecord(imageGen) && isRecord(imageGen.customProviders) && isRecord(imageGen.customProviders.amaster)) {
1919
1920
  const customProviders = imageGen.customProviders;
1920
1921
  const imageGenAmaster = { ...asRecord(customProviders.amaster) };
1921
- const managedApiKey = managedApiKeyConfigValue(executorEnv, apiKey);
1922
1922
  if (imageGenAmaster.apiKey !== managedApiKey) {
1923
1923
  imageGenAmaster.apiKey = managedApiKey;
1924
1924
  changed = true;
@@ -1941,6 +1941,32 @@ function syncAmasterProviderSettings(agentDir, executorEnv) {
1941
1941
  }
1942
1942
  };
1943
1943
  }
1944
+ const videoGen = settings["pi-video-gen"];
1945
+ if (isRecord(videoGen) && isRecord(videoGen.customProviders) && isRecord(videoGen.customProviders.newapi)) {
1946
+ const customProviders = videoGen.customProviders;
1947
+ const videoGenNewapi = { ...asRecord(customProviders.newapi) };
1948
+ if (videoGenNewapi.apiKey !== managedApiKey) {
1949
+ videoGenNewapi.apiKey = managedApiKey;
1950
+ changed = true;
1951
+ }
1952
+ if (baseUrl && videoGenNewapi.baseUrl !== baseUrl) {
1953
+ videoGenNewapi.baseUrl = baseUrl;
1954
+ changed = true;
1955
+ }
1956
+ const videoGenHeaders = syncManagedBillingHeaders(videoGenNewapi.headers, executorEnv);
1957
+ if (JSON.stringify(videoGenHeaders) !== JSON.stringify(videoGenNewapi.headers)) {
1958
+ if (videoGenHeaders) videoGenNewapi.headers = videoGenHeaders;
1959
+ else delete videoGenNewapi.headers;
1960
+ changed = true;
1961
+ }
1962
+ settings["pi-video-gen"] = {
1963
+ ...asRecord(videoGen),
1964
+ customProviders: {
1965
+ ...customProviders,
1966
+ newapi: videoGenNewapi
1967
+ }
1968
+ };
1969
+ }
1944
1970
  const webAccess = settings["pi-web-access"];
1945
1971
  if (isRecord(webAccess) && isRecord(webAccess.providers)) {
1946
1972
  const webProviders = webAccess.providers;
@@ -2317,6 +2343,10 @@ export default function amasterEffectiveToolsAttestor(pi) {
2317
2343
 
2318
2344
  const expectedEntries = Array.isArray(manifest.entries) ? manifest.entries : [];
2319
2345
  if (expectedEntries.length === 0) throw new Error("effective tool manifest is empty");
2346
+ const proxyMode = manifest.proxyMode ?? "forbidden";
2347
+ if (proxyMode !== "required" && proxyMode !== "forbidden") {
2348
+ throw new Error("effective tool proxy mode is invalid");
2349
+ }
2320
2350
  const expectedByName = new Map(expectedEntries.map((entry) => [entry.name, entry]));
2321
2351
  if (expectedByName.size !== expectedEntries.length) throw new Error("effective tool manifest has duplicate names");
2322
2352
  for (const entry of expectedEntries) {
@@ -2337,7 +2367,8 @@ export default function amasterEffectiveToolsAttestor(pi) {
2337
2367
  activeToolNames.sort();
2338
2368
  const activeToolNameSet = new Set(activeToolNames);
2339
2369
  const proxyPresent = allTools.some((tool) => tool.name === "mcp");
2340
- const nonCatalogTools = activeToolNames.filter((name) => !expectedByName.has(name));
2370
+ // Hybrid keeps Pi builtins active, so catalog drift applies only to adapter tools;
2371
+ // direct_typed constrains the complete active surface separately via toolAllowlist.
2341
2372
  const adapterTools = allTools.filter((tool) => sourceIsMcpAdapter(tool.sourceInfo));
2342
2373
  const directTools = adapterTools.filter((tool) => tool.name !== "mcp" && activeToolNameSet.has(tool.name)).map((tool) => ({
2343
2374
  name: tool.name,
@@ -2356,14 +2387,16 @@ export default function amasterEffectiveToolsAttestor(pi) {
2356
2387
  : [];
2357
2388
  });
2358
2389
  const effectiveSetHash = toolSetHash(directTools);
2359
- if (proxyPresent || nonCatalogTools.length > 0 || missing.length > 0 || unexpected.length > 0 || schemaMismatches.length > 0) {
2360
- throw new Error("effective tool surface mismatch: proxy=" + proxyPresent + " nonCatalog=" + nonCatalogTools.join(",") + " missing=" + missing.join(",") + " unexpected=" + unexpected.join(",") + " schemas=" + schemaMismatches.map((entry) => entry.name).join(","));
2390
+ const proxyMismatch = proxyMode === "required" ? !proxyPresent : proxyPresent;
2391
+ if (proxyMismatch || missing.length > 0 || unexpected.length > 0 || schemaMismatches.length > 0) {
2392
+ throw new Error("effective tool surface mismatch: proxyMode=" + proxyMode + " proxy=" + proxyPresent + " missing=" + missing.join(",") + " unexpected=" + unexpected.join(",") + " schemas=" + schemaMismatches.map((entry) => entry.name).join(","));
2361
2393
  }
2362
2394
  if (effectiveSetHash !== manifest.effectiveSetHash) throw new Error("effective tool set hash mismatch");
2363
2395
  receipt = {
2364
2396
  schemaVersion: SCHEMA_VERSION,
2365
2397
  status: "attested",
2366
2398
  mode,
2399
+ proxyMode,
2367
2400
  proxyPresent,
2368
2401
  effectiveSetHash,
2369
2402
  effectiveTools: directTools.sort((left, right) => left.name.localeCompare(right.name)),
@@ -2409,6 +2442,7 @@ export default function amasterEffectiveToolsAttestor(pi) {
2409
2442
 
2410
2443
  // src/amaster-runtime-daemon/pi-managed-mcp-profile.mjs
2411
2444
  var MANAGED_PI_MCP_TOOL_MODE = "proxy_only";
2445
+ var MANAGED_PI_HYBRID_MCP_TOOL_MODE = "hybrid";
2412
2446
  var MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE = "direct_typed";
2413
2447
  var MANAGED_PI_MCP_ARGS_NORMALIZATION = "json_string_control_characters_v1";
2414
2448
  var MANAGED_PI_MCP_ARGS_NORMALIZER_FILENAME = "amaster-mcp-args-normalizer.js";
@@ -2435,6 +2469,12 @@ function createManagedPiMcpProfileApi(options = {}) {
2435
2469
  "amaster.read_company_diagnosis",
2436
2470
  "amaster.publish_company_diagnosis_brief"
2437
2471
  ]);
2472
+ const HYBRID_DIRECT_TYPED_V1_TOOL_NAMES = /* @__PURE__ */ new Set([
2473
+ "amaster.read_company_snapshot",
2474
+ "runtime_action.describe",
2475
+ "amaster.read_issue_document",
2476
+ "amaster.read_issue_evidence"
2477
+ ]);
2438
2478
  const PROVIDER_SAFE_TOOL_NAME = /^[A-Za-z][A-Za-z0-9_-]*$/;
2439
2479
  const PI_BUILTIN_TOOL_NAMES = /* @__PURE__ */ new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "mcp"]);
2440
2480
  const MINIMUM_PI_VERSION = [0, 73, 1];
@@ -2685,20 +2725,21 @@ function createManagedPiMcpProfileApi(options = {}) {
2685
2725
  excludeTools: definition.excludeTools
2686
2726
  }));
2687
2727
  }
2688
- function validateDirectCatalog(gateway) {
2728
+ function validateDirectCatalog(gateway, mcpToolMode) {
2689
2729
  const catalog = record8(gateway.toolCatalog);
2690
2730
  if (catalog.schemaVersion !== DIRECT_CATALOG_SCHEMA_VERSION) {
2691
2731
  throw new Error("pi_managed_mcp_invalid: direct tool catalog schema mismatch");
2692
2732
  }
2693
2733
  const tools = Array.isArray(catalog.tools) ? catalog.tools.map(record8) : [];
2694
- if (tools.length !== DIRECT_TYPED_V1_TOOL_NAMES.size) {
2734
+ const admittedToolNames = mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE ? HYBRID_DIRECT_TYPED_V1_TOOL_NAMES : DIRECT_TYPED_V1_TOOL_NAMES;
2735
+ if (tools.length !== admittedToolNames.size) {
2695
2736
  throw new Error("pi_managed_mcp_invalid: direct tool catalog size mismatch");
2696
2737
  }
2697
2738
  const names = /* @__PURE__ */ new Set();
2698
2739
  const exposedNames = /* @__PURE__ */ new Set();
2699
2740
  const normalized = tools.map((tool) => {
2700
2741
  const name = nonEmpty2(tool.name, "toolCatalog.tools.name");
2701
- if (!DIRECT_TYPED_V1_TOOL_NAMES.has(name) || names.has(name)) {
2742
+ if (!admittedToolNames.has(name) || names.has(name)) {
2702
2743
  throw new Error("pi_managed_mcp_invalid: direct tool catalog name mismatch");
2703
2744
  }
2704
2745
  names.add(name);
@@ -2722,6 +2763,9 @@ function createManagedPiMcpProfileApi(options = {}) {
2722
2763
  if (!(/* @__PURE__ */ new Set(["read", "write", "destructive"])).has(riskLevel)) {
2723
2764
  throw new Error(`pi_managed_mcp_invalid: direct tool risk level mismatch for ${name}`);
2724
2765
  }
2766
+ if (mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE && riskLevel !== "read") {
2767
+ throw new Error(`pi_managed_mcp_invalid: hybrid direct tool must be read-only for ${name}`);
2768
+ }
2725
2769
  return {
2726
2770
  name,
2727
2771
  exposedName,
@@ -2729,6 +2773,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2729
2773
  inputSchema,
2730
2774
  schemaHash,
2731
2775
  riskLevel,
2776
+ // Match the adapter-exposed schema, which omits top-level $schema and additionalProperties.
2732
2777
  effectiveSchemaHash: stablePiToolSchemaHash(inputSchema, { adapterNormalized: true })
2733
2778
  };
2734
2779
  });
@@ -2818,10 +2863,10 @@ function createManagedPiMcpProfileApi(options = {}) {
2818
2863
  }
2819
2864
  if ((runtimeAuth.issueId ?? null) !== (headers["x-amaster-issue-id"] ?? null)) throw new Error("pi_managed_mcp_invalid: issue authority mismatch");
2820
2865
  const mcpToolMode = gateway.mcpToolMode ?? MANAGED_PI_MCP_TOOL_MODE;
2821
- if (mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE && mcpToolMode !== MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
2866
+ if (mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE && mcpToolMode !== MANAGED_PI_HYBRID_MCP_TOOL_MODE && mcpToolMode !== MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
2822
2867
  throw new Error("pi_managed_mcp_invalid: unsupported managed Pi MCP tool mode");
2823
2868
  }
2824
- const directCatalog = mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? validateDirectCatalog(gateway) : null;
2869
+ const directCatalog = mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE ? validateDirectCatalog(gateway, mcpToolMode) : null;
2825
2870
  if (mcpToolMode === MANAGED_PI_MCP_TOOL_MODE && gateway.toolCatalog !== void 0) {
2826
2871
  throw new Error("pi_managed_mcp_invalid: proxy-only authority cannot carry a direct tool catalog");
2827
2872
  }
@@ -3046,12 +3091,13 @@ function createManagedPiMcpProfileApi(options = {}) {
3046
3091
  `);
3047
3092
  const extensionsDir = join4(agentDir, "extensions");
3048
3093
  mkdirSync3(extensionsDir, { recursive: true, mode: 448 });
3049
- if (mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
3094
+ if (mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE) {
3050
3095
  writePrivateFile2(
3051
3096
  join4(extensionsDir, MANAGED_PI_EFFECTIVE_TOOLS_ATTESTOR_FILENAME),
3052
3097
  managedPiEffectiveToolsAttestorExtensionSource()
3053
3098
  );
3054
- } else {
3099
+ }
3100
+ if (mcpToolMode !== MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
3055
3101
  writePrivateFile2(
3056
3102
  join4(extensionsDir, MANAGED_PI_MCP_ARGS_NORMALIZER_FILENAME),
3057
3103
  managedPiMcpArgsNormalizerExtensionSource()
@@ -3215,7 +3261,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3215
3261
  } catch {
3216
3262
  throw new Error("pi_managed_mcp_effective_tools_failed: probe receipt missing");
3217
3263
  }
3218
- if (receipt.status !== "attested" || receipt.mode !== "probe" || receipt.proxyPresent !== false || receipt.effectiveSetHash !== input.effectiveSetHash || receipt.attestorSourceSha256 !== input.attestorSourceSha256 || receipt.configSha256 !== input.configSha256 || receipt.cacheSha256 !== input.cacheSha256) {
3264
+ const expectedProxyPresent = input.proxyMode === "required";
3265
+ if (receipt.status !== "attested" || receipt.mode !== "probe" || receipt.proxyMode !== input.proxyMode || receipt.proxyPresent !== expectedProxyPresent || receipt.effectiveSetHash !== input.effectiveSetHash || receipt.attestorSourceSha256 !== input.attestorSourceSha256 || receipt.configSha256 !== input.configSha256 || receipt.cacheSha256 !== input.cacheSha256) {
3219
3266
  throw new Error("pi_managed_mcp_effective_tools_failed: probe receipt mismatch");
3220
3267
  }
3221
3268
  if (sha256(readFileSync3(input.configPath)) !== input.configSha256) {
@@ -3225,6 +3272,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3225
3272
  throw new Error("pi_managed_mcp_effective_tools_failed: cache drifted during probe");
3226
3273
  }
3227
3274
  return {
3275
+ effectiveToolProxyMode: receipt.proxyMode,
3276
+ effectiveToolProxyPresent: receipt.proxyPresent,
3228
3277
  effectiveToolSetHash: receipt.effectiveSetHash,
3229
3278
  effectiveToolProbeDigest: sha256(stablePiJson(receipt)),
3230
3279
  effectiveToolProbeAt: receipt.attestedAt,
@@ -3274,7 +3323,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3274
3323
  const config = {
3275
3324
  settings: {
3276
3325
  toolPrefix: "none",
3277
- ...directCatalog ? { disableProxyTool: true } : {}
3326
+ ...mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? { disableProxyTool: true } : {}
3278
3327
  },
3279
3328
  mcpServers: {
3280
3329
  [SUPPORTED_SERVER_NAME2]: serverConfig
@@ -3319,6 +3368,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3319
3368
  name: tool.exposedName,
3320
3369
  schemaHash: tool.effectiveSchemaHash
3321
3370
  }))),
3371
+ proxyMode: mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE ? "required" : "forbidden",
3322
3372
  attestorSourceSha256,
3323
3373
  configSha256: sha256(readFileSync3(configPath)),
3324
3374
  cacheSha256
@@ -3333,7 +3383,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3333
3383
  configPath,
3334
3384
  configSha256: sha256(readFileSync3(configPath)),
3335
3385
  attestorSourceSha256,
3336
- effectiveSetHash: manifest.effectiveSetHash
3386
+ effectiveSetHash: manifest.effectiveSetHash,
3387
+ proxyMode: manifest.proxyMode
3337
3388
  };
3338
3389
  }
3339
3390
  const env = {
@@ -3365,7 +3416,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3365
3416
  ...executorAttestation,
3366
3417
  mcpAdapterVersion: seededRuntime.adapterVersion,
3367
3418
  mcpToolMode,
3368
- mcpArgsNormalization: directCatalog ? "none" : MANAGED_PI_MCP_ARGS_NORMALIZATION,
3419
+ mcpArgsNormalization: mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? "none" : MANAGED_PI_MCP_ARGS_NORMALIZATION,
3369
3420
  ...directCatalog ? {
3370
3421
  catalogSetHash: directCatalog.setHash,
3371
3422
  ...effectiveToolsAttestation
@@ -3387,7 +3438,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3387
3438
  configPath,
3388
3439
  markerPath,
3389
3440
  env,
3390
- toolAllowlist: directCatalog ? [...directToolNames] : null,
3441
+ toolAllowlist: mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? [...directToolNames] : null,
3391
3442
  protectedValues: [.../* @__PURE__ */ new Set([
3392
3443
  sessionToken,
3393
3444
  ...seededRuntime.protectedValues,
@@ -3408,6 +3459,9 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3408
3459
  function prepareDelegatedPiMcpProfile2(input) {
3409
3460
  assertInvocationIsolation2(input);
3410
3461
  const { gateway, gatewayUrl, sessionToken, headers, runId, mcpToolMode, directCatalog } = validateAuthority2(input);
3462
+ if (mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE) {
3463
+ throw new Error("pi_delegated_mcp_hybrid_unsupported: managed effective-tool attestation is required");
3464
+ }
3411
3465
  const runDir = resolve2(nonEmpty2(input.runDir, "runDir"));
3412
3466
  const cwd = resolve2(nonEmpty2(input.cwd, "cwd"));
3413
3467
  if (!within4(cwd, runDir)) throw new Error("pi_delegated_mcp_owner_mismatch: cwd is outside the managed run");
@@ -3453,7 +3507,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3453
3507
  ...sourceMcp,
3454
3508
  settings: {
3455
3509
  ...record8(sourceMcp.settings),
3456
- ...directCatalog ? { disableProxyTool: true } : {}
3510
+ ...mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? { disableProxyTool: true } : {}
3457
3511
  },
3458
3512
  mcpServers: {
3459
3513
  ...record8(sourceMcp.mcpServers),
@@ -4043,6 +4097,39 @@ function retainedSourceExecutorEntry(entry, executorKind) {
4043
4097
  };
4044
4098
  }
4045
4099
 
4100
+ // src/amaster-runtime-daemon/task-context-policy.mjs
4101
+ var TASK_CONTEXT_MANIFEST_VERSION = "task-context-v1";
4102
+ function resolveTaskContextMemoryPolicy(context) {
4103
+ const contextRecord = asRecord(context);
4104
+ const hasManifest = Object.prototype.hasOwnProperty.call(contextRecord, "taskContextManifest");
4105
+ const manifest = asRecord(contextRecord.taskContextManifest);
4106
+ const version = readString(manifest.version);
4107
+ if (!hasManifest) {
4108
+ return {
4109
+ governed: false,
4110
+ memoryScope: null,
4111
+ allowAutomaticHistoricalContext: true,
4112
+ allowCompanyMemoryMount: true
4113
+ };
4114
+ }
4115
+ if (!version) throw new Error("task_context_manifest_version_required");
4116
+ if (version !== TASK_CONTEXT_MANIFEST_VERSION) {
4117
+ throw new Error(`task_context_manifest_version_unsupported:${version}`);
4118
+ }
4119
+ const memoryScope = readString(manifest.memoryScope);
4120
+ if (memoryScope !== "none" && memoryScope !== "task") {
4121
+ throw new Error("task_context_manifest_memory_scope_invalid");
4122
+ }
4123
+ return {
4124
+ governed: true,
4125
+ memoryScope,
4126
+ // The current runtime has Company memory, not a task-scoped memory store.
4127
+ // Governed scopes therefore never authorize Company history implicitly.
4128
+ allowAutomaticHistoricalContext: false,
4129
+ allowCompanyMemoryMount: false
4130
+ };
4131
+ }
4132
+
4046
4133
  // src/amaster-runtime-daemon/prompt-compiler.mjs
4047
4134
  var DEADLINE_POSTURE_GUARD = "If a named time window or milestone is missed, skip that window and keep the task moving: never lower quality, bypass approvals, fabricate results, or stop the whole task because of the miss. Record a deadline-posture receipt with targetMilestoneRef, posture, onMiss=skip_this_window_and_continue, taskContinuation, and the next owner/action; the receipt is an execution signal, not Server-side proof.";
4048
4135
  var MIN_PROMPT_BUDGET_CHARS = 8192;
@@ -4295,14 +4382,15 @@ function resolvedDependencySections(context, input, contextScope, snapshotFreshn
4295
4382
  "Compare each returned latestRevisionId with the expected value. On revision mismatch, do not perform downstream writes; report it.",
4296
4383
  ...tuples.flatMap((tuple, index) => {
4297
4384
  const readArguments = { issueId: tuple.blockerSelector, key: tuple.key };
4298
- const call = input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? {
4385
+ const directToolName = managedDirectToolName(input, "amaster.read_issue_document");
4386
+ const call = directToolName ? readArguments : input.executorKind === "pi" && managedPiMcpProxyAvailable(input) ? {
4299
4387
  server: "amaster",
4300
4388
  tool: "amaster.read_issue_document",
4301
4389
  args: JSON.stringify(readArguments)
4302
4390
  } : readArguments;
4303
4391
  return [
4304
4392
  `- Required read ${index + 1}: issue ${JSON.stringify(tuple.blockerSelector)}${tuple.blockerId ? ` (id ${JSON.stringify(tuple.blockerId)})` : ""}; document ${JSON.stringify(tuple.documentId)}; key ${JSON.stringify(tuple.key)}; expected latestRevisionId ${JSON.stringify(tuple.expectedLatestRevisionId)}${tuple.expectedLatestRevisionNumber != null ? `; revisionNumber ${tuple.expectedLatestRevisionNumber}` : ""}.`,
4305
- input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? ` Exact Pi \`mcp\` arguments: ${JSON.stringify(call)}` : ` Call amaster.read_issue_document with these exact arguments: ${JSON.stringify(call)}`
4393
+ directToolName ? ` Call \`${directToolName}\` with these exact object arguments: ${JSON.stringify(call)}` : input.executorKind === "pi" && managedPiMcpProxyAvailable(input) ? ` Exact Pi \`mcp\` arguments: ${JSON.stringify(call)}` : ` Call amaster.read_issue_document with these exact arguments: ${JSON.stringify(call)}`
4306
4394
  ];
4307
4395
  })
4308
4396
  ].join("\n") : "";
@@ -4372,6 +4460,7 @@ function wikiAccessRuleLine(input) {
4372
4460
  return "";
4373
4461
  }
4374
4462
  function optionalTaskWikiContextSection(context) {
4463
+ if (!resolveTaskContextMemoryPolicy(context).allowAutomaticHistoricalContext) return null;
4375
4464
  const snapshot = asRecord(context.mirrorxTaskWikiContext);
4376
4465
  if (readString(snapshot.schemaVersion) !== "mirrorx.task-wiki-context.v1") return null;
4377
4466
  const querySeeds = (Array.isArray(snapshot.querySeeds) ? snapshot.querySeeds : []).map(readString).filter(Boolean).slice(0, 3);
@@ -4426,6 +4515,31 @@ function optionalTaskWikiContextSection(context) {
4426
4515
  truncationReason: ready ? null : `wiki_optional_context_gap:${readString(snapshot.gapCode) ?? "invalid_snapshot"}`
4427
4516
  };
4428
4517
  }
4518
+ function taskContextAuthoritySection(context) {
4519
+ const manifest = asRecord(context.taskContextManifest);
4520
+ if (readString(manifest.version) !== "task-context-v1") return null;
4521
+ const sourceRefs = (Array.isArray(manifest.sourceRefs) ? manifest.sourceRefs : []).map(asRecord).map((ref) => ({
4522
+ kind: readString(ref.kind),
4523
+ id: readString(ref.id),
4524
+ revision: readString(ref.revision),
4525
+ scope: readString(ref.scope),
4526
+ useReason: readString(ref.useReason)
4527
+ })).filter((ref) => ref.kind && ref.id && ref.revision && ref.scope);
4528
+ if (sourceRefs.length === 0) return null;
4529
+ return {
4530
+ content: [
4531
+ "Immutable Task admission context authority. It identifies admitted sources and automatic memory policy; it does not replace the runtime Context Manifest below.",
4532
+ jsonText({
4533
+ version: manifest.version,
4534
+ memoryScope: readString(manifest.memoryScope),
4535
+ freshness: readString(manifest.freshness),
4536
+ sourceRefs
4537
+ })
4538
+ ].join("\n"),
4539
+ sourceRef: sourceRefs.map((ref) => `${ref.kind}:${ref.id}@${ref.revision}`),
4540
+ scope: sourceRefs.map((ref) => ref.scope)
4541
+ };
4542
+ }
4429
4543
  function fixedRules(input, includeIssueLine) {
4430
4544
  const issue = asRecord(asRecord(input.context).paperclipIssue);
4431
4545
  const businessOutcome = asRecord(asRecord(issue.taskRequirements).businessOutcome);
@@ -4452,7 +4566,7 @@ function fixedRules(input, includeIssueLine) {
4452
4566
  wikiAccessRuleLine(input),
4453
4567
  "- Runtime Artifact lineage fields sourceWorkProductId and sourceWorkProductIds accept only current artifact work product ids returned as result.effectResult.workProductId by a succeeded upload_artifact action. Never pass a documentId or revisionId as artifact lineage.",
4454
4568
  "- When all inputs are issue documents and there is no source artifact work product, persist the derived result with upsert_document and do not call upload_artifact for a derived or review artifact.",
4455
- input.hasGovernedMcp && input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? "- For proxy-only Pi MCP writes, put the complete target argument object directly in actual `mcp` string `args` as strict JSON; escape quotes, backslashes, and control characters. Do not stage or print tool calls. If inner JSON syntax fails, correct it once without changing values; never repeat a possibly accepted call. After `runtime_action.describe`, emit the write." : ""
4569
+ input.hasGovernedMcp && input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? "- For proxy-only Pi MCP writes, put the complete target argument object directly in actual `mcp` string `args` as strict JSON; escape quotes, backslashes, and control characters. Do not stage or print tool calls. If inner JSON syntax fails, correct it once without changing values; never repeat a possibly accepted call. After `runtime_action.describe`, emit the write." : input.hasGovernedMcp && input.executorKind === "pi" && input.managedMcpToolMode === "hybrid" ? "- For hybrid Pi MCP writes, call direct `runtime_action_describe`, then put long-tail write arguments in `mcp.args` as strict JSON. Never stage, print, or repeat a possibly accepted call." : ""
4456
4570
  ].filter(Boolean).join("\n");
4457
4571
  }
4458
4572
  function approvalContinuationText(input) {
@@ -4542,12 +4656,15 @@ function continuationRuntimeActionEnvelope(context) {
4542
4656
  return envelope;
4543
4657
  }
4544
4658
  function managedDirectToolName(input, canonicalName) {
4545
- if (input.managedMcpToolMode !== "direct_typed") return null;
4659
+ if (input.managedMcpToolMode !== "direct_typed" && input.managedMcpToolMode !== "hybrid") return null;
4546
4660
  const catalog = asRecord(input.managedMcpToolCatalog);
4547
4661
  const tools = Array.isArray(catalog.tools) ? catalog.tools.map(asRecord) : [];
4548
4662
  const match = tools.find((tool) => readString(tool.name) === canonicalName);
4549
4663
  return readString(match?.exposedName) ?? null;
4550
4664
  }
4665
+ function managedPiMcpProxyAvailable(input) {
4666
+ return input.managedMcpToolMode === "proxy_only" || input.managedMcpToolMode === "hybrid";
4667
+ }
4551
4668
  function runtimeActionContinuationOptionText(input) {
4552
4669
  if (!isRecoveryWakeReason(input.wakeReason)) return "";
4553
4670
  const heading = "### Runtime Action Continuation Option";
@@ -4566,12 +4683,8 @@ Runtime Action continuation is unavailable: managed governed MCP capability is m
4566
4683
  Runtime Action continuation is unavailable: continuationRuntimeActionEnvelope is missing or invalid. Do not guess a tool call.`;
4567
4684
  }
4568
4685
  if (input.executorKind === "pi") {
4569
- if (input.managedMcpToolMode === "direct_typed") {
4570
- const toolName = managedDirectToolName(input, "runtime_action.submit");
4571
- if (!toolName) {
4572
- return `${heading}
4573
- Runtime Action continuation is unavailable: the run catalog does not advertise the required typed submit tool. Do not guess a tool call.`;
4574
- }
4686
+ const toolName = managedDirectToolName(input, "runtime_action.submit");
4687
+ if (toolName) {
4575
4688
  return [
4576
4689
  heading,
4577
4690
  `Only after selecting continuation/todo from the disposition menu, emit an actual \`${toolName}\` typed tool call with the exact object arguments below. Do not print this JSON as prose.`,
@@ -4580,7 +4693,11 @@ Runtime Action continuation is unavailable: the run catalog does not advertise t
4580
4693
  "```"
4581
4694
  ].join("\n");
4582
4695
  }
4583
- if (input.managedMcpToolMode !== "proxy_only") {
4696
+ if (!managedPiMcpProxyAvailable(input)) {
4697
+ if (input.managedMcpToolMode === "direct_typed") {
4698
+ return `${heading}
4699
+ Runtime Action continuation is unavailable: the run catalog does not advertise the required typed submit tool. Do not guess a tool call.`;
4700
+ }
4584
4701
  return `${heading}
4585
4702
  Runtime Action continuation is unavailable: managed Pi MCP tool mode is not proxy_only. Do not guess a proxy or direct-tool call.`;
4586
4703
  }
@@ -4692,7 +4809,7 @@ function runtimeDecompositionRequirementText(context) {
4692
4809
  }
4693
4810
  function deliveryReadCallText(input) {
4694
4811
  const args = { issueId: input.issueId };
4695
- if (input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only") {
4812
+ if (input.executorKind === "pi" && managedPiMcpProxyAvailable(input)) {
4696
4813
  return `emit an mcp proxy call: ${JSON.stringify({
4697
4814
  server: "amaster",
4698
4815
  tool: "amaster.read_issue_delivery",
@@ -4763,7 +4880,11 @@ function runtimeDeliveryReadinessText(context, input) {
4763
4880
  }
4764
4881
  function readIssueEvidenceCommentCallText(issueId, commentId, options) {
4765
4882
  const readArguments = { refs: [{ kind: "issue_comment", issueId, commentId }] };
4766
- if (options?.executorKind === "pi" && options?.managedMcpToolMode === "proxy_only") {
4883
+ const directToolName = managedDirectToolName(options ?? {}, "amaster.read_issue_evidence");
4884
+ if (directToolName) {
4885
+ return `call \`${directToolName}\` with these exact object arguments: ${JSON.stringify(readArguments)}`;
4886
+ }
4887
+ if (options?.executorKind === "pi" && managedPiMcpProxyAvailable(options)) {
4767
4888
  return `emit an mcp proxy call: ${JSON.stringify({ server: "amaster", tool: "amaster.read_issue_evidence", args: JSON.stringify(readArguments) })}`;
4768
4889
  }
4769
4890
  return `call amaster.read_issue_evidence with these exact arguments: ${JSON.stringify(readArguments)}`;
@@ -4781,36 +4902,37 @@ function taskCommentRefGuidance(input) {
4781
4902
  return `References like comment:<id> above mark truncated comment bodies. Fetch the full text before relying on them \u2014 ${call} (replace <id> with the referenced comment id).`;
4782
4903
  }
4783
4904
  function piMcpProxyExamplesText(input) {
4784
- if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "proxy_only" || isRecoveryWakeReason(input.wakeReason)) return "";
4905
+ if (!input.hasGovernedMcp || input.executorKind !== "pi" || !managedPiMcpProxyAvailable(input) || isRecoveryWakeReason(input.wakeReason)) return "";
4906
+ const hybrid = input.managedMcpToolMode === "hybrid";
4785
4907
  const proxy = (tool, args) => JSON.stringify({
4786
4908
  server: "amaster",
4787
4909
  tool,
4788
4910
  args: JSON.stringify(args)
4789
4911
  });
4790
4912
  return [
4791
- "The Pi native tool is the outer `mcp` proxy. Emit these as actual tool calls; `args` is the stringified inner canonical object. Pi validates this string schema before extension hooks, so never send object-valued `args`:",
4913
+ hybrid ? "For governed tools not exposed in the direct typed list, use the outer `mcp` proxy. Before the first long-tail proxy call, describe that exact canonical tool; `args` is the stringified inner canonical object and must never be object-valued." : "The Pi native tool is the outer `mcp` proxy. Emit these as actual tool calls; `args` is the stringified inner canonical object. Pi validates this string schema before extension hooks, so never send object-valued `args`:",
4792
4914
  "Keep review payload strings short. Reference the exact document key and revision in `target`; do not duplicate the reviewed document body in `prompt` or `detailsMarkdown`.",
4793
4915
  "payload.supersedesInteractionId is invalid. provenance.supersedesInteractionId is only for replacing a currently pending governed interaction; after changes_requested or rejected resolution, do not send a supersession id.",
4794
4916
  "update_parent.comment creates a separate persistent issue comment. Omit it when add_comment already recorded the message.",
4795
- `- describe: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`,
4917
+ ...!hybrid ? [`- describe: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`] : [],
4796
4918
  `- submit: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-progress", action: { type: "update_parent", status: "in_progress" } })}`,
4797
4919
  `- submit intermediate document review interaction: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-review", action: { type: "create_interaction", kind: "request_confirmation", continuationPolicy: "wake_assignee_on_accept", provenance: { purposeCode: "review_document_revision", requirementRefs: ["acceptance:document_review"], attentionOwner: { kind: "board", id: "board" }, epochKey: "document_revision:22222222-2222-4222-8222-222222222222" }, payload: { version: 1, resolutionMode: "review", prompt: "Review `plan` revision 1.", target: { type: "issue_document", issueId: "11111111-1111-4111-8111-111111111111", documentId: "33333333-3333-4333-8333-333333333333", key: "plan", revisionId: "22222222-2222-4222-8222-222222222222", revisionNumber: 1 } } } })}`,
4798
4920
  `- plan: ${proxy("runtime_action.plan", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-plan", actions: [{ type: "update_parent", status: "in_progress" }] })}`,
4799
4921
  `- commit the returned plan revision: ${proxy("runtime_action.commit", { schemaVersion: "runtime-action-v1", planId: "11111111-1111-4111-8111-111111111111", revision: "plan-revision-1" })}`,
4800
- `- read document: ${proxy("amaster.read_issue_document", { issueId: "AM-123", key: "plan" })}`
4922
+ ...!hybrid ? [`- read document: ${proxy("amaster.read_issue_document", { issueId: "AM-123", key: "plan" })}`] : []
4801
4923
  ].join("\n");
4802
4924
  }
4803
4925
  function piDirectTypedToolsText(input) {
4804
- if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "direct_typed") return "";
4926
+ if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "direct_typed" && input.managedMcpToolMode !== "hybrid") return "";
4805
4927
  const catalog = asRecord(input.managedMcpToolCatalog);
4806
4928
  const tools = (Array.isArray(catalog.tools) ? catalog.tools : []).map(asRecord).map((tool) => ({ name: readString(tool.exposedName), description: readString(tool.description) })).filter((tool) => tool.name);
4807
4929
  if (tools.length === 0) {
4808
4930
  return "Direct typed governed tools are unavailable because the run catalog snapshot is empty. Do not guess a proxy or tool name.";
4809
4931
  }
4810
4932
  return [
4811
- "This run uses the attested direct typed Governed MCP surface below. Call these exact names with object arguments; do not call the `mcp` proxy and do not stringify an inner argument envelope.",
4933
+ input.managedMcpToolMode === "hybrid" ? "This run exposes the attested high-frequency Governed MCP tools below as direct typed tools. Call these exact names with object arguments and do not send them through the `mcp` proxy." : "This run uses the attested direct typed Governed MCP surface below. Call these exact names with object arguments; do not call the `mcp` proxy and do not stringify an inner argument envelope.",
4812
4934
  ...tools.map((tool) => `- ${tool.name}${tool.description ? `: ${tool.description}` : ""}`),
4813
- "A tool not listed above is unavailable in this run. Do not infer a namespace or fall back to REST/bare MCP."
4935
+ input.managedMcpToolMode === "hybrid" ? "For a canonical tool not listed above, use the single managed `mcp` proxy only after exact describe. Never infer an alias, use REST, or bypass the governed Gateway." : "A tool not listed above is unavailable in this run. Do not infer a namespace or fall back to REST/bare MCP."
4814
4936
  ].join("\n");
4815
4937
  }
4816
4938
  function sectionText(section) {
@@ -4919,9 +5041,14 @@ function compileCommandPromptWithManifest(input, options = {}) {
4919
5041
  resolvedDependencies.details.content ? `Auxiliary predecessor context (may be truncated):
4920
5042
  ${resolvedDependencies.details.content}` : ""
4921
5043
  ].filter(Boolean).join("\n\n") : "";
4922
- const piMcpProxyExamples = resolvedDependencies.required.content ? "" : [piMcpProxyExamplesText(input), piDirectTypedToolsText(input)].filter(Boolean).join("\n");
5044
+ const piDirectTypedTools = piDirectTypedToolsText(input);
5045
+ const piMcpProxyExamples = [
5046
+ resolvedDependencies.required.content ? "" : piMcpProxyExamplesText(input),
5047
+ piDirectTypedTools
5048
+ ].filter(Boolean).join("\n");
4923
5049
  const deliveryReadinessContent = runtimeDeliveryReadinessText(context, input);
4924
5050
  const optionalTaskWikiContext = optionalTaskWikiContextSection(context);
5051
+ const taskContextAuthority = taskContextAuthoritySection(context);
4925
5052
  const rawSections = [
4926
5053
  { name: "recovery_instruction", title: "Recovery Instruction", priority: 100, sourceRef: `run:${input.runId ?? "unknown"}`, content: completeRecoveryInstruction, truncationReason: completeRecoveryInstruction ? null : "mode_selection" },
4927
5054
  { name: "approval_continuation", title: "Approved Runtime Action Continuation", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: approvalContinuationText(input), truncationReason: mode === "continuation" ? null : "mode_selection" },
@@ -4940,8 +5067,15 @@ ${resolvedDependencies.details.content}` : ""
4940
5067
  { name: "runtime_rules", title: "", priority: 100, sourceRef: `command:${input.commandId}`, content: fixedRules(input, !hasTask) },
4941
5068
  { name: "runtime_authorization", title: "Runtime Action Contract", priority: 98, sourceRef: `run:${input.runId ?? "unknown"}`, content: runtimeAuthorizationText(context, mode, { suppressOrdinaryCompletionContract }) },
4942
5069
  { name: "runtime_decomposition_requirement", title: "Required Task Decomposition", priority: 98, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: runtimeDecompositionRequirementText(context) },
5070
+ ...taskContextAuthority ? [{ name: "task_context_authority", title: "Task Context Authority", priority: 98, ...taskContextAuthority }] : [],
4943
5071
  ...verifiedCompanyContext.content ? [{ name: "verified_company_context", title: "Verified Company Context", priority: 96, sourceRef: verifiedCompanyContext.sourceRef, observedAt: verifiedCompanyContext.observedAt, freshness: { kind: "run_snapshot" }, content: verifiedCompanyContext.content }] : [],
4944
- ...piMcpProxyExamples ? [{ name: "pi_mcp_proxy_examples", title: "Pi MCP Proxy Examples", priority: 96, sourceRef: "amaster_governed_mcp_proxy_contract", content: piMcpProxyExamples }] : [],
5072
+ ...piMcpProxyExamples ? [{
5073
+ name: "pi_mcp_proxy_examples",
5074
+ title: piDirectTypedTools ? "Pi Governed MCP Tools" : "Pi MCP Proxy Examples",
5075
+ priority: 96,
5076
+ sourceRef: "amaster_governed_mcp_proxy_contract",
5077
+ content: piMcpProxyExamples
5078
+ }] : [],
4945
5079
  { name: "governed_reads", title: "Governed External Reads", priority: 88, sourceRef: governedReads.provenance.map((entry) => entry.sourceRef), observedAt: governedReads.provenance.map((entry) => entry.observedAt), freshness: governedReads.provenance.map((entry) => entry.freshness), scope: governedReads.provenance.map((entry) => entry.scope), content: governedReads.content },
4946
5080
  ...optionalTaskWikiContext ? [optionalTaskWikiContext] : [],
4947
5081
  { name: "agent_instructions", title: "Agent Instructions", priority: 100, sourceRef: "agent_instructions_bundle", content: readString(input.agentInstructions) ?? "" },
@@ -9546,7 +9680,7 @@ function assertSourceAcquisitionRuntimeAuthority({
9546
9680
  }
9547
9681
 
9548
9682
  // src/amaster-runtime-daemon.mjs
9549
- var CONNECTOR_VERSION = "0.1.1-beta.15";
9683
+ var CONNECTOR_VERSION = "0.1.1-beta.16";
9550
9684
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
9551
9685
  var SOURCE_ACQUISITION_CAPABILITY = "source_acquisition_v1";
9552
9686
  var SOURCE_ACQUISITION_PROFILE_VERSION = "source_acquisition_v1";
@@ -14027,6 +14161,9 @@ async function executeRunCommand(config, command) {
14027
14161
  throw new Error(`runtime_actions_v2_preflight_failed: ${executor.kind} command lacks an exact managed governed MCP profile`);
14028
14162
  }
14029
14163
  const workspace = resolveExecutionWorkspace(config, command, { executorKind: executor.kind });
14164
+ const taskContextMemoryPolicy = resolveTaskContextMemoryPolicy(
14165
+ asRecord(asRecord(command.payload).contextSnapshot)
14166
+ );
14030
14167
  const cwd = workspace.cwd;
14031
14168
  try {
14032
14169
  await materializeAgentInstructionsBundle(config, command, workspace);
@@ -14238,20 +14375,26 @@ async function executeRunCommand(config, command) {
14238
14375
  }
14239
14376
  if (piChildAllocator2) {
14240
14377
  try {
14241
- const companyId = readString(commandRuntimeAuth(command).companyId) ?? readString(asRecord(command.payload).companyId);
14242
- if (!companyId) throw new Error("pi_company_memory_company_id_required");
14243
- const companyMemoryGroup = resolveCompanyPiMemoryGroup({
14244
- root: companyPiHomeRoot(process.env),
14245
- companyId
14246
- });
14247
- const assignment = piChildAllocator2.acquire(commandRunId(command), {
14248
- gid: companyMemoryGroup.gid
14249
- });
14378
+ const companyMemoryGroup = taskContextMemoryPolicy.allowCompanyMemoryMount ? (() => {
14379
+ const companyId = readString(commandRuntimeAuth(command).companyId) ?? readString(asRecord(command.payload).companyId);
14380
+ if (!companyId) throw new Error("pi_company_memory_company_id_required");
14381
+ return {
14382
+ companyId,
14383
+ ...resolveCompanyPiMemoryGroup({
14384
+ root: companyPiHomeRoot(process.env),
14385
+ companyId
14386
+ })
14387
+ };
14388
+ })() : null;
14389
+ const assignment = piChildAllocator2.acquire(
14390
+ commandRunId(command),
14391
+ companyMemoryGroup ? { gid: companyMemoryGroup.gid } : {}
14392
+ );
14250
14393
  piChildAssignmentAcquired = true;
14251
- if (managedMcpProfile) {
14394
+ if (managedMcpProfile && companyMemoryGroup) {
14252
14395
  piCompanyMemory = prepareCompanyPiMemory({
14253
14396
  root: companyMemoryGroup.root,
14254
- companyId,
14397
+ companyId: companyMemoryGroup.companyId,
14255
14398
  gid: companyMemoryGroup.gid,
14256
14399
  profileRoot: managedMcpProfile.profileRoot,
14257
14400
  profileHome: managedMcpProfile.env.PI_AGENT_HOME,
@@ -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.15";
9
+ const CONNECTOR_VERSION = "0.1.1-beta.16";
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.15",
3
+ "version": "0.1.1-beta.16",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",