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

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,35 +2469,18 @@ 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];
2441
2481
  const MINIMUM_MCP_ADAPTER_VERSION = [2, 6, 1];
2442
2482
  const MANAGED_BROWSER_USE_PACKAGE = "@amaster.ai/pi-browser-use";
2443
2483
  const MANAGED_BROWSER_USE_PLUGIN = "browser-use";
2444
- const MANAGED_WEB_ACCESS_PACKAGE = "@amaster.ai/pi-web-access";
2445
- const MANAGED_TELEMETRY_PACKAGE = "@amaster.ai/pi-telemetry";
2446
- const MANAGED_TELEMETRY_ENV_NAMES = [
2447
- "PI_TELEMETRY_TASK_RUN_ID",
2448
- "PI_TELEMETRY_SERVICE_NAME",
2449
- "PI_TELEMETRY_SERVICE_VERSION",
2450
- "PI_TELEMETRY_INCLUDE_PAYLOADS",
2451
- "PI_TELEMETRY_LANGFUSE_ENABLED",
2452
- "PI_TELEMETRY_LANGFUSE_PUBLIC_KEY",
2453
- "PI_TELEMETRY_LANGFUSE_SECRET_KEY",
2454
- "PI_TELEMETRY_LANGFUSE_BASE_URL",
2455
- "PI_TELEMETRY_LANGFUSE_FLUSH_AT",
2456
- "PI_TELEMETRY_LANGFUSE_FLUSH_INTERVAL_MS",
2457
- "PI_TELEMETRY_OTEL_ENABLED",
2458
- "PI_TELEMETRY_OTEL_ENDPOINT",
2459
- "PI_TELEMETRY_OTEL_HEADERS",
2460
- "PI_TELEMETRY_OTEL_FLUSH_AT",
2461
- "PI_TELEMETRY_OTEL_FLUSH_INTERVAL_MS"
2462
- ];
2463
- const MANAGED_TELEMETRY_PROTECTED_ENV_NAMES = [
2464
- "PI_TELEMETRY_LANGFUSE_SECRET_KEY",
2465
- "PI_TELEMETRY_OTEL_HEADERS"
2466
- ];
2467
2484
  const MANAGED_BROWSER_USE_BOOLEAN_SETTINGS = [
2468
2485
  "headless",
2469
2486
  "categoryNetwork",
@@ -2490,6 +2507,12 @@ function createManagedPiMcpProfileApi(options = {}) {
2490
2507
  "AMASTER-CLI_CODING_AGENT_SESSION_DIR",
2491
2508
  "PI_AGENT_MCP_SERVERS_FILE"
2492
2509
  ]);
2510
+ const RUN_OWNED_SETTINGS_ENV = /* @__PURE__ */ new Set([
2511
+ ...FORBIDDEN_COMMAND_ENV2,
2512
+ "MCP_DIRECT_TOOLS",
2513
+ "PAPERCLIP_API_KEY",
2514
+ "AMASTER_BOARD_API_KEY"
2515
+ ]);
2493
2516
  const ALLOWED_COMMAND_ENV2 = new Set(MANAGED_PI_PROVIDER_ENV_NAMES);
2494
2517
  const SAFE_INHERITED_ENV2 = /* @__PURE__ */ new Set([
2495
2518
  "PATH",
@@ -2515,8 +2538,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2515
2538
  "PAPERCLIP_TASK_ID",
2516
2539
  "PAPERCLIP_AGENT_ID",
2517
2540
  "PAPERCLIP_COMPANY_ID",
2518
- "AMASTER_EMPLOYEE_COMPANY_ID",
2519
- ...MANAGED_TELEMETRY_ENV_NAMES
2541
+ "AMASTER_EMPLOYEE_COMPANY_ID"
2520
2542
  ]);
2521
2543
  const FORBIDDEN_ARGV = /* @__PURE__ */ new Set([
2522
2544
  "--no-tools",
@@ -2685,20 +2707,21 @@ function createManagedPiMcpProfileApi(options = {}) {
2685
2707
  excludeTools: definition.excludeTools
2686
2708
  }));
2687
2709
  }
