@amaster.ai/employee-runtime-connector 0.1.14 → 0.1.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.
@@ -83,7 +83,7 @@ function withAuditCorrelationEnvironment(environment, command) {
83
83
  }
84
84
 
85
85
  // src/amaster-runtime-daemon.mjs
86
- import { createHash as createHash20, randomUUID as randomUUID3 } from "node:crypto";
86
+ import { createHash as createHash21, randomUUID as randomUUID3 } from "node:crypto";
87
87
  import { createRequire } from "node:module";
88
88
 
89
89
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
@@ -5069,7 +5069,8 @@ var AMASTER_RUNTIME_CONNECTOR_COMMAND_TYPES = [
5069
5069
  "wakeup",
5070
5070
  "model_call",
5071
5071
  "cancel",
5072
- "terminate"
5072
+ "terminate",
5073
+ "browser_session_revoke"
5073
5074
  ];
5074
5075
  var AMASTER_RUNTIME_CONNECTOR_COMMAND_STATUSES = [
5075
5076
  "queued",
@@ -9627,7 +9628,7 @@ var taskResourceInputSchema = external_exports.discriminatedUnion("kind", [
9627
9628
  });
9628
9629
  }
9629
9630
  });
9630
- var browserCredentialRefAuthoritySchema = external_exports.object({
9631
+ var browserCredentialRefV1Schema = external_exports.object({
9631
9632
  version: external_exports.literal(1),
9632
9633
  companyId: external_exports.string().uuid(),
9633
9634
  issueId: external_exports.string().uuid(),
@@ -9642,9 +9643,39 @@ var browserCredentialRefAuthoritySchema = external_exports.object({
9642
9643
  bindingId: external_exports.string().uuid(),
9643
9644
  browserLeaseId: external_exports.string().regex(/^browser-credential-(?:auth-write|agent-read)-[0-9a-f-]{36}$/iu)
9644
9645
  }).strict();
9645
- var browserCredentialRefConsumeSchema = browserCredentialRefAuthoritySchema.extend({
9646
- controlSemantic: external_exports.enum(["username", "email", "password"])
9646
+ var browserCredentialRefV2BaseSchema = external_exports.object({
9647
+ version: external_exports.literal(2),
9648
+ companyId: external_exports.string().uuid(),
9649
+ issueId: external_exports.string().uuid(),
9650
+ runId: external_exports.string().uuid(),
9651
+ commandId: external_exports.string().uuid(),
9652
+ grantId: external_exports.string().uuid(),
9653
+ grantRevision: external_exports.number().int().positive(),
9654
+ commandAuthId: external_exports.string().uuid(),
9655
+ credentialKey: external_exports.string().trim().min(1).max(255),
9656
+ credentialVersion: external_exports.number().int().positive(),
9657
+ credentialRole: external_exports.enum(BROWSER_CREDENTIAL_ROLES),
9658
+ targetOrigin: exactOriginSchema,
9659
+ authenticationOrigin: exactOriginSchema
9660
+ });
9661
+ var browserCredentialRefV2InteractionSchema = browserCredentialRefV2BaseSchema.extend({
9662
+ grantKind: external_exports.literal("interaction"),
9663
+ interactionId: external_exports.string().uuid()
9647
9664
  }).strict();
9665
+ var browserCredentialRefV2StoredSchema = browserCredentialRefV2BaseSchema.extend({
9666
+ grantKind: external_exports.literal("stored_grant")
9667
+ }).strict();
9668
+ var browserCredentialRefAuthoritySchema = external_exports.union([
9669
+ browserCredentialRefV1Schema,
9670
+ browserCredentialRefV2InteractionSchema,
9671
+ browserCredentialRefV2StoredSchema
9672
+ ]);
9673
+ var controlSemanticSchema = external_exports.enum(["username", "email", "password"]);
9674
+ var browserCredentialRefConsumeSchema = external_exports.union([
9675
+ browserCredentialRefV1Schema.extend({ controlSemantic: controlSemanticSchema }),
9676
+ browserCredentialRefV2InteractionSchema.extend({ controlSemantic: controlSemanticSchema }),
9677
+ browserCredentialRefV2StoredSchema.extend({ controlSemantic: controlSemanticSchema })
9678
+ ]);
9648
9679
  var runtimeWebEvidenceReceiptSchema = external_exports.object({
9649
9680
  issueId: external_exports.string().uuid(),
9650
9681
  runId: external_exports.string().uuid(),
@@ -13746,7 +13777,7 @@ var ceoExecutionAffordanceSchema = external_exports.object({
13746
13777
  status: external_exports.enum(["available", "confirmation_required", "unavailable"]),
13747
13778
  effectKinds: external_exports.array(external_exports.enum(["read", "download", "upload", "external_write", "readback"])).min(1).max(5),
13748
13779
  source: external_exports.object({
13749
- kind: external_exports.enum(["pi_runtime", "browser_session", "helige", "governed_mcp"]),
13780
+ kind: external_exports.enum(["pi_runtime", "browser_session", "browser_grant", "helige", "governed_mcp"]),
13750
13781
  ref: external_exports.string().trim().min(1).max(240),
13751
13782
  revision: external_exports.string().trim().min(1).max(240)
13752
13783
  }).strict(),
@@ -19173,6 +19204,10 @@ var wikiMentionPageSchema = external_exports.object({
19173
19204
  contentHash: external_exports.string().regex(/^[a-f0-9]{64}$/),
19174
19205
  byteSize: external_exports.number().int().nonnegative()
19175
19206
  });
19207
+ var wikiTrashPageSchema = wikiMentionPageSchema.extend({
19208
+ archivedAt: external_exports.string(),
19209
+ archiveReason: external_exports.string().nullable()
19210
+ });
19176
19211
  var wikiMentionListSchema = external_exports.object({
19177
19212
  pages: external_exports.array(wikiMentionPageSchema),
19178
19213
  nextCursor: external_exports.string().nullable()
@@ -20129,7 +20164,7 @@ function preparePiExecutorAccess(input) {
20129
20164
  }
20130
20165
 
20131
20166
  // src/amaster-runtime-daemon/browser-session-profile.mjs
20132
- import { randomUUID as randomUUID2 } from "node:crypto";
20167
+ import { createHash as createHash5, randomUUID as randomUUID2 } from "node:crypto";
20133
20168
  import {
20134
20169
  chmodSync as chmodSync2,
20135
20170
  chownSync as chownSync2,
@@ -20145,6 +20180,22 @@ import {
20145
20180
  import { parse, resolve as resolve4, join as join5, dirname as dirname2 } from "node:path";
20146
20181
  import { spawnSync } from "node:child_process";
20147
20182
  var MARKERS = ".owners";
20183
+ function browserGrantProfileIdentity(companyId, origin) {
20184
+ let parsedOrigin;
20185
+ try {
20186
+ parsedOrigin = new URL(origin);
20187
+ } catch {
20188
+ }
20189
+ if (typeof companyId !== "string" || !/^[0-9a-f-]{36}$/iu.test(companyId) || !parsedOrigin || parsedOrigin.protocol !== "https:" || parsedOrigin.origin !== origin || parsedOrigin.username || parsedOrigin.password) {
20190
+ throw new Error("browser_session_profile_identity_invalid");
20191
+ }
20192
+ return {
20193
+ version: 2,
20194
+ companyId,
20195
+ origin,
20196
+ localOpaqueRef: `profile_${createHash5("sha256").update(`mirrorx-company-origin-browser\0${companyId}\0${origin}`).digest("hex").slice(0, 32)}`
20197
+ };
20198
+ }
20148
20199
  function statOrNull(path) {
20149
20200
  try {
20150
20201
  return lstatSync4(path);
@@ -20284,7 +20335,7 @@ function cleanupUnprivilegedBrowserSessionProfile(input) {
20284
20335
  }
20285
20336
 
20286
20337
  // src/amaster-runtime-daemon/codex-managed-mcp-profile.mjs
20287
- import { createHash as createHash5 } from "node:crypto";
20338
+ import { createHash as createHash6 } from "node:crypto";
20288
20339
  import { chmodSync as chmodSync3, existsSync as existsSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync2, realpathSync as realpathSync4, readdirSync as readdirSync3, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
20289
20340
  import { arch, platform } from "node:os";
20290
20341
  import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join7, relative, resolve as resolve5 } from "node:path";
@@ -21518,7 +21569,7 @@ function restoreManagedCodexSessionRollout(input, codexHome, runDir, executorHom
21518
21569
  }
21519
21570
  const sourceWorkspacePath = nonEmpty(session.cwd, "nativeSession.cwd");
21520
21571
  const issueRoot = dirname3(runDir);
21521
- const managedSourceRunDirName = `${sourceRunId}-${createHash5("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
21572
+ const managedSourceRunDirName = `${sourceRunId}-${createHash6("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
21522
21573
  const sourceRunDirs = readdirSync3(issueRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() && (entry.name === sourceRunId || entry.name === managedSourceRunDirName)).map((entry) => join7(issueRoot, entry.name));
21523
21574
  if (sourceRunDirs.length !== 1) {
21524
21575
  throw new Error(`codex_managed_mcp_session_rollout_missing: expected one source run directory for ${sourceRunId}, received ${sourceRunDirs.length}`);
@@ -21947,7 +21998,7 @@ function prepareManagedCodexMcpProfile(input) {
21947
21998
  protectedValues: [.../* @__PURE__ */ new Set([sessionToken, ...auth.protectedValues])],
21948
21999
  attestation: {
21949
22000
  ...attestationFacts,
21950
- attestationId: createHash5("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
22001
+ attestationId: createHash6("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
21951
22002
  attestedAt: (/* @__PURE__ */ new Date()).toISOString(),
21952
22003
  authMode: auth.authMode
21953
22004
  }
@@ -22109,7 +22160,7 @@ function reconcileManagedCodexMcpProfiles(rootPath, options = {}) {
22109
22160
  }
22110
22161
 
22111
22162
  // src/amaster-runtime-daemon/codebuddy-managed-mcp-profile.mjs
22112
- import { createHash as createHash8 } from "node:crypto";
22163
+ import { createHash as createHash9 } from "node:crypto";
22113
22164
  import {
22114
22165
  chmodSync as chmodSync4,
22115
22166
  closeSync as closeSync3,
@@ -22130,11 +22181,11 @@ import { arch as arch2, homedir as homedir2, platform as platform2 } from "node:
22130
22181
  import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute3, join as join8, parse as parse3, relative as relative2, resolve as resolve6, sep as sep2 } from "node:path";
22131
22182
 
22132
22183
  // src/amaster-runtime-daemon/codebuddy-profile-policy.mjs
22133
- import { createHash as createHash7 } from "node:crypto";
22184
+ import { createHash as createHash8 } from "node:crypto";
22134
22185
  import { platform as hostPlatform } from "node:os";
22135
22186
 
22136
22187
  // src/amaster-runtime-daemon/pi-governed-tool-contract.mjs
22137
- import { createHash as createHash6 } from "node:crypto";
22188
+ import { createHash as createHash7 } from "node:crypto";
22138
22189
  var MANAGED_PI_TOOL_INPUT_GUARD_FILENAME = "amaster-governed-tool-input-guard.js";
22139
22190
  function stablePiJson(value) {
22140
22191
  if (value === null || value === void 0 || typeof value !== "object") {
@@ -22146,7 +22197,7 @@ function stablePiJson(value) {
22146
22197
  return `{${keys.map((key) => `${JSON.stringify(key)}:${stablePiJson(value[key])}`).join(",")}}`;
22147
22198
  }
22148
22199
  function stablePiSha256(value) {
22149
- return createHash6("sha256").update(value).digest("hex");
22200
+ return createHash7("sha256").update(value).digest("hex");
22150
22201
  }
22151
22202
  function stablePiToolSchemaHash(schema, options = {}) {
22152
22203
  const value = schema && typeof schema === "object" && !Array.isArray(schema) ? schema : {};
@@ -22485,7 +22536,7 @@ function fail2(detail) {
22485
22536
  throw new Error(`codebuddy_managed_mcp_invalid: ${detail}`);
22486
22537
  }
22487
22538
  function sha256(value) {
22488
- return createHash7("sha256").update(value).digest("hex");
22539
+ return createHash8("sha256").update(value).digest("hex");
22489
22540
  }
22490
22541
  function codebuddyMcpName(exposedName) {
22491
22542
  return `mcp__${CODEBUDDY_MCP_NAMESPACE}__${exposedName.replaceAll(".", "_")}`;
@@ -23066,7 +23117,7 @@ function restoreManagedCodebuddySessionRollout(input, configDir, runDir, executo
23066
23117
  }
23067
23118
  const sourceWorkspacePath = nonEmpty2(session.cwd, "nativeSession.cwd");
23068
23119
  const issueRoot = dirname4(runDir);
23069
- const managedSourceRunName = `${sourceRunId}-${createHash8("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
23120
+ const managedSourceRunName = `${sourceRunId}-${createHash9("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
23070
23121
  const sourceRuns = readdirSync4(issueRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() && [sourceRunId, managedSourceRunName].includes(entry.name)).map((entry) => join8(issueRoot, entry.name));
23071
23122
  if (sourceRuns.length !== 1) {
23072
23123
  throw new Error(`codebuddy_managed_mcp_session_rollout_missing: expected one source run directory for ${sourceRunId}, received ${sourceRuns.length}`);
@@ -23379,7 +23430,7 @@ function prepareManagedCodebuddyMcpProfile(input, options = {}) {
23379
23430
  protectedValues: [authority.sessionToken, ...provider.protectedValues],
23380
23431
  attestation: {
23381
23432
  ...attestationFacts,
23382
- attestationId: createHash8("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
23433
+ attestationId: createHash9("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
23383
23434
  attestedAt: (/* @__PURE__ */ new Date()).toISOString(),
23384
23435
  authMode: provider.authMode ?? desktopAuthSnapshot.authMode,
23385
23436
  authScope: provider.authScope ?? "desktop_os_user",
@@ -23609,8 +23660,8 @@ async function runInitializationCompletion({ plan, authority, call, sleep, now,
23609
23660
  fail4("initialization_completion_invalid_plan");
23610
23661
  }
23611
23662
  const prefix = "initialization-complete:" + plan.planId;
23612
- const { createHash: createHash21 } = await import("node:crypto");
23613
- const uploadKey = prefix + ":upload:" + createHash21("sha256").update(materialized.path).digest("hex");
23663
+ const { createHash: createHash22 } = await import("node:crypto");
23664
+ const uploadKey = prefix + ":upload:" + createHash22("sha256").update(materialized.path).digest("hex");
23614
23665
  const upload = await settleCall(await invoke("runtime_action_submit", {
23615
23666
  idempotencyKey: uploadKey,
23616
23667
  action: {
@@ -23898,7 +23949,7 @@ export default function(pi) {
23898
23949
  }
23899
23950
 
23900
23951
  // src/amaster-runtime-daemon/pi-managed-mcp-profile.mjs
23901
- import { createHash as createHash9 } from "node:crypto";
23952
+ import { createHash as createHash10 } from "node:crypto";
23902
23953
  import {
23903
23954
  chmodSync as chmodSync5,
23904
23955
  chownSync as chownSync3,
@@ -24761,7 +24812,7 @@ function createManagedPiMcpProfileApi(options = {}) {
24761
24812
  return { ...installed, sourceRunId, sourceCommandId, cacheRoot: null };
24762
24813
  }
24763
24814
  const issueRoot = dirname6(runDir);
24764
- const managedSourceRunDirName = `${sourceRunId}-${createHash9("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
24815
+ const managedSourceRunDirName = `${sourceRunId}-${createHash10("sha256").update(sourceRunId).digest("hex").slice(0, 8)}`;
24765
24816
  const sourceRunDirs = readdirSync5(issueRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.isSymbolicLink() && (entry.name === sourceRunId || entry.name === managedSourceRunDirName)).map((entry) => join11(issueRoot, entry.name));
24766
24817
  if (sourceRunDirs.length !== 1) {
24767
24818
  throw new Error(`pi_managed_mcp_session_rollout_missing: expected one source run directory for ${sourceRunId}, received ${sourceRunDirs.length}`);
@@ -24829,12 +24880,12 @@ function createManagedPiMcpProfileApi(options = {}) {
24829
24880
  return value;
24830
24881
  }
24831
24882
  function sha2563(value) {
24832
- return createHash9("sha256").update(value).digest("hex");
24883
+ return createHash10("sha256").update(value).digest("hex");
24833
24884
  }
24834
24885
  function trustedTreeDigest(rootPath, options2 = {}) {
24835
24886
  const root = resolve8(rootPath);
24836
24887
  const ignoredRootEntries = new Set(Array.isArray(options2.ignoredRootEntries) ? options2.ignoredRootEntries : []);
24837
- const hash3 = createHash9("sha256");
24888
+ const hash3 = createHash10("sha256");
24838
24889
  hash3.update(`ignored-root:${[...ignoredRootEntries].sort().join(",")}
24839
24890
  `);
24840
24891
  const pending = [root];
@@ -24979,7 +25030,7 @@ function createManagedPiMcpProfileApi(options = {}) {
24979
25030
  if (!executableStat.isFile() || executableStat.isSymbolicLink()) {
24980
25031
  throw Object.assign(new Error("Pi executable is not a regular file"), { code: "EUNSAFE" });
24981
25032
  }
24982
- const contentSha256 = createHash9("sha256").update(readFileSync7(realPath)).digest("hex");
25033
+ const contentSha256 = createHash10("sha256").update(readFileSync7(realPath)).digest("hex");
24983
25034
  let packageManifestSha256 = null;
24984
25035
  for (let directory = dirname6(realPath); dirname6(directory) !== directory; directory = dirname6(directory)) {
24985
25036
  const packagePath = join11(directory, "package.json");
@@ -24987,7 +25038,7 @@ function createManagedPiMcpProfileApi(options = {}) {
24987
25038
  packageManifestSha256 = sha2563(readFileSync7(packagePath));
24988
25039
  break;
24989
25040
  }
24990
- return `sha256:${createHash9("sha256").update(JSON.stringify({ realPath, contentSha256, packageManifestSha256 })).digest("hex")}`;
25041
+ return `sha256:${createHash10("sha256").update(JSON.stringify({ realPath, contentSha256, packageManifestSha256 })).digest("hex")}`;
24991
25042
  } catch (error) {
24992
25043
  const errorCode = typeof error?.code === "string" ? error.code : "UNKNOWN";
24993
25044
  throw new Error(`pi_managed_mcp_attestation_failed: --version error=${errorCode}`);
@@ -25776,7 +25827,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
25776
25827
  ])],
25777
25828
  attestation: {
25778
25829
  ...attestationFacts,
25779
- attestationId: createHash9("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
25830
+ attestationId: createHash10("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
25780
25831
  attestedAt: (/* @__PURE__ */ new Date()).toISOString()
25781
25832
  }
25782
25833
  };
@@ -26052,7 +26103,7 @@ ${result2.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
26052
26103
  protectedValues: [.../* @__PURE__ */ new Set([sessionToken, ...seededRuntime.protectedValues])],
26053
26104
  attestation: {
26054
26105
  ...attestationFacts,
26055
- attestationId: createHash9("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
26106
+ attestationId: createHash10("sha256").update(JSON.stringify(attestationFacts)).digest("hex"),
26056
26107
  attestedAt: (/* @__PURE__ */ new Date()).toISOString()
26057
26108
  }
26058
26109
  };
@@ -26291,7 +26342,7 @@ function selectExecutor(config, command) {
26291
26342
  }
26292
26343
 
26293
26344
  // src/amaster-runtime-daemon/web-evidence.mjs
26294
- import { createHash as createHash10 } from "node:crypto";
26345
+ import { createHash as createHash11 } from "node:crypto";
26295
26346
  var SENSITIVE_QUERY_KEY_FRAGMENTS = [
26296
26347
  "apikey",
26297
26348
  "accesskey",
@@ -26346,7 +26397,7 @@ function sanitizeRuntimeWebEvidence(input) {
26346
26397
  mediaType: typeof input.mediaType === "string" && input.mediaType.trim() ? input.mediaType.trim() : "text/plain",
26347
26398
  normalizedText,
26348
26399
  truncated: input.truncated === true || cleanedText.length > 2e5,
26349
- contentSha256: createHash10("sha256").update(bytes).digest("hex"),
26400
+ contentSha256: createHash11("sha256").update(bytes).digest("hex"),
26350
26401
  observedChars: normalizedText.length,
26351
26402
  observedBytes: bytes.byteLength
26352
26403
  };
@@ -26375,7 +26426,7 @@ function runtimeExactTaskResourceBinding(payload) {
26375
26426
  } catch {
26376
26427
  return null;
26377
26428
  }
26378
- if (createHash10("sha256").update(locator).digest("hex") !== binding.locatorFingerprint) return null;
26429
+ if (createHash11("sha256").update(locator).digest("hex") !== binding.locatorFingerprint) return null;
26379
26430
  return {
26380
26431
  locator,
26381
26432
  locatorFingerprint: binding.locatorFingerprint
@@ -30240,11 +30291,11 @@ function selectRuntimeCommandsWithinLaneLimits(input) {
30240
30291
  }
30241
30292
 
30242
30293
  // src/amaster-runtime-daemon/prompt-compiler.mjs
30243
- import { createHash as createHash12 } from "node:crypto";
30294
+ import { createHash as createHash13 } from "node:crypto";
30244
30295
  import { isAbsolute as isAbsolute5 } from "node:path";
30245
30296
 
30246
30297
  // src/amaster-runtime-daemon/current-run-contract.mjs
30247
- import { createHash as createHash11 } from "node:crypto";
30298
+ import { createHash as createHash12 } from "node:crypto";
30248
30299
  var CONTRACT_VERSION = "mirrorx.current-run-contract.v1";
30249
30300
  var REQUIRED_ACTIONS = [
30250
30301
  "mirrorx.read_issue_delivery",
@@ -30276,7 +30327,7 @@ function canonicalJson(value) {
30276
30327
  }
30277
30328
  function semanticHash(contract) {
30278
30329
  const { contractHash: _contractHash, compiledAt: _compiledAt, ...semantic } = contract;
30279
- return `sha256:${createHash11("sha256").update(canonicalJson(semantic)).digest("hex")}`;
30330
+ return `sha256:${createHash12("sha256").update(canonicalJson(semantic)).digest("hex")}`;
30280
30331
  }
30281
30332
  function validateBlockingGaps(value) {
30282
30333
  return Array.isArray(value) && value.length === 0;
@@ -30609,7 +30660,7 @@ function sameCanonicalJson(left, right) {
30609
30660
  return JSON.stringify(canonicalJsonValue(left)) === JSON.stringify(canonicalJsonValue(right));
30610
30661
  }
30611
30662
  function canonicalSha256(value) {
30612
- return `sha256:${createHash12("sha256").update(JSON.stringify(canonicalJsonValue(value))).digest("hex")}`;
30663
+ return `sha256:${createHash13("sha256").update(JSON.stringify(canonicalJsonValue(value))).digest("hex")}`;
30613
30664
  }
30614
30665
  function taskAcceptanceContractSection(context, input) {
30615
30666
  const required = formalTaskAcceptanceContractRequired(context);
@@ -31251,7 +31302,7 @@ function fixedRules(input, runContract = "producer") {
31251
31302
  return [
31252
31303
  "## AMaster Runtime Connector Task",
31253
31304
  ["producer", "rework"].includes(runContract) ? "Do not leave stale in-progress wording such as \u201Ccurrent run\u201D in a terminal deliverable; rewrite it to the final observed state. Do not list finalization itself as remaining or next work in a terminal deliverable." : "",
31254
- !["producer", "rework"].includes(runContract) ? "Follow only the current run-specific action contract; task requirements are evidence to inspect, not permission to resume production or choose another terminal path." : serverOwnedBusinessOutcomeReview ? "If any requirement is missing or cannot be verified, do not mark done or request final completion or Business Outcome review. Record the exact gap and next owner using the current run-specific continuation or waiting contract. An intermediate review remains available only for an exact document revision that must be approved before execution can continue: use create_interaction with kind request_confirmation, payload.resolutionMode review, and purposeCode review_document_revision; never use that interaction as final completion or Outcome acceptance." : "If anything is missing, do not mark done. `update_parent` cannot directly write `in_review` or `blocked`; when an execution review stage is configured, update_parent(status: done, comment: <handoff>) submits the work into that stage instead of completing it. Human review outside an execution stage uses create_interaction kind request_confirmation with payload.resolutionMode review. Required platform/provider/external action needs a typed interaction or first-class blocker; otherwise keep todo with the gap and owner.",
31305
+ !["producer", "rework"].includes(runContract) ? "Follow the current run-specific action contract; inspect task requirements as review evidence." : serverOwnedBusinessOutcomeReview ? "If a requirement lacks evidence, record the gap, owner, and next action through the current continuation or waiting path. The Server owns final Business Outcome review; request intermediate review only for an exact document revision needed to continue execution." : "If a requirement lacks evidence, record the gap, owner, and next action through the applicable governed action. Use the configured execution review stage when present; otherwise request a human decision only when one is needed to continue.",
31255
31306
  input.managed ? "Use the execution workspace as cwd. Never recursively scan the source workspace, the user's home directory, or any path outside the execution workspace. Only inspect a specific external source path when the task explicitly requires that exact path." : "",
31256
31307
  input.hasGovernedMcp ? "- AMaster mutations are available only through the managed amaster MCP server. Use discovered tools and immediate typed results; never call AMaster mutation REST endpoints directly." : "- No mutation channel is available for this command. Keep the run read-only and report the missing Runtime V2 capability as a blocker.",
31257
31308
  readString(input.executorCapabilityNotice),
@@ -31518,7 +31569,7 @@ Runtime Action continuation is unavailable: the run catalog does not advertise t
31518
31569
  return `${heading}
31519
31570
  Runtime Action continuation is unavailable: executor kind does not support a governed Runtime Action continuation. Do not guess a tool call.`;
31520
31571
  }
31521
- function runtimeAuthorizationText(context, mode, {
31572
+ function runtimeAuthorizationText(context, {
31522
31573
  replayAlreadyInTask = false,
31523
31574
  runContract = "producer",
31524
31575
  pendingExecutionStages = [],
@@ -31548,10 +31599,10 @@ function runtimeAuthorizationText(context, mode, {
31548
31599
  const delegatedAggregationEvidence = asRecord(context.paperclipDelegatedAggregationEvidence);
31549
31600
  const delegatedDelivery = readString(delegatedAggregationEvidence.schemaVersion) === "delegated-aggregation-evidence-v1" && readString(delegatedAggregationEvidence.finalAggregationIssueId) && readString(delegatedAggregationEvidence.manifestId) && readString(delegatedAggregationEvidence.packageReviewInteractionId);
31550
31601
  const manifestRefreshOnly = legacyManifestRefreshOnly(context);
31551
- const firstDocumentCheckpoint = completionDeliverable === "document_or_artifact" && !delegatedDelivery ? manifestRefreshOnly ? "The current deliverable content already exists and this run is limited to refreshing stale immutable Manifest refs. Do not create or revise a document unless a fresh Delivery readiness read proves a content or acceptance gap beyond stale refs." : mode === "cold" ? continueTaskEnabled ? "Before the first external browse, search, or research action, call upsert_document with a stable key. Create a checkpoint skeleton containing the acceptance criteria, a source table, and known unknowns; update the same document with each piece of verified evidence instead of waiting until broad research is complete." : "Before the first external browse, search, or research action, call upsert_document with a stable key. Create a checkpoint skeleton containing the acceptance criteria, a source table, and known unknowns; update the same document with each piece of verified evidence instead of waiting until broad research is complete. Immediately after upsert_document, call update_parent with status: in_progress and a concrete next action; complete both control-plane writes before the first external browse, search, or research action." : continueTaskEnabled ? "Before the first external browse, search, or research action, read the existing stable-key document. Preserve all still-valid verified rows, source URLs, conclusions, and known unknowns; do not replace a populated document with a blank skeleton or less-informative fallback. Only when the document does not exist may you create a checkpoint skeleton. Update the same document with each piece of verified evidence." : "Before the first external browse, search, or research action, read the existing stable-key document. Preserve all still-valid verified rows, source URLs, conclusions, and known unknowns; do not replace a populated document with a blank skeleton or less-informative fallback. Only when the document does not exist may you create a checkpoint skeleton. Then call update_parent with status: in_progress and a concrete next action before the first external browse, search, or research action. Update the same document with each piece of verified evidence." : "";
31602
+ const documentProgress = completionDeliverable === "document_or_artifact" && !delegatedDelivery ? manifestRefreshOnly ? "The current deliverable content already exists and this run is limited to refreshing stale immutable Manifest refs. Do not create or revise a document unless a fresh Delivery readiness read proves a content or acceptance gap beyond stale refs." : "Research and inspect evidence as needed. Persist useful findings to a stable-key Issue document before ending or yielding this run; on continuation, preserve existing verified content and add to it rather than replacing it with a blank draft." : "";
31552
31603
  const completionContract = !suppressOrdinaryCompletionContract && completionRole && completionDeliverable ? [
31553
- workDisposition.mode === "required" ? "Before the first business mutation, ensure the current required work disposition is recorded. Read-only governed checks may precede it. If no current valid receipt exists, call runtime_action_describe for record_work_disposition and persist exactly one truthful disposition before upsert_document, update_parent, add_comment, create_interaction, publish_delivery_manifest, or any other business mutation. Before ending this run, persist durable progress through Runtime Actions; browser and tool history alone are not durable progress." : "Before ending this run, persist durable progress through Runtime Actions and record one explicit task disposition. Browser and tool history alone are not durable progress.",
31554
- firstDocumentCheckpoint,
31604
+ workDisposition.mode === "required" ? "A required work disposition must be recorded before business mutations. Read-only checks and research may proceed. Before ending this run, persist durable progress; browser and tool history alone are not durable progress." : "Before ending this run, persist durable progress through Runtime Actions and record one explicit task disposition. Browser and tool history alone are not durable progress.",
31605
+ documentProgress,
31555
31606
  continueTaskEnabled ? "Treat one Run as one bounded, durable checkpoint. Once that checkpoint is persisted and another independent research, build, or revision phase remains, call continue_task immediately with a concrete nextAction and stable idempotencyKey instead of keeping the current Run open, then end the run. If the nextAction depends on files created in this run, include their exact workspace-relative POSIX paths in checkpointPaths; only those files are integrity-checked and carried into the successor workspace. A run-local file omitted from checkpointPaths is not durable continuation state. Do not split an unfinished atomic mutation or claim progress that is not durable. For a future time recheck use schedule_monitor; for an external person or system action use upsert_external_wait. These are mutually exclusive final live paths. Do not call update_parent with status: in_progress." : "If work remains in an ordinary productive run, call update_parent with status: in_progress and a concrete next action so bounded continuation recovery can preserve a live path. Status: todo does not queue a normal continuation from an ordinary productive run. Only a server-issued successful-run handoff recovery may use status: todo, and only according to its exact Recovery Instruction. Otherwise use a supported terminal or waiting disposition."
31556
31607
  ].filter(Boolean).join(" ") : "";
31557
31608
  const businessOutcomeOwnershipContract = businessOutcome.mode === "required" ? runContract === "rework" ? "Business Outcome acceptance remains Server-owned. The producer may use status done only as the configured changes-requested resubmission described in Producer Execution Handoff; it is not acceptance or a terminal completion claim." : evidenceAutoAcceptance ? [
@@ -31625,30 +31676,11 @@ function runtimeDecompositionRequirementText(context) {
31625
31676
  }
31626
31677
  return [
31627
31678
  "This issue has a server-enforced typed decomposition requirement.",
31628
- "Create the complete real direct child graph before doing any substantial source work.",
31629
- "Before browsing, searching, commenting, or doing any source work, call runtime_action_describe for record_work_disposition with dispositionKind create_children and for every child action type you need.",
31630
- "Persist one immutable runtime_action_plan whose first action is record_work_disposition kind create_children and whose remaining actions are exactly the complete child graph referenced by that disposition. Do not append update_parent, add_comment, upsert_document, or any other action after the child graph.",
31631
- "For each record_work_disposition structure child, copy scopeSummary exactly into the bound create_child_issue description. The Server compares those normalized strings and rejects a missing or different description with work_disposition_child_scope_mismatch; delegation.objective does not satisfy that binding. Also copy ownerAgentId exactly into the bound create_child_issue assigneeAgentId; mentioning an owner in delegation prose or title does not assign the child, and a missing or different explicit assignee is rejected with work_disposition_child_owner_binding_mismatch.",
31632
- "Execute that exact plan with runtime_action_commit.",
31633
- "Once runtime_action_commit succeeds, the committed required child graph is this parent run's durable delegated live disposition.",
31634
- "After runtime_action_commit succeeds, yield and end the parent run immediately. Do not browse, search, research, or execute any delegated child acceptance scope, and do not poll child runs. Child assignment runs are the sole execution path for delegated child scope.",
31635
- "Each executable child must have an owner, dependencies where needed, and acceptance criteria. Do not create probe or test children.",
31636
- "Preserve every parent safety and approval boundary in each child title, description, and acceptance criteria. If the parent prohibits registration, payment, booking, or external contact without later explicit authorization, create preparation or approval only children and do not assign the prohibited action.",
31679
+ "Inspect the task and source evidence needed to scope real child outcomes. Before business mutations, create the complete required child graph with owners, dependencies, acceptance criteria, and inherited safety and approval boundaries. Use the action descriptions for exact plan bindings and submission. Once committed, the child graph is this parent's durable delegation; end the parent run and let assigned children execute their scopes.",
31637
31680
  `Requirement source: ${sourceType}:${sourceId}@${sourceRevision}`
31638
31681
  ].join("\n");
31639
31682
  }
31640
- function deliveryReadCallText(input) {
31641
- const args = { issueId: input.issueId };
31642
- const directToolName = managedDirectToolName(input, "mirrorx.read_issue_delivery");
31643
- if (directToolName) {
31644
- return `call \`${directToolName}\` with these exact object arguments: ${JSON.stringify(args)}`;
31645
- }
31646
- if (input.managedMcpToolMode === "direct_typed") {
31647
- return "the Delivery readiness read is unavailable because mirrorx_read_issue_delivery is absent from the attested direct tool catalog; do not guess a tool name";
31648
- }
31649
- return `call mirrorx.read_issue_delivery with these exact arguments: ${JSON.stringify(args)}`;
31650
- }
31651
- function runtimeDeliveryReadinessText(context, input) {
31683
+ function runtimeDeliveryReadinessText(context) {
31652
31684
  const readiness = asRecord(context.paperclipDeliveryReadiness);
31653
31685
  if (readString(readiness.mode) !== "required") return "";
31654
31686
  const currentManifest = asRecord(readiness.currentManifest);
@@ -31696,12 +31728,10 @@ function runtimeDeliveryReadinessText(context, input) {
31696
31728
  "The Server computed this authoritative Delivery snapshot immediately before dispatching the current run.",
31697
31729
  `Expected requirement revision: ${requirementRevision ?? "missing"}`,
31698
31730
  `Expected current Manifest revision: ${currentRevision === null ? "null" : currentRevision}`,
31699
- `Immediately before publish_delivery_manifest, ${deliveryReadCallText(input)}. Copy expectedRequirementRevision from result.content.readiness.requirementRevision and expectedRevision from result.content.readiness.currentManifest.revision (or null when currentManifest is null); never copy them from an interaction, comment, continuation summary, or prior failed action.`,
31700
- "If a publication conflicts, or any action changes the Task, a document, or the Manifest, read Delivery readiness again before retrying. Preserve the conflict and current values; do not guess CAS inputs.",
31731
+ "Use the current Delivery readiness when preparing a Manifest; the publication action describes how to refresh its exact revision fields.",
31701
31732
  ...manifestRefreshOnly ? [
31702
31733
  "This is a manifest-refresh-only continuation: the requirement and coverage are current, while immutable deliverable refs are stale.",
31703
- "Do not call upsert_document or upsert_document_revision merely to refresh the Manifest. Use mirrorx_read_issue to map each stale documentId to its key, then mirrorx_read_issue_document to obtain the exact latest immutable revision and publish one new ready Manifest against the fresh Delivery readiness CAS values.",
31704
- "Do not create an interaction asking the Board to refresh the Manifest. The executor owns Manifest publication; the Board independently reviews only after a ready Manifest and clean Outcome exist."
31734
+ "Refresh the stale immutable deliverable references from current governed reads; the executor owns Manifest publication."
31705
31735
  ] : [],
31706
31736
  "```json",
31707
31737
  jsonText(snapshot),
@@ -31758,7 +31788,7 @@ function producerExecutionHandoffSection(input, runContract, stages) {
31758
31788
  const content = [
31759
31789
  `Remaining configured execution stages: ${JSON.stringify(stages)}`,
31760
31790
  "You are the producer. Finish and self-check the deliverable requirements; independent reviewer approval is a subsequent Server-owned stage, not missing producer work. Do not fabricate that approval or wait for it inside this run.",
31761
- runContract === "rework" ? "This task was returned for changes. Address the review findings and publish current governed delivery evidence. Resubmit through runtime_action_describe and runtime_action_submit for update_parent with status done and a non-empty handoff comment. This re-enters the configured stage; it does not declare Business Outcome acceptance. Do not use executionDecision as the producer or wait for the first-delivery automatic handoff." : "Ensure the exact governed Delivery Manifest is ready when required (for delegated delivery, preserve the final-child Manifest and package review; do not publish a duplicate root package), record the final production evidence with update_parent status in_progress, and end the run successfully. The runtime_action_in_progress_server_owned receipt is the expected handoff receipt, not permission to retry with done.",
31791
+ runContract === "rework" ? "This task was returned for changes. Address the review findings, publish current governed delivery evidence, and resubmit through the available governed action. This re-enters the configured stage; it does not declare Business Outcome acceptance. The action description gives the exact resubmission fields." : "Ensure the exact governed Delivery Manifest is ready when required (for delegated delivery, preserve the final-child Manifest and package review; do not publish a duplicate root package), record the final production evidence with update_parent status in_progress, and end the run successfully. The runtime_action_in_progress_server_owned receipt is the expected handoff receipt, not permission to retry with done.",
31762
31792
  "The Server verifies terminal Outcome evidence, Manifest readiness, and blocking work before starting the configured stages in order. Agent participants receive a fresh independent run (even if the same employee produced the work); user participants follow the configured human stage. Business Outcome acceptance remains a later gate.",
31763
31793
  "Do not create a request_confirmation / review_document_revision interaction as a substitute for these configured final review or approval stages. Preserve genuine intermediate questions, user decisions, and authorization needs; an existing pending interaction must still follow its authoritative continuation policy.",
31764
31794
  "Report delivery submitted and configured review pending until a Server receipt proves otherwise; do not claim the task is accepted or done."
@@ -31793,7 +31823,7 @@ function executionReviewContractSection(context, input) {
31793
31823
  "You are the active Approver in a fresh execution run. Do not execute or continue the producer's task.",
31794
31824
  "Review the current Task, its Acceptance criteria, the completed reviewer findings, and the exact governed delivery references before deciding.",
31795
31825
  "Approve only when the reviewed result is suitable for final acceptance. Otherwise request concrete, scoped changes; the workflow routes them to the stored return assignee.",
31796
- "Record the decision only through runtime_action_describe and runtime_action_submit for update_parent, with executionDecision approved or changes_requested and a non-empty comment. Do not use status and do not embed the decision in an action plan."
31826
+ "Record the decision through the available governed action; its description gives the exact fields and submission mode."
31797
31827
  ].join("\n");
31798
31828
  return {
31799
31829
  sourceRef: `issue:${input.issueId ?? "unknown"}:execution-approval:${readString(executionStage.stageId) ?? "unknown"}`,
@@ -31862,7 +31892,6 @@ function executionReviewContractSection(context, input) {
31862
31892
  "The Server-owned review target below is authoritative. Review is valid only while Delivery readiness is ready and the exact Manifest identity remains current.",
31863
31893
  "Inspect every listed refId and evaluate every listed acceptanceRef. Submit reviewEvidence with the decision; the Server rejects missing refs, missing Acceptance findings, mismatched Manifest identity, or a Manifest that changed before commit.",
31864
31894
  "For approval, every Acceptance finding must be passed. For changes_requested, include at least one failed finding with a concrete explanation tied to its acceptanceRef and inspected artifact.",
31865
- 'Use this exact reviewEvidence shape in the Issue update that records the decision: {"schemaVersion":"mirrorx.execution-review-evidence.v1","manifest":<copy exact target manifest>,"inspectedRefIds":<every target refId>,"acceptanceFindings":[{"acceptanceRef":<target acceptanceRef>,"outcome":"passed"|"failed","finding":<concrete observed evidence>}]}. Copy manifest and refIds exactly from the target; every passed or failed finding must state what was actually observed in the inspected artifact.',
31866
31895
  "Authoritative review target:",
31867
31896
  "```json",
31868
31897
  jsonText(reviewTarget),
@@ -31870,7 +31899,7 @@ function executionReviewContractSection(context, input) {
31870
31899
  ] : [
31871
31900
  "No Server-managed Delivery Manifest is required for this Task. Use only governed exact work-product, document, artifact, or commit references, and identify each inspected reference in the decision comment."
31872
31901
  ],
31873
- "Record the decision only through runtime_action_describe and runtime_action_submit for update_parent, with executionDecision approved or changes_requested and a non-empty comment. Include reviewEvidence in that same update_parent action whenever the authoritative target above is present. Do not use status for an execution-stage decision.",
31902
+ "Record the decision through the available governed action; its description gives the exact evidence fields and submission mode.",
31874
31903
  "Approve only when every Acceptance criterion is satisfied by inspected deliverables. Otherwise request changes with concrete, scoped findings. The workflow routes requested changes to the stored return assignee."
31875
31904
  ].filter(Boolean).join("\n");
31876
31905
  return {
@@ -32382,7 +32411,7 @@ ${resolvedDependencies.details.content}` : resolvedDependencies.details.content
32382
32411
  content: resolvedDependencyContent,
32383
32412
  mandatoryContent: resolvedDependencies.required.content
32384
32413
  } : null;
32385
- const deliveryReadinessContent = runtimeDeliveryReadinessText(context, input);
32414
+ const deliveryReadinessContent = runtimeDeliveryReadinessText(context);
32386
32415
  const executionReviewContract = ["reviewer", "approver", "invalid_execution_stage"].includes(runContract) ? executionReviewContractSection(context, input) : null;
32387
32416
  const producerExecutionHandoff = producerExecutionHandoffSection(input, runContract, pendingExecutionStages);
32388
32417
  const optionalTaskWikiContext = optionalTaskWikiContextSection(context);
@@ -32424,7 +32453,7 @@ ${resolvedDependencies.details.content}` : resolvedDependencies.details.content
32424
32453
  ...!hasTask && readString(input.issueLine) && options.separateRuntimeRules === true ? [{ name: "issue_line", title: "", priority: 100, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: `- issue: ${input.issueLine}` }] : [],
32425
32454
  { name: "runtime_rules", title: "", priority: 100, sourceRef: `command:${input.commandId}`, content: fixedRules(input, runContract) },
32426
32455
  { name: "current_run_context", title: "", priority: 100, sourceRef: `command:${input.commandId}`, content: currentRunContext(input, !hasTask && options.separateRuntimeRules !== true) },
32427
- { name: "runtime_authorization", title: "Runtime Action Contract", priority: 98, sourceRef: `run:${input.runId ?? "unknown"}`, content: runtimeAuthorizationText(context, mode, {
32456
+ { name: "runtime_authorization", title: "Runtime Action Contract", priority: 98, sourceRef: `run:${input.runId ?? "unknown"}`, content: runtimeAuthorizationText(context, {
32428
32457
  replayAlreadyInTask: includeTask && taskText.includes(EXACT_ORGANIZATION_INTENT_REPLAY_MARKER),
32429
32458
  runContract,
32430
32459
  pendingExecutionStages,
@@ -32484,7 +32513,7 @@ ${resolvedDependencies.details.content}` : resolvedDependencies.details.content
32484
32513
  }
32485
32514
 
32486
32515
  // src/amaster-runtime-daemon/agent-instruction-delivery.mjs
32487
- import { createHash as createHash13, randomBytes } from "node:crypto";
32516
+ import { createHash as createHash14, randomBytes } from "node:crypto";
32488
32517
  import { existsSync as existsSync10, lstatSync as lstatSync9, mkdirSync as mkdirSync10, readFileSync as readFileSync11, readdirSync as readdirSync8, realpathSync as realpathSync9, renameSync as renameSync8, rmSync as rmSync8, writeFileSync as writeFileSync11 } from "node:fs";
32489
32518
  import { dirname as dirname9, isAbsolute as isAbsolute6, join as join15, relative as relative4, resolve as resolve9 } from "node:path";
32490
32519
 
@@ -32696,7 +32725,7 @@ function inspectExternalWorkspaceProjectInstructions(sourceWorkspacePath, option
32696
32725
  path: relativePath,
32697
32726
  scope: relativePath.includes("/") ? relativePath.slice(0, relativePath.lastIndexOf("/")) : ".",
32698
32727
  bytes: content.byteLength,
32699
- sha256: createHash13("sha256").update(content).digest("hex")
32728
+ sha256: createHash14("sha256").update(content).digest("hex")
32700
32729
  });
32701
32730
  }
32702
32731
  }
@@ -32707,9 +32736,9 @@ function inspectExternalWorkspaceProjectInstructions(sourceWorkspacePath, option
32707
32736
  status: sources.length === 0 ? "absent_verified" : "present_verified",
32708
32737
  visitedDirectories,
32709
32738
  sources,
32710
- topologySha256: createHash13("sha256").update(JSON.stringify(sources)).digest("hex"),
32739
+ topologySha256: createHash14("sha256").update(JSON.stringify(sources)).digest("hex"),
32711
32740
  ignoredManagedExecutionDirectoryCount: ignoredManagedExecutionDirectories.length,
32712
- ignoredManagedExecutionDirectoriesSha256: createHash13("sha256").update(JSON.stringify(ignoredManagedExecutionDirectories)).digest("hex")
32741
+ ignoredManagedExecutionDirectoriesSha256: createHash14("sha256").update(JSON.stringify(ignoredManagedExecutionDirectories)).digest("hex")
32713
32742
  };
32714
32743
  }
32715
32744
  function composeProjectedInstruction(sources, platformInstructions) {
@@ -32798,7 +32827,7 @@ function projectExternalWorkspaceProjectInstructions(sourceWorkspacePath, execut
32798
32827
  );
32799
32828
  }
32800
32829
  const sourceContent = readFileSync11(sourcePath, "utf8");
32801
- const sourceSha256 = createHash13("sha256").update(sourceContent, "utf8").digest("hex");
32830
+ const sourceSha256 = createHash14("sha256").update(sourceContent, "utf8").digest("hex");
32802
32831
  if (sourceSha256 !== source.sha256) {
32803
32832
  throw instructionTopologyError(
32804
32833
  "workspace_project_instruction_source_changed",
@@ -32843,7 +32872,7 @@ function projectExternalWorkspaceProjectInstructions(sourceWorkspacePath, execut
32843
32872
  }
32844
32873
  modelFacingFile = "AGENTS.md";
32845
32874
  modelFacingBytes = Buffer.byteLength(projectedContent, "utf8");
32846
- modelFacingSha256 = createHash13("sha256").update(projectedContent, "utf8").digest("hex");
32875
+ modelFacingSha256 = createHash14("sha256").update(projectedContent, "utf8").digest("hex");
32847
32876
  }
32848
32877
  const receiptSources = projected.map(({ content: _content, ...entry }) => entry);
32849
32878
  return {
@@ -32856,7 +32885,7 @@ function projectExternalWorkspaceProjectInstructions(sourceWorkspacePath, execut
32856
32885
  modelFacingFile,
32857
32886
  modelFacingBytes,
32858
32887
  modelFacingSha256,
32859
- projectionSha256: createHash13("sha256").update(JSON.stringify(receiptSources)).digest("hex")
32888
+ projectionSha256: createHash14("sha256").update(JSON.stringify(receiptSources)).digest("hex")
32860
32889
  };
32861
32890
  }
32862
32891
  function resolveAgentInstructionDelivery(executorKind, options = {}) {
@@ -33361,6 +33390,23 @@ var AUTHORITY_FIELDS = /* @__PURE__ */ new Set([
33361
33390
  "bindingId",
33362
33391
  "browserLeaseId"
33363
33392
  ]);
33393
+ var AUTHORITY_V2_FIELDS = /* @__PURE__ */ new Set([
33394
+ "version",
33395
+ "companyId",
33396
+ "issueId",
33397
+ "runId",
33398
+ "commandId",
33399
+ "grantKind",
33400
+ "grantId",
33401
+ "grantRevision",
33402
+ "commandAuthId",
33403
+ "interactionId",
33404
+ "credentialKey",
33405
+ "credentialVersion",
33406
+ "credentialRole",
33407
+ "targetOrigin",
33408
+ "authenticationOrigin"
33409
+ ]);
33364
33410
  function encodeBrowserCredentialFrame(type, payload) {
33365
33411
  if (!/^[ACREV]$/u.test(type) || !Buffer.isBuffer(payload)) throw new Error("browser_credential_frame_invalid");
33366
33412
  if (payload.length > MAX_BYTES3) throw new Error("browser_credential_frame_too_large");
@@ -33403,7 +33449,13 @@ function semanticMatches(role, semantic) {
33403
33449
  }
33404
33450
  function browserCredentialRefForRequest(command, request) {
33405
33451
  const refs = Array.isArray(command?.payload?.browserCredentialRefs) ? command.payload.browserCredentialRefs : [];
33406
- const matches = refs.filter((ref2) => ref2 && typeof ref2 === "object" && !Array.isArray(ref2) && !Object.keys(ref2).some((key) => !AUTHORITY_FIELDS.has(key)) && ref2.version === 1 && ref2.commandId === command?.commandId && ref2.runId === request.runId && ref2.commandId === request.commandId && ref2.interactionId === request.interactionId && ref2.credentialKey === request.credentialKey && ref2.credentialVersion === request.credentialVersion && ref2.credentialRole === request.credentialRole && ref2.targetOrigin === request.targetOrigin && ref2.authenticationOrigin === request.authenticationOrigin && ref2.bindingId === request.bindingId && [ref2.companyId, ref2.issueId, ref2.runId, ref2.commandId, ref2.interactionId, ref2.bindingId].every((id) => typeof id === "string" && UUID.test(id)) && typeof ref2.credentialKey === "string" && ref2.credentialKey.length > 0 && Number.isSafeInteger(ref2.credentialVersion) && ref2.credentialVersion > 0 && ["username", "password"].includes(ref2.credentialRole) && exactOrigin(ref2.targetOrigin) === ref2.targetOrigin && exactOrigin(ref2.authenticationOrigin) === ref2.authenticationOrigin && typeof ref2.browserLeaseId === "string" && /^browser-credential-(?:auth-write|agent-read)-[0-9a-f-]{36}$/u.test(ref2.browserLeaseId));
33452
+ const matches = refs.filter((ref2) => ref2 && typeof ref2 === "object" && !Array.isArray(ref2) && [1, 2].includes(ref2.version) && ref2.version === request.version && !Object.keys(ref2).some((key) => !(ref2.version === 1 ? AUTHORITY_FIELDS : AUTHORITY_V2_FIELDS).has(key)) && ref2.commandId === command?.commandId && ref2.runId === request.runId && ref2.commandId === request.commandId && (ref2.version === 1 ? ref2.interactionId === request.interactionId && ref2.bindingId === request.bindingId : ref2.grantKind === request.grantKind && ref2.grantId === request.grantId && ref2.grantRevision === request.grantRevision && ref2.commandAuthId === request.commandAuthId && ref2.interactionId === request.interactionId) && ref2.credentialKey === request.credentialKey && ref2.credentialVersion === request.credentialVersion && ref2.credentialRole === request.credentialRole && ref2.targetOrigin === request.targetOrigin && ref2.authenticationOrigin === request.authenticationOrigin && [
33453
+ ref2.companyId,
33454
+ ref2.issueId,
33455
+ ref2.runId,
33456
+ ref2.commandId,
33457
+ ...ref2.version === 1 ? [ref2.interactionId, ref2.bindingId] : [ref2.grantId, ref2.commandAuthId]
33458
+ ].every((id) => typeof id === "string" && UUID.test(id)) && (ref2.version === 1 || ["interaction", "stored_grant"].includes(ref2.grantKind) && Number.isSafeInteger(ref2.grantRevision) && ref2.grantRevision > 0 && ref2.grantKind === "interaction" === (typeof ref2.interactionId === "string" && UUID.test(ref2.interactionId))) && typeof ref2.credentialKey === "string" && ref2.credentialKey.length > 0 && Number.isSafeInteger(ref2.credentialVersion) && ref2.credentialVersion > 0 && ["username", "password"].includes(ref2.credentialRole) && exactOrigin(ref2.targetOrigin) === ref2.targetOrigin && exactOrigin(ref2.authenticationOrigin) === ref2.authenticationOrigin && (ref2.version === 2 || typeof ref2.browserLeaseId === "string" && /^browser-credential-(?:auth-write|agent-read)-[0-9a-f-]{36}$/u.test(ref2.browserLeaseId)));
33407
33459
  if (matches.length !== 1 || !semanticMatches(matches[0].credentialRole, request.controlSemantic)) {
33408
33460
  throw new Error("browser_credential_semantic_mismatch");
33409
33461
  }
@@ -33411,7 +33463,23 @@ function browserCredentialRefForRequest(command, request) {
33411
33463
  }
33412
33464
  function exactRequest(value, challenge) {
33413
33465
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
33414
- const allowed = /* @__PURE__ */ new Set([
33466
+ const allowed = new Set(value.version === 2 ? [
33467
+ "version",
33468
+ "challenge",
33469
+ "grantKind",
33470
+ "grantId",
33471
+ "grantRevision",
33472
+ "commandAuthId",
33473
+ "interactionId",
33474
+ "credentialKey",
33475
+ "credentialVersion",
33476
+ "credentialRole",
33477
+ "runId",
33478
+ "commandId",
33479
+ "targetOrigin",
33480
+ "authenticationOrigin",
33481
+ "controlSemantic"
33482
+ ] : [
33415
33483
  "version",
33416
33484
  "challenge",
33417
33485
  "interactionId",
@@ -33425,11 +33493,16 @@ function exactRequest(value, challenge) {
33425
33493
  "authenticationOrigin",
33426
33494
  "controlSemantic"
33427
33495
  ]);
33428
- if (Object.keys(value).some((key) => !allowed.has(key)) || value.version !== 1 || typeof value.challenge !== "string") return null;
33496
+ if (Object.keys(value).some((key) => !allowed.has(key)) || ![1, 2].includes(value.version) || typeof value.challenge !== "string") return null;
33429
33497
  const expected = Buffer.from(challenge, "utf8");
33430
33498
  const actual = Buffer.from(value.challenge, "utf8");
33431
33499
  if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) return null;
33432
- if (![value.interactionId, value.runId, value.commandId, value.bindingId].every((id) => typeof id === "string" && UUID.test(id))) return null;
33500
+ if (![
33501
+ value.runId,
33502
+ value.commandId,
33503
+ ...value.version === 1 ? [value.interactionId, value.bindingId] : [value.grantId, value.commandAuthId]
33504
+ ].every((id) => typeof id === "string" && UUID.test(id))) return null;
33505
+ if (value.version === 2 && (!["interaction", "stored_grant"].includes(value.grantKind) || !Number.isSafeInteger(value.grantRevision) || value.grantRevision < 1 || value.grantKind === "interaction" !== (typeof value.interactionId === "string" && UUID.test(value.interactionId)))) return null;
33433
33506
  const targetOrigin = exactOrigin(value.targetOrigin);
33434
33507
  const authenticationOrigin = exactOrigin(value.authenticationOrigin);
33435
33508
  const semantic = typeof value.controlSemantic === "string" ? value.controlSemantic.trim().toLowerCase() : "";
@@ -33438,8 +33511,9 @@ function exactRequest(value, challenge) {
33438
33511
  if (!["username", "password"].includes(value.credentialRole) || !semanticMatches(value.credentialRole, semantic)) return null;
33439
33512
  return { ...value, credentialKey: value.credentialKey.trim(), targetOrigin, authenticationOrigin, controlSemantic: semantic };
33440
33513
  }
33441
- function createBrowserCredentialChannel({ consume, onFailure }) {
33514
+ function createBrowserCredentialChannel({ consume, onFailure, authorizedRefs = [] }) {
33442
33515
  if (typeof consume !== "function") throw new Error("browser_credential_consumer_required");
33516
+ if (!Array.isArray(authorizedRefs)) throw new Error("browser_credential_authority_invalid");
33443
33517
  const challenge = randomBytes2(32).toString("base64url");
33444
33518
  const consumedRefs = /* @__PURE__ */ new Set();
33445
33519
  const consumedRequests = [];
@@ -33474,7 +33548,21 @@ function createBrowserCredentialChannel({ consume, onFailure }) {
33474
33548
  return;
33475
33549
  }
33476
33550
  if (!receipt || typeof receipt !== "object" || Array.isArray(receipt)) return;
33477
- const allowed = /* @__PURE__ */ new Set([
33551
+ const allowed = new Set(receipt.version === 2 ? [
33552
+ "version",
33553
+ "status",
33554
+ "runId",
33555
+ "commandId",
33556
+ "grantKind",
33557
+ "grantId",
33558
+ "grantRevision",
33559
+ "commandAuthId",
33560
+ "interactionId",
33561
+ "origin",
33562
+ "pageGeneration",
33563
+ "contextRotated",
33564
+ "credentialRoles"
33565
+ ] : [
33478
33566
  "version",
33479
33567
  "status",
33480
33568
  "runId",
@@ -33487,7 +33575,25 @@ function createBrowserCredentialChannel({ consume, onFailure }) {
33487
33575
  "credentialRoles"
33488
33576
  ]);
33489
33577
  if (Object.keys(receipt).some((key) => !allowed.has(key))) return;
33490
- if (receipt.version !== 1 || receipt.status !== "authenticated" || receipt.contextRotated !== true) return;
33578
+ if (![1, 2].includes(receipt.version)) return;
33579
+ if (receipt.version === 2) {
33580
+ if (!["authenticated", "session_authenticated"].includes(receipt.status) || !["interaction", "stored_grant"].includes(receipt.grantKind) || typeof receipt.pageGeneration !== "string" || !UUID.test(receipt.pageGeneration) || !Number.isSafeInteger(receipt.grantRevision) || receipt.grantRevision < 1 || ![receipt.grantId, receipt.commandAuthId, receipt.runId, receipt.commandId].every((id) => typeof id === "string" && UUID.test(id)) || receipt.grantKind === "interaction" !== (typeof receipt.interactionId === "string" && UUID.test(receipt.interactionId))) return;
33581
+ const matches = authorizedRefs.filter((ref2) => ref2?.version === 2 && ref2.runId === receipt.runId && ref2.commandId === receipt.commandId && ref2.grantKind === receipt.grantKind && ref2.grantId === receipt.grantId && ref2.grantRevision === receipt.grantRevision && ref2.commandAuthId === receipt.commandAuthId && ref2.interactionId === receipt.interactionId && ref2.authenticationOrigin === receipt.origin);
33582
+ if (!matches.some((ref2) => ref2.credentialRole === "password")) return;
33583
+ if (receipt.status === "session_authenticated") {
33584
+ if (receipt.contextRotated !== false || !Array.isArray(receipt.credentialRoles) || receipt.credentialRoles.length !== 0 || consumedRequests.length !== 0) return;
33585
+ if (authReceipts.length === 0) authReceipts.push(Object.freeze({ ...receipt, credentialRoles: [] }));
33586
+ return;
33587
+ }
33588
+ if (receipt.contextRotated !== true) return;
33589
+ const consumed = consumedRequests.filter((request) => request.version === 2 && request.runId === receipt.runId && request.commandId === receipt.commandId && request.grantId === receipt.grantId && request.grantRevision === receipt.grantRevision && request.commandAuthId === receipt.commandAuthId && request.authenticationOrigin === receipt.origin);
33590
+ if (!consumed.some((request) => request.credentialRole === "password")) return;
33591
+ const roles = new Set(consumed.map((request) => request.credentialRole));
33592
+ if (!Array.isArray(receipt.credentialRoles) || !receipt.credentialRoles.includes("password") || receipt.credentialRoles.some((role) => !roles.has(role))) return;
33593
+ if (authReceipts.length === 0) authReceipts.push(Object.freeze({ ...receipt, credentialRoles: [...new Set(receipt.credentialRoles)].sort() }));
33594
+ return;
33595
+ }
33596
+ if (receipt.status !== "authenticated" || receipt.contextRotated !== true) return;
33491
33597
  if (typeof receipt.pageGeneration !== "string" || !UUID.test(receipt.pageGeneration)) return;
33492
33598
  if (!Array.isArray(receipt.credentialRoles) || receipt.credentialRoles.length < 1 || receipt.credentialRoles.some((role) => !["username", "password"].includes(role))) return;
33493
33599
  const matching = consumedRequests.filter((request) => request.runId === receipt.runId && request.commandId === receipt.commandId && request.interactionId === receipt.interactionId && request.bindingId === receipt.bindingId && request.authenticationOrigin === receipt.origin);
@@ -33580,22 +33686,11 @@ function createBrowserCredentialChannel({ consume, onFailure }) {
33580
33686
 
33581
33687
  // src/amaster-runtime-daemon/browser-credential-readiness.mjs
33582
33688
  import { existsSync as existsSync12, lstatSync as lstatSync10, readFileSync as readFileSync13, readdirSync as readdirSync9, statSync as statSync6 } from "node:fs";
33583
- import { createHash as createHash14 } from "node:crypto";
33689
+ import { createHash as createHash15 } from "node:crypto";
33584
33690
  import { homedir as homedir4 } from "node:os";
33585
33691
  import { dirname as dirname11, isAbsolute as isAbsolute7, join as join17, relative as relative5, resolve as resolve11 } from "node:path";
33586
- var CREDENTIAL_BROWSER_TCB = Object.freeze({
33587
- package: "chrome-devtools-mcp",
33588
- version: "1.6.0",
33589
- mode: "puppeteer_pipe",
33590
- buildTreeSha256: "5bd07cd7ea92141441db12d1e84c4829dd4e2a45ea77f719878be9f4a42925d7"
33591
- });
33592
- var CREDENTIAL_BROWSER_PACKAGE_FILES = Object.freeze({
33593
- "dist/config.js": "01da4c975a050dc1860a5115b244020be741100bff3c426f601642a6f757f370",
33594
- "dist/index.js": "9cf0dac303552cbfb7f87c9499dbd8c1d88565e0145825ca222424e1123b70e2"
33595
- });
33596
- var CREDENTIAL_BROWSER_DIST_TREE_SHA256 = "fcf1abd578c519b7ab7cec921d1abe36992aab84b4f713e0b89587e6254145a9";
33597
- var CREDENTIAL_AUTH_EXTENSION_SHA256 = "48f36d0c1c5c46f07bd447c2bc2000595d17f109ce6963865870d88f42c60598";
33598
- var CREDENTIAL_BROWSER_PACKAGE_VERSION = "0.1.2-beta.80";
33692
+ var TCB_DIGEST = /^[a-f0-9]{64}$/u;
33693
+ var TCB_INTEGRITY = /^sha512-[A-Za-z0-9+/]+={0,2}$/u;
33599
33694
  var IMAGE_PI_HOME = "/opt/pi-cli-runtime/.pi";
33600
33695
  var BROWSER_AUTH_IMAGE_HOME = IMAGE_PI_HOME;
33601
33696
  var IMAGE_AUTH_EXTENSION_PATH = join17(IMAGE_PI_HOME, "extensions", "browser-credential-auth.mjs");
@@ -33608,8 +33703,9 @@ function inspectBrowserCredentialAuthReadiness(env = process.env, expected = {},
33608
33703
  const home = String(env.PI_CODING_AGENT_DIR ?? env.PI_AGENT_HOME ?? join17(homedir4(), ".pi", "agent")).trim();
33609
33704
  const packageHome = expected.packageHome ?? IMAGE_PI_HOME;
33610
33705
  const extensionPath = expected.authExtensionPath ?? IMAGE_AUTH_EXTENSION_PATH;
33706
+ const tcbManifestPath = expected.tcbManifestPath ?? join17(packageHome, "browser-credential-tcb.json");
33611
33707
  const requireImageOwnership = options.requireImageOwnership !== false;
33612
- const cacheKey = JSON.stringify([home, packageHome, extensionPath, requireImageOwnership]);
33708
+ const cacheKey = JSON.stringify([home, packageHome, extensionPath, tcbManifestPath, requireImageOwnership]);
33613
33709
  const now = Date.now();
33614
33710
  const cached = readinessCache.get(cacheKey);
33615
33711
  if (!options.fresh && cached && cached.expiresAt > now) return { ...cached.readiness };
@@ -33617,16 +33713,12 @@ function inspectBrowserCredentialAuthReadiness(env = process.env, expected = {},
33617
33713
  join17(packageHome, "npm", "node_modules", "@amaster.ai", "pi-browser-use", "package.json"),
33618
33714
  join17(packageHome, "node_modules", "@amaster.ai", "pi-browser-use", "package.json")
33619
33715
  ];
33620
- const packageAttestation = candidates.map((manifestPath) => attestedPackageManifest(manifestPath, {
33621
- browserTcb: expected.browserTcb ?? CREDENTIAL_BROWSER_TCB,
33622
- packageFiles: expected.packageFiles ?? CREDENTIAL_BROWSER_PACKAGE_FILES,
33623
- packageDistTreeSha256: expected.packageDistTreeSha256 ?? CREDENTIAL_BROWSER_DIST_TREE_SHA256,
33624
- authExtensionSha256: expected.authExtensionSha256 ?? CREDENTIAL_AUTH_EXTENSION_SHA256
33625
- }, requireImageOwnership)).find(Boolean) ?? null;
33716
+ const tcb = imageTcbManifest(tcbManifestPath, requireImageOwnership);
33717
+ const packageAttestation = tcb ? candidates.map((manifestPath) => attestedPackageManifest(manifestPath, tcb, requireImageOwnership)).find(Boolean) ?? null : null;
33626
33718
  const packageAttested = Boolean(packageAttestation);
33627
33719
  const authExtensionAttested = attestedAuthExtension(
33628
33720
  extensionPath,
33629
- packageAttestation ? expected.authExtensionSha256 ?? CREDENTIAL_AUTH_EXTENSION_SHA256 : null,
33721
+ packageAttestation ? tcb.authExtension.sha256 : null,
33630
33722
  requireImageOwnership
33631
33723
  );
33632
33724
  let runtimeExtensionsAttested = false;
@@ -33717,7 +33809,7 @@ function attestedAuthExtension(extensionPath, expectedSha256, requireImageOwners
33717
33809
  if (!extensionStat.isFile() || extensionStat.isSymbolicLink()) return false;
33718
33810
  if (requireImageOwnership && !immutableImageFile(extensionPath)) return false;
33719
33811
  const source = readFileSync13(extensionPath, "utf8");
33720
- return createHash14("sha256").update(source, "utf8").digest("hex") === expectedSha256 && source.includes("BrowserCredentialAuthBroker") && source.includes("browser_authenticate") && source.includes("AMASTER_BROWSER_CREDENTIAL_PRIVATE_CHANNEL");
33812
+ return createHash15("sha256").update(source, "utf8").digest("hex") === expectedSha256 && source.includes("BrowserCredentialAuthBroker") && source.includes("browser_authenticate") && source.includes("AMASTER_BROWSER_CREDENTIAL_PRIVATE_CHANNEL");
33721
33813
  } catch {
33722
33814
  return false;
33723
33815
  }
@@ -33731,9 +33823,6 @@ function immutableImageFile(filePath) {
33731
33823
  }
33732
33824
  return true;
33733
33825
  }
33734
- function fileSha256(path) {
33735
- return createHash14("sha256").update(readFileSync13(path)).digest("hex");
33736
- }
33737
33826
  function treeAttestation(root, requireImageOwnership) {
33738
33827
  const files = [];
33739
33828
  const visit = (directory) => {
@@ -33746,7 +33835,7 @@ function treeAttestation(root, requireImageOwnership) {
33746
33835
  };
33747
33836
  visit(root);
33748
33837
  files.sort();
33749
- const digest2 = createHash14("sha256");
33838
+ const digest2 = createHash15("sha256");
33750
33839
  for (const path of files) {
33751
33840
  digest2.update(relative5(root, path).replaceAll("\\", "/"));
33752
33841
  digest2.update("\0");
@@ -33754,23 +33843,38 @@ function treeAttestation(root, requireImageOwnership) {
33754
33843
  }
33755
33844
  return digest2.digest("hex");
33756
33845
  }
33846
+ function imageTcbManifest(manifestPath, requireImageOwnership) {
33847
+ try {
33848
+ if (requireImageOwnership && !immutableImageFile(manifestPath)) return null;
33849
+ const manifest = JSON.parse(readFileSync13(manifestPath, "utf8"));
33850
+ if (manifest?.schemaVersion !== 1 || manifest.browserPackage?.name !== "@amaster.ai/pi-browser-use" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(manifest.browserPackage.version) || !TCB_INTEGRITY.test(manifest.browserPackage.integrity) || manifest.browserPackage.main !== "./dist/index.js" || !TCB_DIGEST.test(manifest.browserPackage.distTreeSha256) || manifest.browserTcb?.name !== "chrome-devtools-mcp" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(manifest.browserTcb.version) || !TCB_INTEGRITY.test(manifest.browserTcb.integrity) || !TCB_DIGEST.test(manifest.browserTcb.buildTreeSha256) || !TCB_DIGEST.test(manifest.authExtension?.sha256)) return null;
33851
+ return manifest;
33852
+ } catch {
33853
+ return null;
33854
+ }
33855
+ }
33757
33856
  function attestedPackageManifest(manifestPath, expected, requireImageOwnership) {
33758
33857
  try {
33759
33858
  if (requireImageOwnership && !immutableImageFile(manifestPath)) return null;
33760
33859
  const manifest = JSON.parse(readFileSync13(manifestPath, "utf8"));
33761
- if (manifest?.name !== "@amaster.ai/pi-browser-use" || manifest.version !== CREDENTIAL_BROWSER_PACKAGE_VERSION) return null;
33860
+ if (manifest?.name !== "@amaster.ai/pi-browser-use" || manifest.version !== expected.browserPackage.version) return null;
33762
33861
  if (manifest.main !== "./dist/index.js" || !Array.isArray(manifest.pi?.extensions) || manifest.pi.extensions.length !== 1 || manifest.pi.extensions[0] !== "./dist/index.js") return null;
33763
33862
  const packageDir = resolve11(manifestPath, "..");
33764
- if (Object.entries(expected.packageFiles).some(([relativePath, sha2563]) => {
33765
- const path = resolve11(packageDir, relativePath);
33766
- const relativePathFromPackage = relative5(packageDir, path);
33767
- return !relativePathFromPackage || relativePathFromPackage.startsWith("..") || isAbsolute7(relativePathFromPackage) || !statSync6(path).isFile() || requireImageOwnership && !immutableImageFile(path) || fileSha256(path) !== sha2563;
33768
- }) || treeAttestation(join17(packageDir, "dist"), requireImageOwnership) !== expected.packageDistTreeSha256) return null;
33863
+ const npmLockPath = join17(packageDir, "..", "..", "..", "package-lock.json");
33864
+ if (requireImageOwnership && !immutableImageFile(npmLockPath)) return null;
33865
+ const npmLock = JSON.parse(readFileSync13(npmLockPath, "utf8"));
33866
+ if (npmLock.packages?.["node_modules/@amaster.ai/pi-browser-use"]?.version !== expected.browserPackage.version || npmLock.packages?.["node_modules/@amaster.ai/pi-browser-use"]?.integrity !== expected.browserPackage.integrity || npmLock.packages?.["node_modules/chrome-devtools-mcp"]?.version !== expected.browserTcb.version || npmLock.packages?.["node_modules/chrome-devtools-mcp"]?.integrity !== expected.browserTcb.integrity || treeAttestation(join17(packageDir, "dist"), requireImageOwnership) !== expected.browserPackage.distTreeSha256) return null;
33769
33867
  const browserPackageDir = resolve11(packageDir, "..", "..", "chrome-devtools-mcp");
33770
33868
  const browserManifestPath = join17(browserPackageDir, "package.json");
33771
33869
  if (requireImageOwnership && !immutableImageFile(browserManifestPath)) return null;
33772
33870
  const browserPackage = JSON.parse(readFileSync13(browserManifestPath, "utf8"));
33773
- if (browserPackage.name !== expected.browserTcb.package || browserPackage.version !== expected.browserTcb.version || treeAttestation(join17(browserPackageDir, "build"), requireImageOwnership) !== expected.browserTcb.buildTreeSha256) return null;
33871
+ if (browserPackage.name !== expected.browserTcb.name || browserPackage.version !== expected.browserTcb.version || treeAttestation(join17(browserPackageDir, "build"), requireImageOwnership) !== expected.browserTcb.buildTreeSha256) return null;
33872
+ for (const entry of [browserPackage.main, browserPackage.bin?.["chrome-devtools-mcp"]]) {
33873
+ if (typeof entry !== "string" || !/^(?:\.\/)?build\//u.test(entry)) return null;
33874
+ const path = resolve11(browserPackageDir, entry);
33875
+ const fromBuild = relative5(join17(browserPackageDir, "build"), path);
33876
+ if (!fromBuild || fromBuild.startsWith("..") || isAbsolute7(fromBuild) || !lstatSync10(path).isFile() || lstatSync10(path).isSymbolicLink() || requireImageOwnership && !immutableImageFile(path)) return null;
33877
+ }
33774
33878
  const entrypoint = resolve11(packageDir, manifest.main);
33775
33879
  const relativeEntrypoint = relative5(packageDir, entrypoint);
33776
33880
  if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || isAbsolute7(relativeEntrypoint) || !existsSync12(entrypoint) || requireImageOwnership && !immutableImageFile(entrypoint)) return null;
@@ -33924,11 +34028,12 @@ function browserCredentialPrivateAuthority(command, presentation = browserCreden
33924
34028
  const origin = parsedTarget.protocol === "https:" && !parsedTarget.username && !parsedTarget.password ? parsedTarget.origin : null;
33925
34029
  const passwordRefs = refs.filter((ref2) => ref2?.credentialRole === "password");
33926
34030
  const usernameRefs = refs.filter((ref2) => ref2?.credentialRole === "username");
33927
- if (!origin || refs.length < 1 || refs.length > 2 || passwordRefs.length !== 1 || usernameRefs.length > 1 || !predicate || predicate.version !== 1 || predicate.type !== "snapshot_text_v1" || typeof predicate.requiredText !== "string" || predicate.requiredText !== predicate.requiredText.trim() || predicate.requiredText.length < 8 || predicate.requiredText.length > 256 || /[\u0000-\u001f\u007f]/u.test(predicate.requiredText) || refs.some((ref2) => ref2?.commandId !== command?.commandId || ref2?.bindingId !== session?.bindingId || ref2?.browserLeaseId !== session?.browserLeaseId || ref2?.targetOrigin !== origin || ref2?.authenticationOrigin !== origin)) {
34031
+ const version = session?.version === 2 ? 2 : 1;
34032
+ if (!origin || refs.length < 1 || refs.length > 2 || passwordRefs.length !== 1 || usernameRefs.length > 1 || !predicate || predicate.version !== 1 || predicate.type !== "snapshot_text_v1" || typeof predicate.requiredText !== "string" || predicate.requiredText !== predicate.requiredText.trim() || predicate.requiredText.length < 8 || predicate.requiredText.length > 256 || /[\u0000-\u001f\u007f]/u.test(predicate.requiredText) || refs.some((ref2) => (version === 2 ? ref2?.version !== 2 : ref2?.version !== void 0 && ref2?.version !== 1) || ref2?.commandId !== command?.commandId || (version === 1 ? ref2?.bindingId !== session?.bindingId || ref2?.browserLeaseId !== session?.browserLeaseId : ref2?.grantId !== session?.grantId || ref2?.grantRevision !== session?.grantRevision || ref2?.commandAuthId !== session?.commandAuthId || ref2?.grantKind !== session?.grantKind || ref2?.interactionId !== session?.interactionId || ref2?.companyId !== session?.companyId) || ref2?.targetOrigin !== origin || ref2?.authenticationOrigin !== origin)) {
33928
34033
  fail3("browser_credential_authority_invalid");
33929
34034
  }
33930
34035
  return Object.freeze({
33931
- version: 1,
34036
+ version,
33932
34037
  targetUrl: parsedTarget.href,
33933
34038
  authenticatedPredicate: Object.freeze({ ...predicate }),
33934
34039
  refs: Object.freeze(refs.map((ref2) => Object.freeze({ ...ref2 })))
@@ -34011,7 +34116,7 @@ async function materializeBrowserCredentialEnv(plan, options) {
34011
34116
  }
34012
34117
 
34013
34118
  // src/amaster-runtime-daemon/runtime-artifact-upload.mjs
34014
- import { createHash as createHash15 } from "node:crypto";
34119
+ import { createHash as createHash16 } from "node:crypto";
34015
34120
  import { closeSync as closeSync4, constants as constants3, fstatSync as fstatSync4, lstatSync as lstatSync13, openSync as openSync4, readFileSync as readFileSync16, realpathSync as realpathSync10 } from "node:fs";
34016
34121
  import { isAbsolute as isAbsolute10, relative as relative6, resolve as resolve13 } from "node:path";
34017
34122
  var SHA256_PATTERN = /^[a-f0-9]{64}$/;
@@ -34101,7 +34206,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
34101
34206
  `Runtime Artifact ${intentId}`,
34102
34207
  { expectedByteSize }
34103
34208
  );
34104
- const actualSha256 = createHash15("sha256").update(body).digest("hex");
34209
+ const actualSha256 = createHash16("sha256").update(body).digest("hex");
34105
34210
  if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
34106
34211
  throw new Error(`Runtime Artifact ${intentId} bytes do not match the governed ownership manifest`);
34107
34212
  }
@@ -34118,7 +34223,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
34118
34223
  }
34119
34224
 
34120
34225
  // src/amaster-runtime-daemon/runtime-document-upload.mjs
34121
- import { createHash as createHash16 } from "node:crypto";
34226
+ import { createHash as createHash17 } from "node:crypto";
34122
34227
 
34123
34228
  // src/amaster-runtime-daemon/workspace-sensitive-path.mjs
34124
34229
  var SENSITIVE_PATH_SEGMENTS = /* @__PURE__ */ new Set([
@@ -34193,7 +34298,7 @@ function prepareRuntimeDocumentUploads(cwd, mcpToolResults) {
34193
34298
  maxByteSize: MAX_WORKSPACE_DOCUMENT_BYTES
34194
34299
  }
34195
34300
  );
34196
- const actualSha256 = createHash16("sha256").update(body).digest("hex");
34301
+ const actualSha256 = createHash17("sha256").update(body).digest("hex");
34197
34302
  if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
34198
34303
  throw new Error(`Runtime Document ${callId} bytes do not match the governed ownership manifest`);
34199
34304
  }
@@ -34390,7 +34495,7 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
34390
34495
  }
34391
34496
 
34392
34497
  // src/amaster-runtime-daemon/workspace-guard.mjs
34393
- import { createHash as createHash17 } from "node:crypto";
34498
+ import { createHash as createHash18 } from "node:crypto";
34394
34499
  import { existsSync as existsSync14, mkdirSync as mkdirSync12, realpathSync as realpathSync11, statSync as statSync7 } from "node:fs";
34395
34500
  import { basename as basename6, join as join21, isAbsolute as isAbsolute11, relative as relative7, resolve as resolve14 } from "node:path";
34396
34501
  function pathWithin3(candidate, root) {
@@ -34419,7 +34524,7 @@ function resolveWorkspaceCwd(config, command) {
34419
34524
  return cwd;
34420
34525
  }
34421
34526
  function shortHash(value, length = 12) {
34422
- return createHash17("sha256").update(String(value)).digest("hex").slice(0, length);
34527
+ return createHash18("sha256").update(String(value)).digest("hex").slice(0, length);
34423
34528
  }
34424
34529
  function safeSegment(value, fallback) {
34425
34530
  const raw = String(value ?? "").trim();
@@ -34615,7 +34720,7 @@ function planManagedWorkspaceGcDryRun(input) {
34615
34720
  }
34616
34721
 
34617
34722
  // src/amaster-runtime-daemon/preset-templates.mjs
34618
- import { createHash as createHash18 } from "node:crypto";
34723
+ import { createHash as createHash19 } from "node:crypto";
34619
34724
  import {
34620
34725
  accessSync,
34621
34726
  chmodSync as chmodSync8,
@@ -34639,7 +34744,7 @@ var MAX_PRESET_TEMPLATE_FILES = 256;
34639
34744
  var MAX_PRESET_TEMPLATE_FILE_BYTES = 20 * 1024 * 1024;
34640
34745
  var MAX_PRESET_TEMPLATE_TOTAL_BYTES = 50 * 1024 * 1024;
34641
34746
  function sha2562(value) {
34642
- return createHash18("sha256").update(value).digest("hex");
34747
+ return createHash19("sha256").update(value).digest("hex");
34643
34748
  }
34644
34749
  function lstatIfExists(path) {
34645
34750
  try {
@@ -35310,7 +35415,7 @@ export default function amasterProjectInstructions(pi) {
35310
35415
 
35311
35416
  // src/amaster-runtime-daemon/workspace-status.mjs
35312
35417
  import { spawnSync as spawnSync5 } from "node:child_process";
35313
- import { createHash as createHash19 } from "node:crypto";
35418
+ import { createHash as createHash20 } from "node:crypto";
35314
35419
  import { existsSync as existsSync18, readdirSync as readdirSync13, readFileSync as readFileSync20, statSync as statSync11 } from "node:fs";
35315
35420
  import { basename as basename7, extname as extname2, isAbsolute as isAbsolute13, join as join25, relative as relative8, resolve as resolve19 } from "node:path";
35316
35421
  var WORKSPACE_RUNTIME_SERVICES_FILENAME = ".amaster-runtime-services.json";
@@ -35381,7 +35486,7 @@ function sanitizeTrackedChange(line) {
35381
35486
  return isSafeRelativePath(path) ? line : null;
35382
35487
  }
35383
35488
  function sha256File(filePath) {
35384
- return createHash19("sha256").update(readFileSync20(filePath)).digest("hex");
35489
+ return createHash20("sha256").update(readFileSync20(filePath)).digest("hex");
35385
35490
  }
35386
35491
  function artifactHashCacheKey(relativePath, stat) {
35387
35492
  return `${relativePath}\0${stat.size}\0${stat.mtimeMs}`;
@@ -35613,7 +35718,7 @@ function assertRequiredTaskAttachmentMaterialized(input, materialized) {
35613
35718
  }
35614
35719
 
35615
35720
  // src/amaster-runtime-daemon.mjs
35616
- var CONNECTOR_VERSION = "0.1.14";
35721
+ var CONNECTOR_VERSION = "0.1.16";
35617
35722
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
35618
35723
  var SUPPORTED_TASK_CONTEXT_VERSIONS = Object.freeze([TASK_CONTEXT_MANIFEST_VERSION, TASK_CONTEXT_V2]);
35619
35724
  var daemonRequire = createRequire(import.meta.url);
@@ -35627,6 +35732,27 @@ var PI_COMPLETION_OUTPUT_TYPES = /* @__PURE__ */ new Set(["agent_settled", "appr
35627
35732
  var PI_MODEL_CALL_PROTOCOL_AMPLIFICATION_LIMIT = 8;
35628
35733
  var PROCESS_GROUP_RSS_SAMPLE_MIN_INTERVAL_MS = 5e3;
35629
35734
  var activeRunCommands = /* @__PURE__ */ new Map();
35735
+ var companyBrowserProfileTails = /* @__PURE__ */ new Map();
35736
+ async function acquireCompanyBrowserProfileLock(companyId) {
35737
+ if (typeof companyId !== "string" || !/^[0-9a-f-]{36}$/iu.test(companyId)) {
35738
+ throw new Error("browser_company_profile_invalid");
35739
+ }
35740
+ const preceding = companyBrowserProfileTails.get(companyId) ?? Promise.resolve();
35741
+ let resolveCurrent;
35742
+ const current = new Promise((resolve21) => {
35743
+ resolveCurrent = resolve21;
35744
+ });
35745
+ const tail = preceding.then(() => current);
35746
+ companyBrowserProfileTails.set(companyId, tail);
35747
+ await preceding;
35748
+ let released = false;
35749
+ return () => {
35750
+ if (released) return;
35751
+ released = true;
35752
+ resolveCurrent();
35753
+ if (companyBrowserProfileTails.get(companyId) === tail) companyBrowserProfileTails.delete(companyId);
35754
+ };
35755
+ }
35630
35756
  var pendingResultOutboxRunCommands = /* @__PURE__ */ new Map();
35631
35757
  var pendingRunCompletionCommands = /* @__PURE__ */ new Map();
35632
35758
  var runCompletionCoordinators = /* @__PURE__ */ new Map();
@@ -36303,7 +36429,7 @@ function handoffPiRunPathsToChild(config, paths) {
36303
36429
  function materializePiRuntimeSystemPrompt(config, promptRoot, commandId, contents) {
36304
36430
  const normalizedCommandId = readString(commandId);
36305
36431
  if (!normalizedCommandId) throw new Error("pi_runtime_system_prompt_command_id_missing");
36306
- const promptIdentity = createHash20("sha256").update(normalizedCommandId).digest("hex");
36432
+ const promptIdentity = createHash21("sha256").update(normalizedCommandId).digest("hex");
36307
36433
  const promptDir = join26(promptRoot, "tmp");
36308
36434
  mkdirSync14(promptDir, { recursive: true, mode: 448 });
36309
36435
  const promptDirStat = lstatSync16(promptDir);
@@ -36951,6 +37077,9 @@ function commandTaskResourceInput(command) {
36951
37077
  }
36952
37078
  var BROWSER_SESSION_PROFILE_OWNER_MARKER = ".mirrorx-browser-session-owner.json";
36953
37079
  function browserSessionProfileIdentity(config, session) {
37080
+ if (session.version === 2) {
37081
+ return browserGrantProfileIdentity(readString(session.companyId), readString(session.origin));
37082
+ }
36954
37083
  const identity = {
36955
37084
  version: 1,
36956
37085
  companyId: readString(session.companyId),
@@ -37000,7 +37129,7 @@ function ensureBrowserSessionProfile(config, session) {
37000
37129
  } else {
37001
37130
  const temporaryPath = join26(
37002
37131
  userDataDir,
37003
- `.${BROWSER_SESSION_PROFILE_OWNER_MARKER}.${process.pid}.${createHash20("sha256").update(randomUUID3()).digest("hex")}`
37132
+ `.${BROWSER_SESSION_PROFILE_OWNER_MARKER}.${process.pid}.${createHash21("sha256").update(randomUUID3()).digest("hex")}`
37004
37133
  );
37005
37134
  writeFileSync15(temporaryPath, `${JSON.stringify(identity)}
37006
37135
  `, { mode: 384, flag: "wx" });
@@ -37089,7 +37218,7 @@ function safeAgentInstructionMaterializationTarget(workspace, filePath) {
37089
37218
  }
37090
37219
  function stableInstructionFilesHash(files) {
37091
37220
  const canonical = Object.entries(files).filter(([filePath, content]) => typeof filePath === "string" && typeof content === "string").sort(([left], [right]) => left.localeCompare(right)).map(([filePath, content]) => `${filePath.length}:${filePath}${content.length}:${content}`).join("");
37092
- return createHash20("sha256").update(canonical, "utf8").digest("hex");
37221
+ return createHash21("sha256").update(canonical, "utf8").digest("hex");
37093
37222
  }
37094
37223
  function requireCommandContextEnvelope(command) {
37095
37224
  const payload = asRecord(command.payload);
@@ -37133,7 +37262,7 @@ function requireCommandContextEnvelope(command) {
37133
37262
  if (instructions.effectiveChars !== files["AGENTS.md"].length) {
37134
37263
  throw new Error("context_envelope_instruction_size_mismatch");
37135
37264
  }
37136
- const entrySha256 = createHash20("sha256").update(files["AGENTS.md"], "utf8").digest("hex");
37265
+ const entrySha256 = createHash21("sha256").update(files["AGENTS.md"], "utf8").digest("hex");
37137
37266
  if (entrySha256 !== readString(instructions.contentSha256)) {
37138
37267
  throw new Error("context_envelope_instruction_content_hash_mismatch");
37139
37268
  }
@@ -37143,7 +37272,7 @@ function requireCommandContextEnvelope(command) {
37143
37272
  }
37144
37273
  const runDecisionContext = asRecord(envelope.runDecisionContext);
37145
37274
  const dynamicContext2 = asRecord(runDecisionContext.content);
37146
- const runDecisionHash = createHash20("sha256").update(canonicalGoalOutcomeValue(dynamicContext2), "utf8").digest("hex");
37275
+ const runDecisionHash = createHash21("sha256").update(canonicalGoalOutcomeValue(dynamicContext2), "utf8").digest("hex");
37147
37276
  if (!readString(runDecisionContext.revision) || !Number.isInteger(runDecisionContext.authorizationEpoch) || runDecisionContext.authorizationEpoch < 0 || runDecisionHash !== readString(runDecisionContext.contentSha256)) throw new Error("context_envelope_run_decision_invalid");
37148
37277
  if (!Array.isArray(envelope.selectedProcedures)) throw new Error("context_envelope_procedures_invalid");
37149
37278
  const toolProfile = asRecord(envelope.toolProfile);
@@ -37153,7 +37282,7 @@ function requireCommandContextEnvelope(command) {
37153
37282
  throw new Error("context_envelope_session_binding_invalid");
37154
37283
  }
37155
37284
  const envelopeHashInput = Object.fromEntries(Object.entries(envelope).filter(([key]) => key !== "envelopeSha256"));
37156
- const envelopeHash = createHash20("sha256").update(canonicalGoalOutcomeValue(envelopeHashInput), "utf8").digest("hex");
37285
+ const envelopeHash = createHash21("sha256").update(canonicalGoalOutcomeValue(envelopeHashInput), "utf8").digest("hex");
37157
37286
  if (envelopeHash !== readString(envelope.envelopeSha256)) {
37158
37287
  throw new Error("context_envelope_hash_mismatch");
37159
37288
  }
@@ -37184,7 +37313,7 @@ async function materializeEffectiveAgentInstructions(config, command, workspace,
37184
37313
  materialized.push({
37185
37314
  path: target.relativePath,
37186
37315
  byteSize: Buffer.byteLength(content, "utf8"),
37187
- sha256: createHash20("sha256").update(content, "utf8").digest("hex")
37316
+ sha256: createHash21("sha256").update(content, "utf8").digest("hex")
37188
37317
  });
37189
37318
  }
37190
37319
  const readBackFiles = Object.fromEntries(materialized.map((entry) => [
@@ -38733,6 +38862,7 @@ function runExecutor(command, args, options) {
38733
38862
  const maxRssBytes = maxRssMb * 1024 * 1024;
38734
38863
  const browserCredentialChannel = typeof options.browserCredentialConsumer === "function" ? createBrowserCredentialChannel({
38735
38864
  consume: options.browserCredentialConsumer,
38865
+ authorizedRefs: options.browserCredentialRefs,
38736
38866
  onFailure: (reason) => {
38737
38867
  spawnError = reason;
38738
38868
  spawnErrorCode = reason;
@@ -39986,12 +40116,12 @@ async function materializeIssueAttachments(config, command, workspace) {
39986
40116
  usedFilenames.add(filename);
39987
40117
  const targetPath = join26(targetDir, filename);
39988
40118
  const body = await runtimeApiBuffer(runtimeAuth, contentPath);
39989
- if (attachment.initializationInput === true && (body.byteLength !== attachment.byteSize || createHash20("sha256").update(body).digest("hex") !== attachment.sha256)) {
40119
+ if (attachment.initializationInput === true && (body.byteLength !== attachment.byteSize || createHash21("sha256").update(body).digest("hex") !== attachment.sha256)) {
39990
40120
  throw new Error("Initialization input content does not match its preparation receipt");
39991
40121
  }
39992
40122
  writeFileSync15(targetPath, body);
39993
40123
  const attachmentId = readString(attachment.id);
39994
- const actualSha256 = createHash20("sha256").update(body).digest("hex");
40124
+ const actualSha256 = createHash21("sha256").update(body).digest("hex");
39995
40125
  const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
39996
40126
  const lineage = selectAttachmentLineage(lineageCandidates, actualSha256);
39997
40127
  if (lineageCandidates.length > 0 && !lineage) {
@@ -40076,7 +40206,7 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
40076
40206
  throw new Error(`artifact_input_manifest_invalid: entry ${index} contentPath does not match attachmentId`);
40077
40207
  }
40078
40208
  const body = await runtimeApiBuffer(runtimeAuth, contentPath);
40079
- const actualSha256 = createHash20("sha256").update(body).digest("hex");
40209
+ const actualSha256 = createHash21("sha256").update(body).digest("hex");
40080
40210
  if (body.byteLength !== byteSize || actualSha256 !== sha2563) {
40081
40211
  throw new Error(
40082
40212
  `artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha2563} actualSha256=${actualSha256}`
@@ -40155,7 +40285,7 @@ async function materializeMentionedArtifactFiles(config, command, workspace) {
40155
40285
  });
40156
40286
  continue;
40157
40287
  }
40158
- const actualSha256 = createHash20("sha256").update(body).digest("hex");
40288
+ const actualSha256 = createHash21("sha256").update(body).digest("hex");
40159
40289
  const expectedSha256 = readString(entry.sha256)?.toLowerCase() ?? null;
40160
40290
  const expectedByteSize = readNumber(entry.byteSize, null);
40161
40291
  if (expectedByteSize !== null && body.byteLength !== expectedByteSize || expectedSha256 && actualSha256 !== expectedSha256) {
@@ -40223,7 +40353,7 @@ function safeCheckpointRelativePath(rawPath) {
40223
40353
  return normalized;
40224
40354
  }
40225
40355
  function hashFileSha256(filePath) {
40226
- return createHash20("sha256").update(readFileSync21(filePath)).digest("hex");
40356
+ return createHash21("sha256").update(readFileSync21(filePath)).digest("hex");
40227
40357
  }
40228
40358
  function expectedContinuationCheckpoint(command) {
40229
40359
  const payload = asRecord(command.payload);
@@ -40711,6 +40841,7 @@ async function executeRunCommand(config, command) {
40711
40841
  let invocation = null;
40712
40842
  let executorEnv = buildExecutorEnv(config, command, workspace);
40713
40843
  let browserSessionUserDataDir = null;
40844
+ let releaseBrowserProfileLock = null;
40714
40845
  let managedMcpProfile = null;
40715
40846
  let managedMcpCleanup = null;
40716
40847
  let cleanupManagedMcpProfile = null;
@@ -40756,7 +40887,11 @@ async function executeRunCommand(config, command) {
40756
40887
  };
40757
40888
  try {
40758
40889
  await runExecutionStage("browser_session", async () => {
40759
- if (Object.keys(browserSession).length > 0) {
40890
+ if (browserSession.version === 2 && (executor.kind !== "pi" || config.runnerKind !== RUNNER_KIND_CLOUD_MANAGED || Object.keys(governedMcp).length === 0)) throw new Error("browser_session_governed_pi_required");
40891
+ if (executor.kind === "pi" && config.runnerKind === RUNNER_KIND_CLOUD_MANAGED && browserSession.version === 2) {
40892
+ releaseBrowserProfileLock = await acquireCompanyBrowserProfileLock(executorEnv.PAPERCLIP_COMPANY_ID);
40893
+ }
40894
+ if (Object.keys(browserSession).length > 0 && browserSession.version !== 2) {
40760
40895
  if (executor.kind !== "pi" || Object.keys(governedMcp).length === 0) {
40761
40896
  throw new Error("browser_session_governed_pi_required");
40762
40897
  }
@@ -40765,6 +40900,15 @@ async function executeRunCommand(config, command) {
40765
40900
  }
40766
40901
  const ownedProfile = ensureBrowserSessionProfile(config, browserSession);
40767
40902
  browserSessionUserDataDir = ownedProfile.userDataDir;
40903
+ } else if (browserSession.version === 2) {
40904
+ if (browserSession.companyId !== executorEnv.PAPERCLIP_COMPANY_ID) {
40905
+ throw new Error("browser_session_company_mismatch");
40906
+ }
40907
+ const companyProfile = { version: 2, companyId: executorEnv.PAPERCLIP_COMPANY_ID, origin: browserSession.origin };
40908
+ if (browserSession.resetProfile === true) {
40909
+ cleanupBrowserSessionProfile(config, companyProfile);
40910
+ }
40911
+ browserSessionUserDataDir = ensureBrowserSessionProfile(config, companyProfile).userDataDir;
40768
40912
  }
40769
40913
  invocation = buildExecutorInvocation(executor, executionCommand, workspace);
40770
40914
  if (taskSessionCheckpointUnavailable) {
@@ -41232,7 +41376,10 @@ async function executeRunCommand(config, command) {
41232
41376
  signal: abortController.signal,
41233
41377
  executorKind: executor.kind,
41234
41378
  ...piExecutorIdentity ? { spawnIdentity: piExecutorIdentity } : {},
41235
- ...browserCredentialConsumer ? { browserCredentialConsumer } : {},
41379
+ ...browserCredentialConsumer ? {
41380
+ browserCredentialConsumer,
41381
+ browserCredentialRefs: asRecord(command.payload).browserCredentialRefs
41382
+ } : {},
41236
41383
  onOutput: (stream, chunk, rawBytes) => {
41237
41384
  if (!firstOutput) {
41238
41385
  firstOutput = true;
@@ -41824,6 +41971,7 @@ async function executeRunCommand(config, command) {
41824
41971
  }
41825
41972
  return { resultDelivered: Boolean(completion) };
41826
41973
  } finally {
41974
+ releaseBrowserProfileLock?.();
41827
41975
  await preparationLogChain;
41828
41976
  if (piRuntimeSystemPromptCleanupPath) {
41829
41977
  rmSync12(piRuntimeSystemPromptCleanupPath, { force: true });
@@ -41852,15 +42000,23 @@ async function processCommand(config, command) {
41852
42000
  }
41853
42001
  if (command.commandType === "browser_session_revoke" && Object.keys(commandBrowserSession(command)).length > 0) {
41854
42002
  await ackCommand(config, command, "spawned");
41855
- const cleanup = cleanupBrowserSessionProfile(
41856
- config,
41857
- commandBrowserSession(command)
41858
- );
42003
+ const session = commandBrowserSession(command);
42004
+ if (session.version === 2 && session.companyId !== asRecord(command.payload).companyId) {
42005
+ throw new Error("browser_session_company_mismatch");
42006
+ }
42007
+ const release = session.version === 2 ? await acquireCompanyBrowserProfileLock(session.companyId) : null;
42008
+ let cleanup;
42009
+ try {
42010
+ cleanup = cleanupBrowserSessionProfile(config, session);
42011
+ } finally {
42012
+ release?.();
42013
+ }
41859
42014
  await completeCommand(config, command, "succeeded", {
41860
42015
  browserSessionCleanup: {
41861
- version: 1,
42016
+ version: cleanup.identity.version,
41862
42017
  companyId: cleanup.identity.companyId,
41863
- bindingId: cleanup.identity.bindingId,
42018
+ ...cleanup.identity.origin ? { origin: cleanup.identity.origin } : {},
42019
+ ...cleanup.identity.bindingId ? { bindingId: cleanup.identity.bindingId } : {},
41864
42020
  outcome: cleanup.outcome
41865
42021
  }
41866
42022
  });
@@ -7,7 +7,7 @@ import { homedir, hostname } from "node:os";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { BUILD_SUPPORTED_CAPABILITIES } from "./amaster-runtime-daemon/capability-registry.mjs";
9
9
 
10
- const CONNECTOR_VERSION = "0.1.14";
10
+ const CONNECTOR_VERSION = "0.1.16";
11
11
 
12
12
  const CONFIG_KEY_MAP = new Map([
13
13
  ["server_url", "AMASTER_EMPLOYEE_SERVER_URL"],
@@ -3,8 +3,8 @@
3
3
  "files": [
4
4
  {
5
5
  "name": "CEO经营简报模板.md",
6
- "bytes": 8066,
7
- "sha256": "07aa5e73e5e5c2dfe2bf5eee9633b5f0a8a8333e0899f0c73cb37cc59dbca3a4"
6
+ "bytes": 8866,
7
+ "sha256": "2bc380b76941530cf70f4320aa6f770037608752283ef0784718711172c818b3"
8
8
  },
9
9
  {
10
10
  "name": "产品缺陷清单模板.md",
@@ -4,6 +4,7 @@
4
4
  <purpose>这是供 CEO 判断方向、取舍与资源配置的经营简报,不是数据汇总。先回答公司是否仍在向已确认战略目标前进、哪些经营结果真正改变了局面、哪些偏差需要管理决策,再用必要数据支撑判断。</purpose>
5
5
  <strategy_baseline>以当前 active primary Goal 及其绑定的已确认公司战略文档为唯一战略基线;从中提取战略主题、目标、指标、重大举措、里程碑、关键假设和风险护栏。不用原始战略规划模板代替公司已确认战略。找不到可验证基线时,明确标记“战略基线缺失”及补齐责任人,不自行构造目标。</strategy_baseline>
6
6
  <period_focus>日报聚焦当日战略异常、关键结果、阻塞和次日动作;周报增加目标计分卡、周环比、重大举措与资源偏差;月报完整检查目标达成、战略假设、业务组合、预算资源和风险阈值,并判断是否需要启动战略修订。各类简报均保留任务要求的业务主题;无变化时注明核实范围与当前状态,缺数据时列出缺口及影响,不能以压缩篇幅为由省略关键风险、经营判断或必要图表。</period_focus>
7
+ <time_cutoff>报告周期与数据截止时间分别填写,并统一用报告时区比较期限。提前生成的周报或月报只报告截至数据截止时间已发生、已核实的事实;周期尚未结束时写“截至 YYYY-MM-DD HH:mm”或“本期至今”,不能写“全周”“全月”“周末”“月末”来暗示已覆盖完整周期。逐项核对任务或决策的截止日期与数据截止时间:未来期限写“尚未到期”,只有期限确已过去且事项仍未完成时才能写“逾期”或“已到期未决”;缺少期限时不推断逾期。若只有日期而没有具体时刻,以报告时区该日结束作为期限。提交文档前复查摘要、表格、图表说明和风险措辞,修正与截止时间冲突的表述。</time_cutoff>
7
8
  <judgement>每个重要结论使用“事实与来源 → 对战略目标的影响 → CEO 判断或动作”。任务完成、运行成功、报告或系统上线只是内部产出,除非有可验证经营变化和验收证据,不得写成业务结果。对无法映射到当前战略目标或重大举措的持续工作,显式标记为战略外资源占用并给出停止、降级或保留的建议。</judgement>
8
9
  <metrics>只保留会改变管理判断的战略衡量与经营信号。可量化的衡量项写明定义和口径、基线、目标或阈值、当前值、趋势、截止时间和来源;客户、市场、竞品或风险信号写明事实、时间和对管理判断的影响。缺失值写明影响、补齐动作、责任人和审定节点,不得以 0 或估算值代替。图表只使用可追溯真实数字;有适合比较的数据时必须制图,并说明结论、单位、期间与来源。数据不足时以证据或缺口表替代,不虚构图表。</metrics>
9
10
  <visual_delivery>首页依次展示总体判断、重点变化和待决策事项,使用清楚的标题和选择性加粗帮助人快速定位。保留战略衡量与经营信号表;多项指标、资源投入和行动使用表格对照,战略取舍与根因用段落解释。状态与风险标记须有已确认目标、阈值或期限作为依据,并附文字说明,不把所有经营判断归为红黄绿。图表能更清楚地揭示关键趋势、差异或结构时采用:时间趋势使用 Mermaid xychart-beta,类别比较使用柱状图,互斥且覆盖同一总体的非负占比才使用 pie;只有单点或不可比数字时用文字或证据表说明。每幅图紧邻一句经营解读,数字与明细一致;增长不一定有利,按指标业务含义解释变化。避免重复展示同一结论。报告无需限定篇幅,完整判断、可读性和证据优先。</visual_delivery>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/employee-runtime-connector",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",