2688
- function validateDirectCatalog(gateway) {
2710
+ function validateDirectCatalog(gateway, mcpToolMode) {
2689
2711
  const catalog = record8(gateway.toolCatalog);
2690
2712
  if (catalog.schemaVersion !== DIRECT_CATALOG_SCHEMA_VERSION) {
2691
2713
  throw new Error("pi_managed_mcp_invalid: direct tool catalog schema mismatch");
2692
2714
  }
2693
2715
  const tools = Array.isArray(catalog.tools) ? catalog.tools.map(record8) : [];
2694
- if (tools.length !== DIRECT_TYPED_V1_TOOL_NAMES.size) {
2716
+ const admittedToolNames = mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE ? HYBRID_DIRECT_TYPED_V1_TOOL_NAMES : DIRECT_TYPED_V1_TOOL_NAMES;
2717
+ if (tools.length !== admittedToolNames.size) {
2695
2718
  throw new Error("pi_managed_mcp_invalid: direct tool catalog size mismatch");
2696
2719
  }
2697
2720
  const names = /* @__PURE__ */ new Set();
2698
2721
  const exposedNames = /* @__PURE__ */ new Set();
2699
2722
  const normalized = tools.map((tool) => {
2700
2723
  const name = nonEmpty2(tool.name, "toolCatalog.tools.name");
2701
- if (!DIRECT_TYPED_V1_TOOL_NAMES.has(name) || names.has(name)) {
2724
+ if (!admittedToolNames.has(name) || names.has(name)) {
2702
2725
  throw new Error("pi_managed_mcp_invalid: direct tool catalog name mismatch");
2703
2726
  }
2704
2727
  names.add(name);
@@ -2722,6 +2745,9 @@ function createManagedPiMcpProfileApi(options = {}) {
2722
2745
  if (!(/* @__PURE__ */ new Set(["read", "write", "destructive"])).has(riskLevel)) {
2723
2746
  throw new Error(`pi_managed_mcp_invalid: direct tool risk level mismatch for ${name}`);
2724
2747
  }
2748
+ if (mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE && riskLevel !== "read") {
2749
+ throw new Error(`pi_managed_mcp_invalid: hybrid direct tool must be read-only for ${name}`);
2750
+ }
2725
2751
  return {
2726
2752
  name,
2727
2753
  exposedName,
@@ -2729,6 +2755,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2729
2755
  inputSchema,
2730
2756
  schemaHash,
2731
2757
  riskLevel,
2758
+ // Match the adapter-exposed schema, which omits top-level $schema and additionalProperties.
2732
2759
  effectiveSchemaHash: stablePiToolSchemaHash(inputSchema, { adapterNormalized: true })
2733
2760
  };
2734
2761
  });
@@ -2818,10 +2845,10 @@ function createManagedPiMcpProfileApi(options = {}) {
2818
2845
  }
2819
2846
  if ((runtimeAuth.issueId ?? null) !== (headers["x-amaster-issue-id"] ?? null)) throw new Error("pi_managed_mcp_invalid: issue authority mismatch");
2820
2847
  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) {
2848
+ if (mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE && mcpToolMode !== MANAGED_PI_HYBRID_MCP_TOOL_MODE && mcpToolMode !== MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
2822
2849
  throw new Error("pi_managed_mcp_invalid: unsupported managed Pi MCP tool mode");
2823
2850
  }
2824
- const directCatalog = mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? validateDirectCatalog(gateway) : null;
2851
+ const directCatalog = mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE ? validateDirectCatalog(gateway, mcpToolMode) : null;
2825
2852
  if (mcpToolMode === MANAGED_PI_MCP_TOOL_MODE && gateway.toolCatalog !== void 0) {
2826
2853
  throw new Error("pi_managed_mcp_invalid: proxy-only authority cannot carry a direct tool catalog");
2827
2854
  }
@@ -2832,13 +2859,38 @@ function createManagedPiMcpProfileApi(options = {}) {
2832
2859
  return /^(?:(?:access|refresh|id)_)?token$/.test(normalized) || normalized.includes("api_key") || normalized.includes("secret") || normalized.includes("password") || normalized.includes("credential") || normalized.includes("authorization") || normalized.includes("cookie");
2833
2860
  }
2834
2861
  function collectAuthSecretStrings2(value, output = []) {
2835
- if (!value || typeof value !== "object" || Array.isArray(value)) return output;
2862
+ if (!value || typeof value !== "object") return output;
2863
+ if (Array.isArray(value)) {
2864
+ for (const entry of value) collectAuthSecretStrings2(entry, output);
2865
+ return output;
2866
+ }
2836
2867
  for (const [key, entry] of Object.entries(value)) {
2837
2868
  if (typeof entry === "string" && entry && isSensitiveAuthKey2(key)) output.push(entry);
2838
- else if (entry && typeof entry === "object" && !Array.isArray(entry)) collectAuthSecretStrings2(entry, output);
2869
+ else if (entry && typeof entry === "object") collectAuthSecretStrings2(entry, output);
2839
2870
  }
2840
2871
  return output;
2841
2872
  }
2873
+ function referencedSettingsEnvironment(settings, baseEnv) {
2874
+ const names = /* @__PURE__ */ new Set();
2875
+ const visit = (value) => {
2876
+ if (typeof value === "string") {
2877
+ for (const match of value.matchAll(/\$(?:\{([A-Za-z_][A-Za-z0-9_]*)(?::-[^}]*)?\}|([A-Za-z_][A-Za-z0-9_]*))/g)) {
2878
+ names.add(match[1] ?? match[2]);
2879
+ }
2880
+ } else if (Array.isArray(value)) {
2881
+ for (const entry of value) visit(entry);
2882
+ } else if (value && typeof value === "object") {
2883
+ for (const entry of Object.values(value)) visit(entry);
2884
+ }
2885
+ };
2886
+ visit(settings);
2887
+ const env = {};
2888
+ for (const name of names) {
2889
+ if (RUN_OWNED_SETTINGS_ENV.has(name)) continue;
2890
+ if (typeof baseEnv?.[name] === "string" && baseEnv[name]) env[name] = baseEnv[name];
2891
+ }
2892
+ return env;
2893
+ }
2842
2894
  function assertInvocationIsolation2(input) {
2843
2895
  for (const name of Object.keys(record8(input.commandEnv))) {
2844
2896
  if (FORBIDDEN_COMMAND_ENV2.has(name)) throw new Error(`pi_managed_mcp_env_override_blocked: ${name}`);
@@ -2948,49 +3000,7 @@ function createManagedPiMcpProfileApi(options = {}) {
2948
3000
  }
2949
3001
  };
2950
3002
  }
2951
- function selectManagedWebAccess(sourceSettings, npmSource) {
2952
- const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_WEB_ACCESS_PACKAGE) : null;
2953
- if (typeof packageSpec !== "string") return null;
2954
- const packagePath = join4(npmSource, "node_modules", ...MANAGED_WEB_ACCESS_PACKAGE.split("/"), "package.json");
2955
- if (!existsSync3(packagePath) || lstatSync2(packagePath).isSymbolicLink() || !lstatSync2(packagePath).isFile()) {
2956
- throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_WEB_ACCESS_PACKAGE} package is unavailable`);
2957
- }
2958
- let packageMetadata;
2959
- try {
2960
- packageMetadata = JSON.parse(readFileSync3(packagePath, "utf8"));
2961
- } catch {
2962
- throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_WEB_ACCESS_PACKAGE} package metadata is invalid`);
2963
- }
2964
- if (!packageMetadata || packageMetadata.name !== MANAGED_WEB_ACCESS_PACKAGE) {
2965
- throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_WEB_ACCESS_PACKAGE} package identity mismatch`);
2966
- }
2967
- return {
2968
- packageSpec,
2969
- config: record8(sourceSettings["pi-web-access"])
2970
- };
2971
- }
2972
- function selectManagedTelemetry(sourceSettings, npmSource) {
2973
- const packageSpec = Array.isArray(sourceSettings.packages) ? sourceSettings.packages.find((entry) => npmPackageName(entry) === MANAGED_TELEMETRY_PACKAGE) : null;
2974
- if (typeof packageSpec !== "string") return null;
2975
- const packagePath = join4(npmSource, "node_modules", ...MANAGED_TELEMETRY_PACKAGE.split("/"), "package.json");
2976
- if (!existsSync3(packagePath) || lstatSync2(packagePath).isSymbolicLink() || !lstatSync2(packagePath).isFile()) {
2977
- throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_TELEMETRY_PACKAGE} package is unavailable`);
2978
- }
2979
- let packageMetadata;
2980
- try {
2981
- packageMetadata = JSON.parse(readFileSync3(packagePath, "utf8"));
2982
- } catch {
2983
- throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_TELEMETRY_PACKAGE} package metadata is invalid`);
2984
- }
2985
- if (packageMetadata.name !== MANAGED_TELEMETRY_PACKAGE) {
2986
- throw new Error(`pi_managed_mcp_attestation_failed: configured ${MANAGED_TELEMETRY_PACKAGE} package identity mismatch`);
2987
- }
2988
- return {
2989
- packageSpec,
2990
- config: record8(sourceSettings["pi-telemetry"])
2991
- };
2992
- }
2993
- function seedPiRuntime(sourceHome, agentDir, sourceAcquisition = null, mcpToolMode = MANAGED_PI_MCP_TOOL_MODE) {
3003
+ function seedPiRuntime(sourceHome, agentDir, sourceAcquisition = null, mcpToolMode = MANAGED_PI_MCP_TOOL_MODE, baseEnv = {}) {
2994
3004
  const source = resolve2(nonEmpty2(sourceHome, "sourcePiHome"));
2995
3005
  const sourceStat = lstatSync2(source);
2996
3006
  if (!sourceStat.isDirectory() || sourceStat.isSymbolicLink()) {
@@ -3018,40 +3028,31 @@ function createManagedPiMcpProfileApi(options = {}) {
3018
3028
  throw new Error("pi_managed_mcp_attestation_failed: source Pi settings are invalid");
3019
3029
  }
3020
3030
  }
3021
- const browserUse = selectManagedBrowserUse(sourceSettings, npmSource);
3022
- const webAccess = sourceAcquisition ? null : selectManagedWebAccess(sourceSettings, npmSource);
3023
- const telemetry = selectManagedTelemetry(sourceSettings, npmSource);
3031
+ const browserUse = sourceAcquisition ? selectManagedBrowserUse(sourceSettings, npmSource) : null;
3024
3032
  if (sourceAcquisition && !browserUse) {
3025
3033
  throw new Error("pi_managed_mcp_source_acquisition_packages_missing");
3026
3034
  }
3027
- const settings = {
3035
+ const sourcePackages = Array.isArray(sourceSettings.packages) ? [...sourceSettings.packages] : [];
3036
+ const settings = sourceAcquisition ? {
3028
3037
  ...typeof sourceSettings.defaultProvider === "string" ? { defaultProvider: sourceSettings.defaultProvider } : {},
3029
3038
  ...typeof sourceSettings.defaultModel === "string" ? { defaultModel: sourceSettings.defaultModel } : {},
3030
- packages: [
3031
- "npm:pi-mcp-adapter",
3032
- ...telemetry ? [telemetry.packageSpec] : [],
3033
- ...webAccess ? [webAccess.packageSpec] : [],
3034
- ...!sourceAcquisition && browserUse ? [browserUse.packageSpec] : []
3035
- ],
3036
- ...telemetry ? { "pi-telemetry": telemetry.config } : {},
3037
- ...webAccess ? { "pi-web-access": webAccess.config } : {},
3038
- ...!sourceAcquisition && browserUse ? {
3039
- plugins: {
3040
- [MANAGED_BROWSER_USE_PLUGIN]: browserUse.plugin
3041
- },
3042
- "pi-browser-use": browserUse.config
3043
- } : {}
3039
+ packages: ["npm:pi-mcp-adapter"]
3040
+ } : {
3041
+ ...sourceSettings,
3042
+ packages: sourcePackages.some((entry) => npmPackageName(entry) === "pi-mcp-adapter") ? sourcePackages : ["npm:pi-mcp-adapter", ...sourcePackages]
3044
3043
  };
3044
+ const settingsEnv = sourceAcquisition ? {} : referencedSettingsEnvironment(settings, baseEnv);
3045
3045
  writePrivateFile2(join4(agentDir, "settings.json"), `${JSON.stringify(settings, null, 2)}
3046
3046
  `);
3047
3047
  const extensionsDir = join4(agentDir, "extensions");
3048
3048
  mkdirSync3(extensionsDir, { recursive: true, mode: 448 });
3049
- if (mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
3049
+ if (mcpToolMode !== MANAGED_PI_MCP_TOOL_MODE) {
3050
3050
  writePrivateFile2(
3051
3051
  join4(extensionsDir, MANAGED_PI_EFFECTIVE_TOOLS_ATTESTOR_FILENAME),
3052
3052
  managedPiEffectiveToolsAttestorExtensionSource()
3053
3053
  );
3054
- } else {
3054
+ }
3055
+ if (mcpToolMode !== MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE) {
3055
3056
  writePrivateFile2(
3056
3057
  join4(extensionsDir, MANAGED_PI_MCP_ARGS_NORMALIZER_FILENAME),
3057
3058
  managedPiMcpArgsNormalizerExtensionSource()
@@ -3066,7 +3067,10 @@ function createManagedPiMcpProfileApi(options = {}) {
3066
3067
  copyPrivateFile(join4(source, "models.json"), join4(agentDir, "models.json"));
3067
3068
  copyPrivateFile(join4(source, "SYSTEM.md"), join4(agentDir, "SYSTEM.md"));
3068
3069
  const authSource = join4(source, "auth.json");
3069
- const protectedValues = [];
3070
+ const protectedValues = collectAuthSecretStrings2(settings);
3071
+ for (const [name, value] of Object.entries(settingsEnv)) {
3072
+ if (isSensitiveAuthKey2(name)) protectedValues.push(value);
3073
+ }
3070
3074
  if (copyPrivateFile(authSource, join4(agentDir, "auth.json"))) {
3071
3075
  try {
3072
3076
  collectAuthSecretStrings2(JSON.parse(readFileSync3(authSource, "utf8")), protectedValues);
@@ -3077,7 +3081,7 @@ function createManagedPiMcpProfileApi(options = {}) {
3077
3081
  const npmStat = lstatSync2(npmSource);
3078
3082
  if (!npmStat.isDirectory() || npmStat.isSymbolicLink()) throw new Error("pi_managed_mcp_source_config_unsafe: Pi npm root");
3079
3083
  symlinkSync(npmSource, join4(agentDir, "npm"), "dir");
3080
- return { adapterVersion, protectedValues };
3084
+ return { adapterVersion, protectedValues, settingsEnv };
3081
3085
  }
3082
3086
  function seedDelegatedPiRuntime(sourceHome, agentDir) {
3083
3087
  const source = resolve2(nonEmpty2(sourceHome, "sourcePiHome"));
@@ -3215,7 +3219,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3215
3219
  } catch {
3216
3220
  throw new Error("pi_managed_mcp_effective_tools_failed: probe receipt missing");
3217
3221
  }
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) {
3222
+ const expectedProxyPresent = input.proxyMode === "required";
3223
+ 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
3224
  throw new Error("pi_managed_mcp_effective_tools_failed: probe receipt mismatch");
3220
3225
  }
3221
3226
  if (sha256(readFileSync3(input.configPath)) !== input.configSha256) {
@@ -3225,6 +3230,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3225
3230
  throw new Error("pi_managed_mcp_effective_tools_failed: cache drifted during probe");
3226
3231
  }
3227
3232
  return {
3233
+ effectiveToolProxyMode: receipt.proxyMode,
3234
+ effectiveToolProxyPresent: receipt.proxyPresent,
3228
3235
  effectiveToolSetHash: receipt.effectiveSetHash,
3229
3236
  effectiveToolProbeDigest: sha256(stablePiJson(receipt)),
3230
3237
  effectiveToolProbeAt: receipt.attestedAt,
@@ -3260,7 +3267,13 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3260
3267
  commandId: input.commandId
3261
3268
  });
3262
3269
  const sourcePiHome = nonEmpty2(input.baseEnv?.PI_CODING_AGENT_DIR ?? input.baseEnv?.PI_AGENT_HOME, "sourcePiHome");
3263
- const seededRuntime = seedPiRuntime(sourcePiHome, piCodingAgentDir, input.sourceAcquisition, mcpToolMode);
3270
+ const seededRuntime = seedPiRuntime(
3271
+ sourcePiHome,
3272
+ piCodingAgentDir,
3273
+ input.sourceAcquisition,
3274
+ mcpToolMode,
3275
+ input.baseEnv
3276
+ );
3264
3277
  const restoredNativeSession = restoreManagedPiSessionRollout(input, sessionsRoot, runDir, executorHome, authority);
3265
3278
  const configPath = join4(piCodingAgentDir, "mcp.json");
3266
3279
  const directToolNames = directCatalog?.tools.map((tool) => tool.exposedName) ?? [];
@@ -3274,7 +3287,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3274
3287
  const config = {
3275
3288
  settings: {
3276
3289
  toolPrefix: "none",
3277
- ...directCatalog ? { disableProxyTool: true } : {}
3290
+ ...mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? { disableProxyTool: true } : {}
3278
3291
  },
3279
3292
  mcpServers: {
3280
3293
  [SUPPORTED_SERVER_NAME2]: serverConfig
@@ -3319,6 +3332,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3319
3332
  name: tool.exposedName,
3320
3333
  schemaHash: tool.effectiveSchemaHash
3321
3334
  }))),
3335
+ proxyMode: mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE ? "required" : "forbidden",
3322
3336
  attestorSourceSha256,
3323
3337
  configSha256: sha256(readFileSync3(configPath)),
3324
3338
  cacheSha256
@@ -3333,10 +3347,12 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3333
3347
  configPath,
3334
3348
  configSha256: sha256(readFileSync3(configPath)),
3335
3349
  attestorSourceSha256,
3336
- effectiveSetHash: manifest.effectiveSetHash
3350
+ effectiveSetHash: manifest.effectiveSetHash,
3351
+ proxyMode: manifest.proxyMode
3337
3352
  };
3338
3353
  }
3339
3354
  const env = {
3355
+ ...seededRuntime.settingsEnv,
3340
3356
  ...buildIsolatedEnvironment2(input.baseEnv, input.commandEnv),
3341
3357
  HOME: home,
3342
3358
  PI_AGENT_HOME: piAgentHome,
@@ -3365,7 +3381,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3365
3381
  ...executorAttestation,
3366
3382
  mcpAdapterVersion: seededRuntime.adapterVersion,
3367
3383
  mcpToolMode,
3368
- mcpArgsNormalization: directCatalog ? "none" : MANAGED_PI_MCP_ARGS_NORMALIZATION,
3384
+ mcpArgsNormalization: mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? "none" : MANAGED_PI_MCP_ARGS_NORMALIZATION,
3369
3385
  ...directCatalog ? {
3370
3386
  catalogSetHash: directCatalog.setHash,
3371
3387
  ...effectiveToolsAttestation
@@ -3387,11 +3403,10 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3387
3403
  configPath,
3388
3404
  markerPath,
3389
3405
  env,
3390
- toolAllowlist: directCatalog ? [...directToolNames] : null,
3406
+ toolAllowlist: mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? [...directToolNames] : null,
3391
3407
  protectedValues: [.../* @__PURE__ */ new Set([
3392
3408
  sessionToken,
3393
3409
  ...seededRuntime.protectedValues,
3394
- ...MANAGED_TELEMETRY_PROTECTED_ENV_NAMES.map((name) => input.baseEnv?.[name]).filter((value) => typeof value === "string" && value.length > 0),
3395
3410
  ...MANAGED_PI_PROVIDER_PROTECTED_ENV_NAMES.map((name) => input.commandEnv?.[name]).filter((value) => typeof value === "string" && value.length > 0)
3396
3411
  ])],
3397
3412
  attestation: {
@@ -3408,6 +3423,9 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3408
3423
  function prepareDelegatedPiMcpProfile2(input) {
3409
3424
  assertInvocationIsolation2(input);
3410
3425
  const { gateway, gatewayUrl, sessionToken, headers, runId, mcpToolMode, directCatalog } = validateAuthority2(input);
3426
+ if (mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE) {
3427
+ throw new Error("pi_delegated_mcp_hybrid_unsupported: managed effective-tool attestation is required");
3428
+ }
3411
3429
  const runDir = resolve2(nonEmpty2(input.runDir, "runDir"));
3412
3430
  const cwd = resolve2(nonEmpty2(input.cwd, "cwd"));
3413
3431
  if (!within4(cwd, runDir)) throw new Error("pi_delegated_mcp_owner_mismatch: cwd is outside the managed run");
@@ -3453,7 +3471,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3453
3471
  ...sourceMcp,
3454
3472
  settings: {
3455
3473
  ...record8(sourceMcp.settings),
3456
- ...directCatalog ? { disableProxyTool: true } : {}
3474
+ ...mcpToolMode === MANAGED_PI_DIRECT_TYPED_MCP_TOOL_MODE ? { disableProxyTool: true } : {}
3457
3475
  },
3458
3476
  mcpServers: {
3459
3477
  ...record8(sourceMcp.mcpServers),
@@ -4043,6 +4061,39 @@ function retainedSourceExecutorEntry(entry, executorKind) {
4043
4061
  };
4044
4062
  }
4045
4063
 
4064
+ // src/amaster-runtime-daemon/task-context-policy.mjs
4065
+ var TASK_CONTEXT_MANIFEST_VERSION = "task-context-v1";
4066
+ function resolveTaskContextMemoryPolicy(context) {
4067
+ const contextRecord = asRecord(context);
4068
+ const hasManifest = Object.prototype.hasOwnProperty.call(contextRecord, "taskContextManifest");
4069
+ const manifest = asRecord(contextRecord.taskContextManifest);
4070
+ const version = readString(manifest.version);
4071
+ if (!hasManifest) {
4072
+ return {
4073
+ governed: false,
4074
+ memoryScope: null,
4075
+ allowAutomaticHistoricalContext: true,
4076
+ allowCompanyMemoryMount: true
4077
+ };
4078
+ }
4079
+ if (!version) throw new Error("task_context_manifest_version_required");
4080
+ if (version !== TASK_CONTEXT_MANIFEST_VERSION) {
4081
+ throw new Error(`task_context_manifest_version_unsupported:${version}`);
4082
+ }
4083
+ const memoryScope = readString(manifest.memoryScope);
4084
+ if (memoryScope !== "none" && memoryScope !== "task") {
4085
+ throw new Error("task_context_manifest_memory_scope_invalid");
4086
+ }
4087
+ return {
4088
+ governed: true,
4089
+ memoryScope,
4090
+ // The current runtime has Company memory, not a task-scoped memory store.
4091
+ // Governed scopes therefore never authorize Company history implicitly.
4092
+ allowAutomaticHistoricalContext: false,
4093
+ allowCompanyMemoryMount: false
4094
+ };
4095
+ }
4096
+
4046
4097
  // src/amaster-runtime-daemon/prompt-compiler.mjs
4047
4098
  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
4099
  var MIN_PROMPT_BUDGET_CHARS = 8192;
@@ -4295,14 +4346,15 @@ function resolvedDependencySections(context, input, contextScope, snapshotFreshn
4295
4346
  "Compare each returned latestRevisionId with the expected value. On revision mismatch, do not perform downstream writes; report it.",
4296
4347
  ...tuples.flatMap((tuple, index) => {
4297
4348
  const readArguments = { issueId: tuple.blockerSelector, key: tuple.key };
4298
- const call = input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only" ? {
4349
+ const directToolName = managedDirectToolName(input, "amaster.read_issue_document");
4350
+ const call = directToolName ? readArguments : input.executorKind === "pi" && managedPiMcpProxyAvailable(input) ? {
4299
4351
  server: "amaster",
4300
4352
  tool: "amaster.read_issue_document",
4301
4353
  args: JSON.stringify(readArguments)
4302
4354
  } : readArguments;
4303
4355
  return [
4304
4356
  `- 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)}`
4357
+ 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
4358
  ];
4307
4359
  })
4308
4360
  ].join("\n") : "";
@@ -4372,6 +4424,7 @@ function wikiAccessRuleLine(input) {
4372
4424
  return "";
4373
4425
  }
4374
4426
  function optionalTaskWikiContextSection(context) {
4427
+ if (!resolveTaskContextMemoryPolicy(context).allowAutomaticHistoricalContext) return null;
4375
4428
  const snapshot = asRecord(context.mirrorxTaskWikiContext);
4376
4429
  if (readString(snapshot.schemaVersion) !== "mirrorx.task-wiki-context.v1") return null;
4377
4430
  const querySeeds = (Array.isArray(snapshot.querySeeds) ? snapshot.querySeeds : []).map(readString).filter(Boolean).slice(0, 3);
@@ -4426,6 +4479,31 @@ function optionalTaskWikiContextSection(context) {
4426
4479
  truncationReason: ready ? null : `wiki_optional_context_gap:${readString(snapshot.gapCode) ?? "invalid_snapshot"}`
4427
4480
  };
4428
4481
  }
4482
+ function taskContextAuthoritySection(context) {
4483
+ const manifest = asRecord(context.taskContextManifest);
4484
+ if (readString(manifest.version) !== "task-context-v1") return null;
4485
+ const sourceRefs = (Array.isArray(manifest.sourceRefs) ? manifest.sourceRefs : []).map(asRecord).map((ref) => ({
4486
+ kind: readString(ref.kind),
4487
+ id: readString(ref.id),
4488
+ revision: readString(ref.revision),
4489
+ scope: readString(ref.scope),
4490
+ useReason: readString(ref.useReason)
4491
+ })).filter((ref) => ref.kind && ref.id && ref.revision && ref.scope);
4492
+ if (sourceRefs.length === 0) return null;
4493
+ return {
4494
+ content: [
4495
+ "Immutable Task admission context authority. It identifies admitted sources and automatic memory policy; it does not replace the runtime Context Manifest below.",
4496
+ jsonText({
4497
+ version: manifest.version,
4498
+ memoryScope: readString(manifest.memoryScope),
4499
+ freshness: readString(manifest.freshness),
4500
+ sourceRefs
4501
+ })
4502
+ ].join("\n"),
4503
+ sourceRef: sourceRefs.map((ref) => `${ref.kind}:${ref.id}@${ref.revision}`),
4504
+ scope: sourceRefs.map((ref) => ref.scope)
4505
+ };
4506
+ }
4429
4507
  function fixedRules(input, includeIssueLine) {
4430
4508
  const issue = asRecord(asRecord(input.context).paperclipIssue);
4431
4509
  const businessOutcome = asRecord(asRecord(issue.taskRequirements).businessOutcome);
@@ -4452,7 +4530,7 @@ function fixedRules(input, includeIssueLine) {
4452
4530
  wikiAccessRuleLine(input),
4453
4531
  "- 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
4532
  "- 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." : ""
4533
+ 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
4534
  ].filter(Boolean).join("\n");
4457
4535
  }
4458
4536
  function approvalContinuationText(input) {
@@ -4542,12 +4620,15 @@ function continuationRuntimeActionEnvelope(context) {
4542
4620
  return envelope;
4543
4621
  }
4544
4622
  function managedDirectToolName(input, canonicalName) {
4545
- if (input.managedMcpToolMode !== "direct_typed") return null;
4623
+ if (input.managedMcpToolMode !== "direct_typed" && input.managedMcpToolMode !== "hybrid") return null;
4546
4624
  const catalog = asRecord(input.managedMcpToolCatalog);
4547
4625
  const tools = Array.isArray(catalog.tools) ? catalog.tools.map(asRecord) : [];
4548
4626
  const match = tools.find((tool) => readString(tool.name) === canonicalName);
4549
4627
  return readString(match?.exposedName) ?? null;
4550
4628
  }
4629
+ function managedPiMcpProxyAvailable(input) {
4630
+ return input.managedMcpToolMode === "proxy_only" || input.managedMcpToolMode === "hybrid";
4631
+ }
4551
4632
  function runtimeActionContinuationOptionText(input) {
4552
4633
  if (!isRecoveryWakeReason(input.wakeReason)) return "";
4553
4634
  const heading = "### Runtime Action Continuation Option";
@@ -4566,12 +4647,8 @@ Runtime Action continuation is unavailable: managed governed MCP capability is m
4566
4647
  Runtime Action continuation is unavailable: continuationRuntimeActionEnvelope is missing or invalid. Do not guess a tool call.`;
4567
4648
  }
4568
4649
  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
- }
4650
+ const toolName = managedDirectToolName(input, "runtime_action.submit");
4651
+ if (toolName) {
4575
4652
  return [
4576
4653
  heading,
4577
4654
  `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 +4657,11 @@ Runtime Action continuation is unavailable: the run catalog does not advertise t
4580
4657
  "```"
4581
4658
  ].join("\n");
4582
4659
  }
4583
- if (input.managedMcpToolMode !== "proxy_only") {
4660
+ if (!managedPiMcpProxyAvailable(input)) {
4661
+ if (input.managedMcpToolMode === "direct_typed") {
4662
+ return `${heading}
4663
+ Runtime Action continuation is unavailable: the run catalog does not advertise the required typed submit tool. Do not guess a tool call.`;
4664
+ }
4584
4665
  return `${heading}
4585
4666
  Runtime Action continuation is unavailable: managed Pi MCP tool mode is not proxy_only. Do not guess a proxy or direct-tool call.`;
4586
4667
  }
@@ -4692,7 +4773,7 @@ function runtimeDecompositionRequirementText(context) {
4692
4773
  }
4693
4774
  function deliveryReadCallText(input) {
4694
4775
  const args = { issueId: input.issueId };
4695
- if (input.executorKind === "pi" && input.managedMcpToolMode === "proxy_only") {
4776
+ if (input.executorKind === "pi" && managedPiMcpProxyAvailable(input)) {
4696
4777
  return `emit an mcp proxy call: ${JSON.stringify({
4697
4778
  server: "amaster",
4698
4779
  tool: "amaster.read_issue_delivery",
@@ -4763,7 +4844,11 @@ function runtimeDeliveryReadinessText(context, input) {
4763
4844
  }
4764
4845
  function readIssueEvidenceCommentCallText(issueId, commentId, options) {
4765
4846
  const readArguments = { refs: [{ kind: "issue_comment", issueId, commentId }] };
4766
- if (options?.executorKind === "pi" && options?.managedMcpToolMode === "proxy_only") {
4847
+ const directToolName = managedDirectToolName(options ?? {}, "amaster.read_issue_evidence");
4848
+ if (directToolName) {
4849
+ return `call \`${directToolName}\` with these exact object arguments: ${JSON.stringify(readArguments)}`;
4850
+ }
4851
+ if (options?.executorKind === "pi" && managedPiMcpProxyAvailable(options)) {
4767
4852
  return `emit an mcp proxy call: ${JSON.stringify({ server: "amaster", tool: "amaster.read_issue_evidence", args: JSON.stringify(readArguments) })}`;
4768
4853
  }
4769
4854
  return `call amaster.read_issue_evidence with these exact arguments: ${JSON.stringify(readArguments)}`;
@@ -4781,36 +4866,37 @@ function taskCommentRefGuidance(input) {
4781
4866
  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
4867
  }
4783
4868
  function piMcpProxyExamplesText(input) {
4784
- if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "proxy_only" || isRecoveryWakeReason(input.wakeReason)) return "";
4869
+ if (!input.hasGovernedMcp || input.executorKind !== "pi" || !managedPiMcpProxyAvailable(input) || isRecoveryWakeReason(input.wakeReason)) return "";
4870
+ const hybrid = input.managedMcpToolMode === "hybrid";
4785
4871
  const proxy = (tool, args) => JSON.stringify({
4786
4872
  server: "amaster",
4787
4873
  tool,
4788
4874
  args: JSON.stringify(args)
4789
4875
  });
4790
4876
  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`:",
4877
+ 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
4878
  "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
4879
  "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
4880
  "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" })}`,
4881
+ ...!hybrid ? [`- describe: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`] : [],
4796
4882
  `- submit: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-progress", action: { type: "update_parent", status: "in_progress" } })}`,
4797
4883
  `- 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
4884
  `- plan: ${proxy("runtime_action.plan", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-plan", actions: [{ type: "update_parent", status: "in_progress" }] })}`,
4799
4885
  `- 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" })}`
4886
+ ...!hybrid ? [`- read document: ${proxy("amaster.read_issue_document", { issueId: "AM-123", key: "plan" })}`] : []
4801
4887
  ].join("\n");
4802
4888
  }
4803
4889
  function piDirectTypedToolsText(input) {
4804
- if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "direct_typed") return "";
4890
+ if (!input.hasGovernedMcp || input.executorKind !== "pi" || input.managedMcpToolMode !== "direct_typed" && input.managedMcpToolMode !== "hybrid") return "";
4805
4891
  const catalog = asRecord(input.managedMcpToolCatalog);
4806
4892
  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
4893
  if (tools.length === 0) {
4808
4894
  return "Direct typed governed tools are unavailable because the run catalog snapshot is empty. Do not guess a proxy or tool name.";
4809
4895
  }
4810
4896
  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.",
4897
+ 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
4898
  ...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."
4899
+ 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
4900
  ].join("\n");
4815
4901
  }
4816
4902
  function sectionText(section) {
@@ -4919,9 +5005,14 @@ function compileCommandPromptWithManifest(input, options = {}) {
4919
5005
  resolvedDependencies.details.content ? `Auxiliary predecessor context (may be truncated):
4920
5006
  ${resolvedDependencies.details.content}` : ""
4921
5007
  ].filter(Boolean).join("\n\n") : "";
4922
- const piMcpProxyExamples = resolvedDependencies.required.content ? "" : [piMcpProxyExamplesText(input), piDirectTypedToolsText(input)].filter(Boolean).join("\n");
5008
+ const piDirectTypedTools = piDirectTypedToolsText(input);
5009
+ const piMcpProxyExamples = [
5010
+ resolvedDependencies.required.content ? "" : piMcpProxyExamplesText(input),
5011
+ piDirectTypedTools
5012
+ ].filter(Boolean).join("\n");
4923
5013
  const deliveryReadinessContent = runtimeDeliveryReadinessText(context, input);
4924
5014
  const optionalTaskWikiContext = optionalTaskWikiContextSection(context);
5015
+ const taskContextAuthority = taskContextAuthoritySection(context);
4925
5016
  const rawSections = [
4926
5017
  { name: "recovery_instruction", title: "Recovery Instruction", priority: 100, sourceRef: `run:${input.runId ?? "unknown"}`, content: completeRecoveryInstruction, truncationReason: completeRecoveryInstruction ? null : "mode_selection" },
4927
5018
  { 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 +5031,15 @@ ${resolvedDependencies.details.content}` : ""
4940
5031
  { name: "runtime_rules", title: "", priority: 100, sourceRef: `command:${input.commandId}`, content: fixedRules(input, !hasTask) },
4941
5032
  { name: "runtime_authorization", title: "Runtime Action Contract", priority: 98, sourceRef: `run:${input.runId ?? "unknown"}`, content: runtimeAuthorizationText(context, mode, { suppressOrdinaryCompletionContract }) },
4942
5033
  { name: "runtime_decomposition_requirement", title: "Required Task Decomposition", priority: 98, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: runtimeDecompositionRequirementText(context) },
5034
+ ...taskContextAuthority ? [{ name: "task_context_authority", title: "Task Context Authority", priority: 98, ...taskContextAuthority }] : [],
4943
5035
  ...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 }] : [],
5036
+ ...piMcpProxyExamples ? [{
5037
+ name: "pi_mcp_proxy_examples",
5038
+ title: piDirectTypedTools ? "Pi Governed MCP Tools" : "Pi MCP Proxy Examples",
5039
+ priority: 96,
5040
+ sourceRef: "amaster_governed_mcp_proxy_contract",
5041
+ content: piMcpProxyExamples
5042
+ }] : [],
4945
5043
  { 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
5044
  ...optionalTaskWikiContext ? [optionalTaskWikiContext] : [],
4947
5045
  { name: "agent_instructions", title: "Agent Instructions", priority: 100, sourceRef: "agent_instructions_bundle", content: readString(input.agentInstructions) ?? "" },
@@ -9546,7 +9644,7 @@ function assertSourceAcquisitionRuntimeAuthority({
9546
9644
  }
9547
9645
 
9548
9646
  // src/amaster-runtime-daemon.mjs
9549
- var CONNECTOR_VERSION = "0.1.1-beta.15";
9647
+ var CONNECTOR_VERSION = "0.1.1-beta.17";
9550
9648
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
9551
9649
  var SOURCE_ACQUISITION_CAPABILITY = "source_acquisition_v1";
9552
9650
  var SOURCE_ACQUISITION_PROFILE_VERSION = "source_acquisition_v1";
@@ -14027,6 +14125,9 @@ async function executeRunCommand(config, command) {
14027
14125
  throw new Error(`runtime_actions_v2_preflight_failed: ${executor.kind} command lacks an exact managed governed MCP profile`);
14028
14126
  }
14029
14127
  const workspace = resolveExecutionWorkspace(config, command, { executorKind: executor.kind });
14128
+ const taskContextMemoryPolicy = resolveTaskContextMemoryPolicy(
14129
+ asRecord(asRecord(command.payload).contextSnapshot)
14130
+ );
14030
14131
  const cwd = workspace.cwd;
14031
14132
  try {
14032
14133
  await materializeAgentInstructionsBundle(config, command, workspace);
@@ -14238,20 +14339,26 @@ async function executeRunCommand(config, command) {
14238
14339
  }
14239
14340
  if (piChildAllocator2) {
14240
14341
  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
- });
14342
+ const companyMemoryGroup = taskContextMemoryPolicy.allowCompanyMemoryMount ? (() => {
14343
+ const companyId = readString(commandRuntimeAuth(command).companyId) ?? readString(asRecord(command.payload).companyId);
14344
+ if (!companyId) throw new Error("pi_company_memory_company_id_required");
14345
+ return {
14346
+ companyId,
14347
+ ...resolveCompanyPiMemoryGroup({
14348
+ root: companyPiHomeRoot(process.env),
14349
+ companyId
14350
+ })
14351
+ };
14352
+ })() : null;
14353
+ const assignment = piChildAllocator2.acquire(
14354
+ commandRunId(command),
14355
+ companyMemoryGroup ? { gid: companyMemoryGroup.gid } : {}
14356
+ );
14250
14357
  piChildAssignmentAcquired = true;
14251
- if (managedMcpProfile) {
14358
+ if (managedMcpProfile && companyMemoryGroup) {
14252
14359
  piCompanyMemory = prepareCompanyPiMemory({
14253
14360
  root: companyMemoryGroup.root,
14254
- companyId,
14361
+ companyId: companyMemoryGroup.companyId,
14255
14362
  gid: companyMemoryGroup.gid,
14256
14363
  profileRoot: managedMcpProfile.profileRoot,
14257
14364
  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.17";
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.17",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",