@amaster.ai/employee-runtime-connector 0.1.1-beta.21 → 0.1.1-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ For production images, install an exact version and invoke the package bin:
13
13
  ```sh
14
14
  npm install --omit=dev --prefix /opt/pi-cli-runtime @amaster.ai/employee-runtime-connector@0.1.0
15
15
  /opt/pi-cli-runtime/node_modules/.bin/amaster-runtime setup https://employee.example.com \
16
- --capabilities remote_registration,heartbeat,executor_discovery,workspace_binding,run_wakeup,model_call,run_cancel,run_terminate,logs_cost_workspace_status
16
+ --capabilities remote_registration,heartbeat,executor_discovery,workspace_binding,run_wakeup,model_call,model_call_output_contract_v1,run_cancel,run_terminate,logs_cost_workspace_status
17
17
  /opt/pi-cli-runtime/node_modules/.bin/amaster-runtime daemon start --foreground
18
18
  ```
19
19
 
@@ -32,6 +32,20 @@ The source of truth lives under this package's `src/` directory. The package bui
32
32
 
33
33
  Runtime code belongs in the container image. Persist only connector state, the result outbox, and workspaces under the configured state directory.
34
34
 
35
+ ## Contracted Pi model calls
36
+
37
+ Pi `model_call` commands with `model_call_output_contract_v1` keep provider and
38
+ model selection paired with the output ceiling. Command target fields have the
39
+ highest precedence, followed by `AMASTER_PI_PROVIDER` / `AMASTER_PI_MODEL`, then
40
+ the Pi profile's `defaultProvider` / `defaultModel`. Each selected precedence
41
+ layer must be a complete provider/model pair: a partial command or runtime
42
+ override fails closed instead of silently falling through to a lower-precedence
43
+ default. The daemon copies only the normalized default pair into the isolated
44
+ one-shot profile, validates that the resolved model exists, applies
45
+ `maxOutputTokens` to that exact model, and records the resolved target and source
46
+ in command-result diagnostics. Missing or unknown targets also fail closed
47
+ before Pi is spawned.
48
+
35
49
  ## Pi tool-argument transport guard
36
50
 
37
51
  `AMASTER_PI_TOOL_ARGUMENT_GUARD_MODE` defaults to `shadow`; supported values are
@@ -2,7 +2,7 @@
2
2
  // MirrorX runtime connector daemon bundle.
3
3
 
4
4
  // src/amaster-runtime-daemon.mjs
5
- import { createHash as createHash14 } from "node:crypto";
5
+ import { createHash as createHash15 } from "node:crypto";
6
6
  import { chmodSync as chmodSync6, copyFileSync as copyFileSync3, existsSync as existsSync14, lstatSync as lstatSync7, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync11, readdirSync as readdirSync9, realpathSync as realpathSync5, renameSync as renameSync6, rmSync as rmSync7, statSync as statSync8, symlinkSync as symlinkSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "node:fs";
7
7
  import { arch as arch3, homedir as homedir3, hostname as hostname2, platform as platform3, tmpdir } from "node:os";
8
8
  import { basename as basename6, delimiter as delimiter3, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute8, join as join15, relative as relative9, resolve as resolve12 } from "node:path";
@@ -2005,6 +2005,73 @@ function syncAmasterProviderFiles(agentDir, executorEnv) {
2005
2005
  settingsSynced: syncAmasterProviderSettings(agentDir, executorEnv)
2006
2006
  };
2007
2007
  }
2008
+ function normalizePiModelId(modelId) {
2009
+ return readString(modelId)?.replace(/:(?:off|minimal|low|medium|high|xhigh|max)$/i, "") ?? null;
2010
+ }
2011
+ function assertPiModelConfigured(agentDir, provider, model) {
2012
+ const modelsPath = join3(agentDir, "models.json");
2013
+ const config = readJsonFile(modelsPath);
2014
+ const providers = asRecord(config.providers);
2015
+ const providerConfig = asRecord(providers[provider]);
2016
+ const configuredModels = Array.isArray(providerConfig.models) ? providerConfig.models : [];
2017
+ const configuredModelExists = configuredModels.some((entry) => readString(asRecord(entry).id) === model);
2018
+ const existingOverrides = asRecord(providerConfig.modelOverrides);
2019
+ if (!configuredModelExists && !(model in existingOverrides)) {
2020
+ throw new Error(`pi_model_call_model_missing: ${provider}/${model}`);
2021
+ }
2022
+ return { modelsPath, config, providers, providerConfig, existingOverrides };
2023
+ }
2024
+ function resolvePiModelCallTarget(agentDir, providerId, modelId, explicitSource = "command") {
2025
+ const explicitProvider = readString(providerId);
2026
+ const explicitModel = normalizePiModelId(modelId);
2027
+ if (Boolean(explicitProvider) !== Boolean(explicitModel)) {
2028
+ throw new Error("pi_model_call_target_partial");
2029
+ }
2030
+ let provider = explicitProvider;
2031
+ let model = explicitModel;
2032
+ let source = explicitSource;
2033
+ if (!provider || !model) {
2034
+ const settings = readJsonFile(join3(agentDir, "settings.json"));
2035
+ const defaultProvider = readString(settings.defaultProvider);
2036
+ const defaultModel = normalizePiModelId(settings.defaultModel);
2037
+ if (Boolean(defaultProvider) !== Boolean(defaultModel)) {
2038
+ throw new Error("pi_model_call_default_partial");
2039
+ }
2040
+ if (!defaultProvider || !defaultModel) {
2041
+ throw new Error("pi_model_call_default_missing");
2042
+ }
2043
+ provider = defaultProvider;
2044
+ model = defaultModel;
2045
+ source = "pi_settings_default";
2046
+ }
2047
+ assertPiModelConfigured(agentDir, provider, model);
2048
+ return { provider, model, source };
2049
+ }
2050
+ function applyModelCallOutputContract(agentDir, providerId, modelId, maxOutputTokens) {
2051
+ const provider = readString(providerId);
2052
+ const model = normalizePiModelId(modelId);
2053
+ const tokenLimit = Number(maxOutputTokens);
2054
+ if (!provider || !model || !Number.isSafeInteger(tokenLimit) || tokenLimit <= 0) {
2055
+ throw new Error("pi_model_call_output_contract_invalid");
2056
+ }
2057
+ const { modelsPath, config, providers, providerConfig, existingOverrides } = assertPiModelConfigured(agentDir, provider, model);
2058
+ writeJsonFileAtomic(modelsPath, {
2059
+ ...config,
2060
+ providers: {
2061
+ ...providers,
2062
+ [provider]: {
2063
+ ...providerConfig,
2064
+ modelOverrides: {
2065
+ ...existingOverrides,
2066
+ [model]: {
2067
+ ...asRecord(existingOverrides[model]),
2068
+ maxTokens: tokenLimit
2069
+ }
2070
+ }
2071
+ }
2072
+ }
2073
+ });
2074
+ }
2008
2075
 
2009
2076
  // src/amaster-runtime-daemon/pi-mcp-args-normalizer.mjs
2010
2077
  function isJsonObject(value) {
@@ -2734,11 +2801,11 @@ function createManagedPiMcpProfileApi(options = {}) {
2734
2801
  if (!Number.isFinite(value)) throw new Error("pi_managed_mcp_attestation_failed: invalid attestation clock");
2735
2802
  return value;
2736
2803
  }
2737
- function sha256(value) {
2804
+ function sha2562(value) {
2738
2805
  return createHash3("sha256").update(value).digest("hex");
2739
2806
  }
2740
2807
  function adapterServerConfigHash(definition) {
2741
- return sha256(stablePiJson({
2808
+ return sha2562(stablePiJson({
2742
2809
  command: definition.command,
2743
2810
  args: definition.args,
2744
2811
  env: definition.env,
@@ -3278,17 +3345,17 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3278
3345
  if (receipt.status !== "attested" || receipt.mode !== "probe" || receipt.proxyMode !== input.proxyMode || receipt.proxyPresent !== expectedProxyPresent || receipt.effectiveSetHash !== input.effectiveSetHash || receipt.attestorSourceSha256 !== input.attestorSourceSha256 || receipt.configSha256 !== input.configSha256 || receipt.cacheSha256 !== input.cacheSha256) {
3279
3346
  throw new Error("pi_managed_mcp_effective_tools_failed: probe receipt mismatch");
3280
3347
  }
3281
- if (sha256(readFileSync3(input.configPath)) !== input.configSha256) {
3348
+ if (sha2562(readFileSync3(input.configPath)) !== input.configSha256) {
3282
3349
  throw new Error("pi_managed_mcp_effective_tools_failed: config drifted during probe");
3283
3350
  }
3284
- if (sha256(readFileSync3(input.cachePath)) !== input.cacheSha256) {
3351
+ if (sha2562(readFileSync3(input.cachePath)) !== input.cacheSha256) {
3285
3352
  throw new Error("pi_managed_mcp_effective_tools_failed: cache drifted during probe");
3286
3353
  }
3287
3354
  return {
3288
3355
  effectiveToolProxyMode: receipt.proxyMode,
3289
3356
  effectiveToolProxyPresent: receipt.proxyPresent,
3290
3357
  effectiveToolSetHash: receipt.effectiveSetHash,
3291
- effectiveToolProbeDigest: sha256(stablePiJson(receipt)),
3358
+ effectiveToolProbeDigest: sha2562(stablePiJson(receipt)),
3292
3359
  effectiveToolProbeAt: receipt.attestedAt,
3293
3360
  effectiveToolBindings: receipt.effectiveToolBindings
3294
3361
  };
@@ -3370,8 +3437,8 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3370
3437
  };
3371
3438
  writePrivateFile2(cachePath, `${JSON.stringify(cache, null, 2)}
3372
3439
  `);
3373
- const cacheSha256 = sha256(readFileSync3(cachePath));
3374
- const attestorSourceSha256 = sha256(managedPiEffectiveToolsAttestorExtensionSource());
3440
+ const cacheSha256 = sha2562(readFileSync3(cachePath));
3441
+ const attestorSourceSha256 = sha2562(managedPiEffectiveToolsAttestorExtensionSource());
3375
3442
  const manifestPath = join4(piCodingAgentDir, "effective-tools-manifest.json");
3376
3443
  const receiptPath = join4(tmp, "effective-tools-receipt.json");
3377
3444
  const manifest = {
@@ -3389,7 +3456,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3389
3456
  }))),
3390
3457
  proxyMode: mcpToolMode === MANAGED_PI_HYBRID_MCP_TOOL_MODE ? "required" : "forbidden",
3391
3458
  attestorSourceSha256,
3392
- configSha256: sha256(readFileSync3(configPath)),
3459
+ configSha256: sha2562(readFileSync3(configPath)),
3393
3460
  cacheSha256
3394
3461
  };
3395
3462
  writePrivateFile2(manifestPath, `${JSON.stringify(manifest, null, 2)}
@@ -3400,7 +3467,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3400
3467
  receiptPath,
3401
3468
  cacheSha256,
3402
3469
  configPath,
3403
- configSha256: sha256(readFileSync3(configPath)),
3470
+ configSha256: sha2562(readFileSync3(configPath)),
3404
3471
  attestorSourceSha256,
3405
3472
  effectiveSetHash: manifest.effectiveSetHash,
3406
3473
  proxyMode: manifest.proxyMode
@@ -3563,7 +3630,7 @@ ${result3.stderr ?? ""}`, "Pi", MINIMUM_PI_VERSION);
3563
3630
  sessionId: gateway.sessionId,
3564
3631
  sourcePiHome,
3565
3632
  piCodingAgentDir,
3566
- configSha256: sha256(readFileSync3(configPath))
3633
+ configSha256: sha2562(readFileSync3(configPath))
3567
3634
  };
3568
3635
  return {
3569
3636
  profileRoot,
@@ -4364,24 +4431,6 @@ function continuationText(context) {
4364
4431
  if (!body) return "";
4365
4432
  return [readString(summary.title), body].filter(Boolean).join("\n");
4366
4433
  }
4367
- function onDemandRefs(input) {
4368
- const context = asRecord(input.context);
4369
- const issue = asRecord(context.paperclipIssue);
4370
- const wake = asRecord(context.paperclipWake);
4371
- const refs = [
4372
- readString(issue.id) ? `issue:${readString(issue.id)}` : null,
4373
- ...commentRefs(context).map((id) => `comment:${id}`),
4374
- ...(Array.isArray(context.childIssueSummaries) ? context.childIssueSummaries : []).map((entry) => readString(asRecord(entry).id)).filter(Boolean).map((id) => `child_issue:${id}`),
4375
- ...(Array.isArray(wake.workProducts) ? wake.workProducts : []).map((entry) => readString(asRecord(entry).id)).filter(Boolean).map((id) => `work_product:${id}`)
4376
- ];
4377
- const unique = [...new Set(refs.filter(Boolean))];
4378
- if (unique.length === 0) return "";
4379
- return [
4380
- "Large context objects are intentionally omitted from this prompt.",
4381
- "Use managed typed read tools when more detail is required; preserve returned source and freshness metadata.",
4382
- ...unique.map((ref) => `- ${ref}`)
4383
- ].join("\n");
4384
- }
4385
4434
  function governedReadSection(context) {
4386
4435
  const reads = Array.isArray(context.governedReadResults) ? context.governedReadResults : [];
4387
4436
  if (reads.length === 0) return { content: "", provenance: [] };
@@ -4791,6 +4840,7 @@ function fixedRules(input, includeIssueLine) {
4791
4840
  "Before changing the task status to done, audit every explicit requirement in the task against the final evidence. A successful tool or document write proves delivery, not acceptance: inspect the delivered content for required sections, diagrams, tables, and factual constraints.",
4792
4841
  "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.",
4793
4842
  serverOwnedBusinessOutcomeReview ? "If any requirement is missing or cannot be verified, do not mark done or request final completion or Business Outcome review. Keep the issue in_progress with the exact gap and next owner. 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 write `in_review` or `blocked`. Human review: 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.",
4843
+ "A create_interaction result with status=pending or mustEndRun=true establishes human attention and is the final mutation of this run. End the run immediately: do not publish a Delivery Manifest, update a document or task, or submit any other mutation. Continue only in the new run created after the interaction is resolved.",
4794
4844
  DEADLINE_POSTURE_GUARD,
4795
4845
  "Do not install operating-system or user-global packages, and do not use host package managers such as brew, apt, yum, or global pip/npm installs. Use tools already available or workspace-local dependencies or virtual environments. If a required renderer or evaluator is unavailable, keep the source artifact, record the exact verification gap, and do not mutate the host.",
4796
4846
  `- command id: ${input.commandId}`,
@@ -5127,30 +5177,26 @@ function overflowDependencyRefsText(overflowRefs) {
5127
5177
  ...overflowRefs.map((ref) => `- issue ${JSON.stringify(ref.selector)}, key ${JSON.stringify(ref.key)}`)
5128
5178
  ].join("\n");
5129
5179
  }
5130
- function taskCommentRefGuidance(input) {
5180
+ function taskCommentRefGuidance(input, taskText) {
5131
5181
  if (!input.hasGovernedMcp || !readString(input.issueId)) return "";
5182
+ if (!/\[comment body (?:omitted|truncated)[^\]]*comment:[^\s\]]+\]/i.test(taskText)) return "";
5132
5183
  const call = readIssueEvidenceCommentCallText(input.issueId, "<id>", input);
5133
5184
  return `References like comment:<id> above mark truncated comment bodies. Fetch the full text before relying on them \u2014 ${call} (replace <id> with the referenced comment id).`;
5134
5185
  }
5135
- function piMcpProxyExamplesText(input) {
5186
+ function piMcpUsageText(input) {
5136
5187
  if (!input.hasGovernedMcp || input.executorKind !== "pi" || !managedPiMcpProxyAvailable(input) || isRecoveryWakeReason(input.wakeReason)) return "";
5137
- const hybrid = input.managedMcpToolMode === "hybrid";
5138
5188
  const proxy = (tool, args) => JSON.stringify({
5139
5189
  server: "amaster",
5140
5190
  tool,
5141
5191
  args: JSON.stringify(args)
5142
5192
  });
5143
5193
  return [
5144
- hybrid ? "For governed tools not exposed in the direct typed list, use the outer `mcp` proxy. Before the first long-tail proxy call, describe that exact canonical tool; `args` is the stringified inner canonical object and must never be object-valued." : "The Pi native tool is the outer `mcp` proxy. Emit these as actual tool calls; `args` is the stringified inner canonical object. Pi validates this string schema before extension hooks, so never send object-valued `args`:",
5194
+ "This run uses the outer `mcp` proxy for Governed MCP calls. Emit actual tool calls; `args` is the stringified inner canonical object. Pi validates this string schema before extension hooks, so never send object-valued `args`.",
5195
+ "Before the first write, describe that exact canonical action and use the returned schema; do not infer write arguments from this example.",
5145
5196
  "Keep review payload strings short. Reference the exact document key and revision in `target`; do not duplicate the reviewed document body in `prompt` or `detailsMarkdown`.",
5146
5197
  "payload.supersedesInteractionId is invalid. provenance.supersedesInteractionId is only for replacing a currently pending governed interaction; after changes_requested or rejected resolution, do not send a supersession id.",
5147
5198
  "update_parent.comment creates a separate persistent issue comment. Omit it when add_comment already recorded the message.",
5148
- ...!hybrid ? [`- describe: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`] : [],
5149
- `- submit: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-progress", action: { type: "update_parent", status: "in_progress" } })}`,
5150
- `- submit intermediate document review interaction: ${proxy("runtime_action.submit", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-review", action: { type: "create_interaction", kind: "request_confirmation", continuationPolicy: "wake_assignee_on_accept", provenance: { purposeCode: "review_document_revision", requirementRefs: ["acceptance:document_review"], attentionOwner: { kind: "board", id: "board" }, epochKey: "document_revision:22222222-2222-4222-8222-222222222222" }, payload: { version: 1, resolutionMode: "review", prompt: "Review `plan` revision 1.", target: { type: "issue_document", issueId: "11111111-1111-4111-8111-111111111111", documentId: "33333333-3333-4333-8333-333333333333", key: "plan", revisionId: "22222222-2222-4222-8222-222222222222", revisionNumber: 1 } } } })}`,
5151
- `- plan: ${proxy("runtime_action.plan", { schemaVersion: "runtime-action-v1", idempotencyKey: "task-123-plan", actions: [{ type: "update_parent", status: "in_progress" }] })}`,
5152
- `- commit the returned plan revision: ${proxy("runtime_action.commit", { schemaVersion: "runtime-action-v1", planId: "11111111-1111-4111-8111-111111111111", revision: "plan-revision-1" })}`,
5153
- ...!hybrid ? [`- read document: ${proxy("amaster.read_issue_document", { issueId: "AM-123", key: "plan" })}`] : []
5199
+ `- minimal envelope example: ${proxy("runtime_action.describe", { schemaVersion: "runtime-action-v1", actionType: "update_parent" })}`
5154
5200
  ].join("\n");
5155
5201
  }
5156
5202
  function piDirectTypedToolsText(input) {
@@ -5161,9 +5207,8 @@ function piDirectTypedToolsText(input) {
5161
5207
  return "Direct typed governed tools are unavailable because the run catalog snapshot is empty. Do not guess a proxy or tool name.";
5162
5208
  }
5163
5209
  return [
5164
- input.managedMcpToolMode === "hybrid" ? "This run exposes the attested high-frequency Governed MCP tools below as direct typed tools. Call these exact names with object arguments and do not send them through the `mcp` proxy." : "This run uses the attested direct typed Governed MCP surface below. Call these exact names with object arguments; do not call the `mcp` proxy and do not stringify an inner argument envelope.",
5165
- ...tools.map((tool) => `- ${tool.name}${tool.description ? `: ${tool.description}` : ""}`),
5166
- input.managedMcpToolMode === "hybrid" ? "For a canonical tool not listed above, use the single managed `mcp` proxy only after exact describe. Never infer an alias, use REST, or bypass the governed Gateway." : "A tool not listed above is unavailable in this run. Do not infer a namespace or fall back to REST/bare MCP."
5210
+ input.managedMcpToolMode === "hybrid" ? "Use the attested direct typed tools already present in the provider tool definitions with object arguments; do not duplicate them through the `mcp` proxy." : "Use only the attested direct typed tools already present in the provider tool definitions. Call their exact names with object arguments; do not call the `mcp` proxy and do not stringify an inner argument envelope.",
5211
+ input.managedMcpToolMode === "hybrid" ? "For a canonical tool absent from those definitions, first use the direct typed `runtime_action_describe`, then call the single managed `mcp` proxy with stringified inner `args`. Never infer an alias, use REST, or bypass the governed Gateway." : "A tool absent from the provider tool definitions is unavailable in this run. Do not infer a namespace or fall back to REST/bare MCP."
5167
5212
  ].join("\n");
5168
5213
  }
5169
5214
  function sectionText(section) {
@@ -5217,7 +5262,7 @@ var CONTEXT_AVAILABILITY_SECTION_TITLES = Object.freeze({
5217
5262
  runtime_decomposition_requirement: "Required Task Decomposition",
5218
5263
  task_context_authority: "Task Context Authority",
5219
5264
  verified_company_context: "Verified Company Context",
5220
- pi_mcp_proxy_examples: "Pi MCP Proxy Examples",
5265
+ pi_mcp_usage: "Pi Governed MCP Usage",
5221
5266
  governed_reads: "Governed External Reads",
5222
5267
  optional_task_wiki_context: "Optional Company Wiki Context",
5223
5268
  agent_instructions: "Agent Instructions",
@@ -5249,14 +5294,6 @@ function projectModelContextAvailability(manifestSections) {
5249
5294
  );
5250
5295
  coveredSections.push(...budgetOmissions);
5251
5296
  }
5252
- const rawSnapshot = bySection.get("raw_snapshot");
5253
- const onDemandRefs2 = bySection.get("on_demand_refs");
5254
- if (rawSnapshot?.omitted === true && rawSnapshot.truncationReason === "on_demand_large_object" && Number(rawSnapshot.originalChars ?? 0) > 0 && (!onDemandRefs2 || onDemandRefs2.omitted === true)) {
5255
- lines.push(
5256
- "Additional raw run context was intentionally not inlined and no managed on-demand reference was provided. Do not assume that omitted details are absent."
5257
- );
5258
- coveredSections.push("raw_snapshot");
5259
- }
5260
5297
  return {
5261
5298
  content: lines.join("\n"),
5262
5299
  coveredSections: [...new Set(coveredSections)]
@@ -5347,8 +5384,8 @@ function compileCommandPromptWithManifest(input, options = {}) {
5347
5384
  ${resolvedDependencies.details.content}` : ""
5348
5385
  ].filter(Boolean).join("\n\n") : "";
5349
5386
  const piDirectTypedTools = piDirectTypedToolsText(input);
5350
- const piMcpProxyExamples = [
5351
- resolvedDependencies.required.content ? "" : piMcpProxyExamplesText(input),
5387
+ const piMcpUsage = [
5388
+ input.managedMcpToolMode === "proxy_only" && !resolvedDependencies.required.content ? piMcpUsageText(input) : "",
5352
5389
  piDirectTypedTools
5353
5390
  ].filter(Boolean).join("\n");
5354
5391
  const deliveryReadinessContent = runtimeDeliveryReadinessText(context, input);
@@ -5358,7 +5395,7 @@ ${resolvedDependencies.details.content}` : ""
5358
5395
  { name: "recovery_instruction", title: "Recovery Instruction", priority: 100, sourceRef: `run:${input.runId ?? "unknown"}`, content: completeRecoveryInstruction, truncationReason: completeRecoveryInstruction ? null : "mode_selection" },
5359
5396
  { name: "approval_continuation", title: "Approved Runtime Action Continuation", priority: 99, sourceRef: `run:${input.runId ?? "unknown"}`, content: approvalContinuationText(input), truncationReason: mode === "continuation" ? null : "mode_selection" },
5360
5397
  { name: "wake_comments", title: wakeDeltaTitle, priority: interactionResolution ? 99 : 95, sourceRef: wakeDeltaSourceRefs, originalContent: wakeDeltaOriginal, content: wakeDeltaContent, truncationReason: commentsSelected ? null : "duplicate_task_context" },
5361
- { name: "task", title: "Task Context", priority: 90, sourceRef: `issue:${input.issueId ?? "unknown"}`, originalContent: [taskText, taskCommentRefGuidance(input)].filter(Boolean).join("\n"), content: includeTask ? [taskText, taskCommentRefGuidance(input)].filter(Boolean).join("\n") : "", truncationReason: includeTask ? null : "mode_selection" },
5398
+ { name: "task", title: "Task Context", priority: 90, sourceRef: `issue:${input.issueId ?? "unknown"}`, originalContent: [taskText, taskCommentRefGuidance(input, taskText)].filter(Boolean).join("\n"), content: includeTask ? [taskText, taskCommentRefGuidance(input, taskText)].filter(Boolean).join("\n") : "", truncationReason: includeTask ? null : "mode_selection" },
5362
5399
  ...governedBusinessState ? [{ name: "governed_business_state", title: "Governed Business State", priority: 99, ...governedBusinessState }] : [],
5363
5400
  { name: "continuation_summary", title: "Continuation Summary", priority: 97, sourceRef: readString(asRecord(context.paperclipContinuationSummary).key) ?? `issue:${input.issueId ?? "unknown"}`, observedAt: readString(asRecord(context.paperclipContinuationSummary).updatedAt), originalContent: continuationSummary, content: mode === "cold" ? "" : continuationSummary, truncationReason: mode === "cold" ? "mode_selection" : null },
5364
5401
  ...resolvedDependencyContent ? [{
@@ -5375,18 +5412,18 @@ ${resolvedDependencies.details.content}` : ""
5375
5412
  { name: "runtime_decomposition_requirement", title: "Required Task Decomposition", priority: 98, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: runtimeDecompositionRequirementText(context) },
5376
5413
  ...taskContextAuthority ? [{ name: "task_context_authority", title: "Task Context Authority", priority: 98, ...taskContextAuthority }] : [],
5377
5414
  ...verifiedCompanyContext.content ? [{ name: "verified_company_context", title: "Verified Company Context", priority: 96, sourceRef: verifiedCompanyContext.sourceRef, observedAt: verifiedCompanyContext.observedAt, freshness: { kind: "run_snapshot" }, content: verifiedCompanyContext.content }] : [],
5378
- ...piMcpProxyExamples ? [{
5379
- name: "pi_mcp_proxy_examples",
5380
- title: piDirectTypedTools ? "Pi Governed MCP Tools" : "Pi MCP Proxy Examples",
5415
+ ...piMcpUsage ? [{
5416
+ name: "pi_mcp_usage",
5417
+ title: "Pi Governed MCP Usage",
5381
5418
  priority: 96,
5382
5419
  sourceRef: "amaster_governed_mcp_proxy_contract",
5383
- content: piMcpProxyExamples
5420
+ content: piMcpUsage
5384
5421
  }] : [],
5385
5422
  { name: "governed_reads", title: "Governed External Reads", priority: 88, sourceRef: governedReads.provenance.map((entry) => entry.sourceRef), observedAt: governedReads.provenance.map((entry) => entry.observedAt), freshness: governedReads.provenance.map((entry) => entry.freshness), scope: governedReads.provenance.map((entry) => entry.scope), content: governedReads.content },
5386
5423
  ...optionalTaskWikiContext ? [optionalTaskWikiContext] : [],
5387
5424
  { name: "agent_instructions", title: "Agent Instructions", priority: 100, sourceRef: "agent_instructions_bundle", content: readString(input.agentInstructions) ?? "" },
5388
5425
  { name: "attachments", title: "Materialized Inputs", priority: 80, sourceRef: "materialized_attachments", content: readString(input.attachmentsText) ?? "" },
5389
- { name: "on_demand_refs", title: "On-demand Context References", priority: 70, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: [onDemandRefs(input), overflowDependencyRefsText(resolvedDependencies.overflowRefs)].filter(Boolean).join("\n") },
5426
+ { name: "on_demand_refs", title: "On-demand Context References", priority: 70, sourceRef: `issue:${input.issueId ?? "unknown"}`, content: overflowDependencyRefsText(resolvedDependencies.overflowRefs) },
5390
5427
  { name: "raw_snapshot", title: "Raw Context Snapshot", priority: 0, sourceRef: `run:${input.runId ?? "unknown"}`, originalChars: jsonCharLength(context), content: "", truncationReason: "on_demand_large_object" }
5391
5428
  ];
5392
5429
  const seenContent = /* @__PURE__ */ new Set();
@@ -5492,10 +5529,7 @@ function renderAgentInstructionsBundle(bundle, delivery) {
5492
5529
  ].join("\n");
5493
5530
  }
5494
5531
  if (resolvedDelivery.mode === "executor_auto_load") {
5495
- return [
5496
- materialized,
5497
- "This executor has already loaded ./AGENTS.md through its project-instruction channel. Follow it for the whole run; do not read it again merely to initialize. Read sibling instruction files only when ./AGENTS.md references them or the current task requires them."
5498
- ].join("\n");
5532
+ return "";
5499
5533
  }
5500
5534
  return [
5501
5535
  materialized,
@@ -5512,6 +5546,187 @@ function agentInstructionDeliveryAudit(bundle, delivery) {
5512
5546
  };
5513
5547
  }
5514
5548
 
5549
+ // src/amaster-runtime-daemon/agent-instruction-system-kernel-shadow.mjs
5550
+ import { createHash as createHash5 } from "node:crypto";
5551
+ var SHADOW_VERSION = 1;
5552
+ var TARGET_CHARS = 16e3;
5553
+ var USER_RESPONSE_START = "<user-facing-response>";
5554
+ var USER_RESPONSE_END = "</user-facing-response>";
5555
+ var RUNTIME_HEADING = "# AMaster Runtime Contract";
5556
+ var RUNTIME_KERNEL_SECTIONS = /* @__PURE__ */ new Set([
5557
+ "Narrow recovery and terminalization",
5558
+ "Secrets and Safety",
5559
+ "Execution continuity"
5560
+ ]);
5561
+ var ROLE_KERNEL_SECTIONS = /* @__PURE__ */ new Set([
5562
+ "How you think",
5563
+ "What you do",
5564
+ "What you do not do",
5565
+ "When you finish"
5566
+ ]);
5567
+ function sha256(value) {
5568
+ return createHash5("sha256").update(value, "utf8").digest("hex");
5569
+ }
5570
+ function normalizedText(value) {
5571
+ return typeof value === "string" ? value.trim() : "";
5572
+ }
5573
+ function sectionAudit(scope, section, disposition) {
5574
+ return {
5575
+ scope,
5576
+ heading: section.heading,
5577
+ disposition,
5578
+ chars: section.content.length,
5579
+ sha256: sha256(section.content)
5580
+ };
5581
+ }
5582
+ function splitH2Sections(content, scope) {
5583
+ const matches = [...content.matchAll(/^## (.+)$/gm)];
5584
+ const sections = [];
5585
+ const preambleEnd = matches[0]?.index ?? content.length;
5586
+ const preamble = content.slice(0, preambleEnd).trim();
5587
+ if (preamble) {
5588
+ sections.push({
5589
+ scope,
5590
+ heading: `${scope}_preamble`,
5591
+ content: preamble
5592
+ });
5593
+ }
5594
+ for (let index = 0; index < matches.length; index += 1) {
5595
+ const match = matches[index];
5596
+ const start = match.index;
5597
+ const end = matches[index + 1]?.index ?? content.length;
5598
+ const sectionContent = content.slice(start, end).trim();
5599
+ if (!sectionContent) continue;
5600
+ sections.push({
5601
+ scope,
5602
+ heading: match[1].trim(),
5603
+ content: sectionContent
5604
+ });
5605
+ }
5606
+ return sections;
5607
+ }
5608
+ function extractUserResponseContract(content) {
5609
+ const start = content.indexOf(USER_RESPONSE_START);
5610
+ if (start === -1) return null;
5611
+ const end = content.indexOf(USER_RESPONSE_END, start);
5612
+ if (end === -1) return null;
5613
+ const contentEnd = end + USER_RESPONSE_END.length;
5614
+ return {
5615
+ start,
5616
+ end: contentEnd,
5617
+ content: content.slice(start, contentEnd).trim()
5618
+ };
5619
+ }
5620
+ function splitManagedLayout(content) {
5621
+ const userResponse = extractUserResponseContract(content);
5622
+ const runtimeStart = content.indexOf(RUNTIME_HEADING);
5623
+ if (!userResponse || runtimeStart === -1 || runtimeStart < userResponse.end) return null;
5624
+ const afterRuntime = content.slice(runtimeStart);
5625
+ const parts = afterRuntime.split(/^---$/gm);
5626
+ if (parts.length < 2) return null;
5627
+ const rolePartIndex = parts.findIndex((part, index) => index > 0 && /^## (?:How you think|What you do|What you do not do|When you finish)$/m.test(part));
5628
+ if (rolePartIndex === -1) return null;
5629
+ const runtime = parts[0].trim();
5630
+ const role = parts.slice(rolePartIndex).join("\n---\n").trim();
5631
+ if (!runtime.startsWith(RUNTIME_HEADING) || !role) return null;
5632
+ return { userResponse: userResponse.content, runtime, role };
5633
+ }
5634
+ function kernelProjection(content) {
5635
+ const layout = splitManagedLayout(content);
5636
+ if (!layout) return null;
5637
+ const selected = [{
5638
+ scope: "response",
5639
+ heading: "User-Facing Response Contract",
5640
+ content: layout.userResponse
5641
+ }];
5642
+ const onDemand = [];
5643
+ for (const section of splitH2Sections(layout.runtime, "runtime")) {
5644
+ if (section.heading === "runtime_preamble" || RUNTIME_KERNEL_SECTIONS.has(section.heading)) {
5645
+ selected.push(section);
5646
+ } else {
5647
+ onDemand.push(section);
5648
+ }
5649
+ }
5650
+ for (const section of splitH2Sections(layout.role, "role")) {
5651
+ if (section.heading === "role_preamble" || ROLE_KERNEL_SECTIONS.has(section.heading)) {
5652
+ selected.push(section);
5653
+ } else {
5654
+ onDemand.push(section);
5655
+ }
5656
+ }
5657
+ return {
5658
+ candidate: selected.map((section) => section.content).join("\n\n---\n\n"),
5659
+ selected,
5660
+ onDemand
5661
+ };
5662
+ }
5663
+ function buildAgentInstructionSystemKernelShadow(bundle) {
5664
+ const bundleMode = normalizedText(bundle?.mode).toLowerCase();
5665
+ const source = normalizedText(bundle?.files?.["AGENTS.md"]);
5666
+ const base = {
5667
+ version: SHADOW_VERSION,
5668
+ mode: "shadow_only",
5669
+ activation: "disabled",
5670
+ targetChars: TARGET_CHARS,
5671
+ bundleMode: bundleMode || "unknown",
5672
+ sourceFile: source ? "AGENTS.md" : null
5673
+ };
5674
+ if (!source) {
5675
+ return {
5676
+ candidate: "",
5677
+ audit: {
5678
+ ...base,
5679
+ status: "not_applicable",
5680
+ reason: "agents_entry_not_supplied"
5681
+ }
5682
+ };
5683
+ }
5684
+ if (bundleMode !== "managed") {
5685
+ return {
5686
+ candidate: "",
5687
+ audit: {
5688
+ ...base,
5689
+ status: "not_applicable",
5690
+ reason: bundleMode === "external" ? "external_instructions_are_user_owned" : "managed_bundle_not_attested",
5691
+ sourceChars: source.length,
5692
+ sourceSha256: sha256(source)
5693
+ }
5694
+ };
5695
+ }
5696
+ const projection = kernelProjection(source);
5697
+ if (!projection) {
5698
+ return {
5699
+ candidate: "",
5700
+ audit: {
5701
+ ...base,
5702
+ status: "unavailable",
5703
+ reason: "managed_layout_not_recognized",
5704
+ sourceChars: source.length,
5705
+ sourceSha256: sha256(source)
5706
+ }
5707
+ };
5708
+ }
5709
+ const candidateChars = projection.candidate.length;
5710
+ const reductionChars = source.length - candidateChars;
5711
+ return {
5712
+ candidate: projection.candidate,
5713
+ audit: {
5714
+ ...base,
5715
+ status: "candidate_ready",
5716
+ reason: "managed_sections_classified",
5717
+ sourceChars: source.length,
5718
+ sourceSha256: sha256(source),
5719
+ candidateChars,
5720
+ candidateSha256: sha256(projection.candidate),
5721
+ reductionChars,
5722
+ reductionRatio: source.length > 0 ? Number((reductionChars / source.length).toFixed(4)) : 0,
5723
+ withinTarget: candidateChars <= TARGET_CHARS,
5724
+ selectedSections: projection.selected.map((section) => sectionAudit(section.scope, section, "kernel_candidate")),
5725
+ onDemandSections: projection.onDemand.map((section) => sectionAudit(section.scope, section, "on_demand_candidate"))
5726
+ }
5727
+ };
5728
+ }
5729
+
5515
5730
  // src/amaster-runtime-daemon/config-state.mjs
5516
5731
  import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
5517
5732
  import { homedir as homedir2, hostname } from "node:os";
@@ -5597,6 +5812,7 @@ var CAPABILITIES = [
5597
5812
  "run_wakeup",
5598
5813
  "runtime_actions_v2",
5599
5814
  "model_call",
5815
+ "model_call_output_contract_v1",
5600
5816
  "run_cancel",
5601
5817
  "run_terminate",
5602
5818
  "logs_cost_workspace_status"
@@ -6434,9 +6650,9 @@ function governedMcpToolResult(structuredContent) {
6434
6650
  const intentId = readString(effectResult.artifactIntentId);
6435
6651
  const manifestId = readString(effectResult.manifestId);
6436
6652
  const sourceRelativePath = readString(effectResult.sourceRelativePath);
6437
- const sha256 = readString(effectResult.sha256);
6653
+ const sha2562 = readString(effectResult.sha256);
6438
6654
  const byteSize = readNumber(effectResult.byteSize, 0);
6439
- const artifactIntent = providerStatus === "pending_reconcile" && intentId && manifestId && sourceRelativePath && /^[a-f0-9]{64}$/.test(sha256 ?? "") && Number.isSafeInteger(byteSize) && byteSize > 0 ? { intentId, manifestId, sourceRelativePath, sha256, byteSize } : null;
6655
+ const artifactIntent = providerStatus === "pending_reconcile" && intentId && manifestId && sourceRelativePath && /^[a-f0-9]{64}$/.test(sha2562 ?? "") && Number.isSafeInteger(byteSize) && byteSize > 0 ? { intentId, manifestId, sourceRelativePath, sha256: sha2562, byteSize } : null;
6440
6656
  const workspaceDocumentEffect = asRecord(effectResult.workspaceDocumentIntent);
6441
6657
  const workspaceDocumentCallId = readString(workspaceDocumentEffect.callId);
6442
6658
  const workspaceDocumentManifestId = readString(workspaceDocumentEffect.manifestId);
@@ -7391,7 +7607,7 @@ var postJsonWithRetry = postRuntimeConnectorJsonWithRetry;
7391
7607
  var bestEffortPostJson = bestEffortPostRuntimeConnectorJson;
7392
7608
 
7393
7609
  // src/amaster-runtime-daemon/runtime-artifact-upload.mjs
7394
- import { createHash as createHash5 } from "node:crypto";
7610
+ import { createHash as createHash6 } from "node:crypto";
7395
7611
  import { closeSync, constants, fstatSync, lstatSync as lstatSync3, openSync, readFileSync as readFileSync6, realpathSync as realpathSync3 } from "node:fs";
7396
7612
  import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
7397
7613
  var SHA256_PATTERN = /^[a-f0-9]{64}$/;
@@ -7481,7 +7697,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
7481
7697
  `Runtime Artifact ${intentId}`,
7482
7698
  { expectedByteSize }
7483
7699
  );
7484
- const actualSha256 = createHash5("sha256").update(body).digest("hex");
7700
+ const actualSha256 = createHash6("sha256").update(body).digest("hex");
7485
7701
  if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
7486
7702
  throw new Error(`Runtime Artifact ${intentId} bytes do not match the governed ownership manifest`);
7487
7703
  }
@@ -7498,7 +7714,7 @@ function prepareRuntimeArtifactUploads(cwd, mcpToolResults) {
7498
7714
  }
7499
7715
 
7500
7716
  // src/amaster-runtime-daemon/runtime-document-upload.mjs
7501
- import { createHash as createHash6 } from "node:crypto";
7717
+ import { createHash as createHash7 } from "node:crypto";
7502
7718
 
7503
7719
  // src/amaster-runtime-daemon/workspace-sensitive-path.mjs
7504
7720
  var SENSITIVE_PATH_SEGMENTS = /* @__PURE__ */ new Set([
@@ -7573,7 +7789,7 @@ function prepareRuntimeDocumentUploads(cwd, mcpToolResults) {
7573
7789
  maxByteSize: MAX_WORKSPACE_DOCUMENT_BYTES
7574
7790
  }
7575
7791
  );
7576
- const actualSha256 = createHash6("sha256").update(body).digest("hex");
7792
+ const actualSha256 = createHash7("sha256").update(body).digest("hex");
7577
7793
  if (body.length !== expectedByteSize || actualSha256 !== expectedSha256) {
7578
7794
  throw new Error(`Runtime Document ${callId} bytes do not match the governed ownership manifest`);
7579
7795
  }
@@ -7647,9 +7863,9 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
7647
7863
  let queue = Promise.resolve();
7648
7864
  const artifactIdentity = (intent) => {
7649
7865
  const sourceRelativePath = readString(asRecord(intent).sourceRelativePath);
7650
- const sha256 = readString(asRecord(intent).sha256);
7866
+ const sha2562 = readString(asRecord(intent).sha256);
7651
7867
  const byteSize = asRecord(intent).byteSize;
7652
- return sourceRelativePath && sha256 && Number.isSafeInteger(byteSize) && byteSize > 0 ? `${sourceRelativePath}\0${sha256}\0${byteSize}` : null;
7868
+ return sourceRelativePath && sha2562 && Number.isSafeInteger(byteSize) && byteSize > 0 ? `${sourceRelativePath}\0${sha2562}\0${byteSize}` : null;
7653
7869
  };
7654
7870
  const retainReceipts = (receipts) => {
7655
7871
  artifacts.push(...receipts);
@@ -7699,7 +7915,7 @@ function createRuntimeArtifactIngestQueue({ ingest, onError }) {
7699
7915
  }
7700
7916
 
7701
7917
  // src/amaster-runtime-daemon/workspace-guard.mjs
7702
- import { createHash as createHash7 } from "node:crypto";
7918
+ import { createHash as createHash8 } from "node:crypto";
7703
7919
  import { existsSync as existsSync7, mkdirSync as mkdirSync6, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
7704
7920
  import { basename as basename4, join as join8, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
7705
7921
 
@@ -7825,7 +8041,7 @@ function resolveWorkspaceCwd(config, command) {
7825
8041
  return cwd;
7826
8042
  }
7827
8043
  function shortHash(value, length = 12) {
7828
- return createHash7("sha256").update(String(value)).digest("hex").slice(0, length);
8044
+ return createHash8("sha256").update(String(value)).digest("hex").slice(0, length);
7829
8045
  }
7830
8046
  function safeSegment(value, fallback) {
7831
8047
  const raw = String(value ?? "").trim();
@@ -8269,7 +8485,7 @@ function summarizeAmasterRuntimeVersionDrift(input = {}) {
8269
8485
  }
8270
8486
 
8271
8487
  // src/amaster-runtime-daemon/pi-child-isolation.mjs
8272
- import { createHash as createHash8 } from "node:crypto";
8488
+ import { createHash as createHash9 } from "node:crypto";
8273
8489
  import {
8274
8490
  chmodSync as chmodSync3,
8275
8491
  chownSync as chownSync2,
@@ -8280,7 +8496,7 @@ import {
8280
8496
  import { resolve as resolve7, sep } from "node:path";
8281
8497
  var defaultFs = { chmodSync: chmodSync3, chownSync: chownSync2, lchownSync, lstatSync: lstatSync4, readdirSync: readdirSync6 };
8282
8498
  function defaultHashRunId(runId) {
8283
- return Number.parseInt(createHash8("sha256").update(runId).digest("hex").slice(0, 8), 16);
8499
+ return Number.parseInt(createHash9("sha256").update(runId).digest("hex").slice(0, 8), 16);
8284
8500
  }
8285
8501
  function positiveInteger(value, label) {
8286
8502
  if (!Number.isSafeInteger(value) || value <= 0) {
@@ -8404,7 +8620,7 @@ function preparePiChildIsolation(input) {
8404
8620
  }
8405
8621
 
8406
8622
  // src/amaster-runtime-daemon/pi-company-memory.mjs
8407
- import { createHash as createHash9 } from "node:crypto";
8623
+ import { createHash as createHash10 } from "node:crypto";
8408
8624
  import {
8409
8625
  chmodSync as chmodSync4,
8410
8626
  chownSync as chownSync3,
@@ -8490,7 +8706,7 @@ function safeCompanyPiHomeSegment(companyId) {
8490
8706
  const raw = requiredString3(companyId, "companyId");
8491
8707
  if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,119}$/.test(raw)) return raw;
8492
8708
  const normalized = raw.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").slice(0, 80);
8493
- const hash = createHash9("sha256").update(raw).digest("hex").slice(0, 12);
8709
+ const hash = createHash10("sha256").update(raw).digest("hex").slice(0, 12);
8494
8710
  return normalized ? `${normalized}-${hash}` : `company-${hash}`;
8495
8711
  }
8496
8712
  function ensureMemoryRoot(root, fs) {
@@ -8529,7 +8745,7 @@ function allocateCompanyGid(root, companyId, input, fs) {
8529
8745
  if (groups[companyId]) return groups[companyId];
8530
8746
  const used = new Set(Object.values(groups));
8531
8747
  const initialOffset = Number.parseInt(
8532
- createHash9("sha256").update(companyId).digest("hex").slice(0, 12),
8748
+ createHash10("sha256").update(companyId).digest("hex").slice(0, 12),
8533
8749
  16
8534
8750
  ) % gidSpan;
8535
8751
  let gid = null;
@@ -8631,7 +8847,7 @@ function prepareCompanyPiMemory(input, fs = defaultFs2) {
8631
8847
  }
8632
8848
 
8633
8849
  // src/amaster-runtime-daemon/pi-trusted-runtime-profile.mjs
8634
- import { createHash as createHash10 } from "node:crypto";
8850
+ import { createHash as createHash11 } from "node:crypto";
8635
8851
  import {
8636
8852
  chmodSync as chmodSync5,
8637
8853
  copyFileSync as copyFileSync2,
@@ -8671,7 +8887,7 @@ function sha256File(path, label) {
8671
8887
  if (!stat.isFile() || stat.isSymbolicLink()) {
8672
8888
  throw new Error(`pi_trusted_runtime_source_unsafe:${label}`);
8673
8889
  }
8674
- return createHash10("sha256").update(readFileSync9(path)).digest("hex");
8890
+ return createHash11("sha256").update(readFileSync9(path)).digest("hex");
8675
8891
  }
8676
8892
  function verifyDeclaredFiles(manifest, root, label, ignoredPaths = [], enforceComplete = true) {
8677
8893
  if (!Array.isArray(manifest.files) || manifest.files.length === 0) {
@@ -8939,12 +9155,12 @@ function materializeTrustedPiRuntimeProfile(input) {
8939
9155
  // bundle skills were enabled. Absent profile => main skills only.
8940
9156
  ...skillProfile ? {
8941
9157
  skillProfile,
8942
- enabledSkillsDigest: createHash10("sha256").update(JSON.stringify(enabledSkills)).digest("hex")
9158
+ enabledSkillsDigest: createHash11("sha256").update(JSON.stringify(enabledSkills)).digest("hex")
8943
9159
  } : {}
8944
9160
  };
8945
9161
  return {
8946
9162
  facts,
8947
- attestationId: createHash10("sha256").update(JSON.stringify(facts)).digest("hex")
9163
+ attestationId: createHash11("sha256").update(JSON.stringify(facts)).digest("hex")
8948
9164
  };
8949
9165
  }
8950
9166
  function assertAuditArgsRedacted(value) {
@@ -9140,7 +9356,7 @@ function verifyTrustedPiRuntimeAssertion(input) {
9140
9356
  if (hasSourceAssertion) {
9141
9357
  const exactTools = Array.isArray(record7(sourceProfile.tools).exactAllowlist) ? record7(sourceProfile.tools).exactAllowlist : [];
9142
9358
  const exactActions = Array.isArray(record7(sourceProfile.actions).exactAllowlist) ? record7(sourceProfile.actions).exactAllowlist : [];
9143
- const profileHash = createHash10("sha256").update(JSON.stringify(sourceProfile)).digest("hex");
9359
+ const profileHash = createHash11("sha256").update(JSON.stringify(sourceProfile)).digest("hex");
9144
9360
  if (assertion.unknownToolMode !== "deny" || maxCalls !== 0 || sourceAssertion.profileVersion !== sourceProfile.purpose || sourceAssertion.profileHash !== profileHash || sourceAssertion.retentionVersion !== sourceProfile.retention || JSON.stringify(sourceAssertion.exactTools) !== JSON.stringify(exactTools) || JSON.stringify(sourceAssertion.exactActions) !== JSON.stringify(exactActions) || sourceAssertion.sourceId !== sourceProfile.sourceId || sourceAssertion.sourceRevisionId !== sourceProfile.sourceRevisionId || sourceAssertion.sourceRevision !== sourceProfile.sourceRevision || sourceAssertion.attemptId !== sourceProfile.attemptId || sourceAssertion.epoch !== sourceProfile.epoch) {
9145
9361
  throw new Error("pi_trusted_runtime_assertion_binding_mismatch:sourceAcquisition");
9146
9362
  }
@@ -9169,7 +9385,7 @@ function verifyTrustedPiRuntimeAssertion(input) {
9169
9385
 
9170
9386
  // src/amaster-runtime-daemon/workspace-status.mjs
9171
9387
  import { spawnSync as spawnSync4 } from "node:child_process";
9172
- import { createHash as createHash11 } from "node:crypto";
9388
+ import { createHash as createHash12 } from "node:crypto";
9173
9389
  import { existsSync as existsSync12, readdirSync as readdirSync8, readFileSync as readFileSync10, statSync as statSync7 } from "node:fs";
9174
9390
  import { basename as basename5, extname, isAbsolute as isAbsolute7, join as join13, relative as relative7, resolve as resolve10 } from "node:path";
9175
9391
  var WORKSPACE_RUNTIME_SERVICES_FILENAME = ".amaster-runtime-services.json";
@@ -9240,7 +9456,7 @@ function sanitizeTrackedChange(line) {
9240
9456
  return isSafeRelativePath(path) ? line : null;
9241
9457
  }
9242
9458
  function sha256File2(filePath) {
9243
- return createHash11("sha256").update(readFileSync10(filePath)).digest("hex");
9459
+ return createHash12("sha256").update(readFileSync10(filePath)).digest("hex");
9244
9460
  }
9245
9461
  function artifactHashCacheKey(relativePath, stat) {
9246
9462
  return `${relativePath}\0${stat.size}\0${stat.mtimeMs}`;
@@ -9441,7 +9657,7 @@ function readWorkspaceStatus(cwd, opts = {}) {
9441
9657
  }
9442
9658
 
9443
9659
  // src/amaster-runtime-daemon/pi-browser-session-adapter.mjs
9444
- import { createHash as createHash12 } from "node:crypto";
9660
+ import { createHash as createHash13 } from "node:crypto";
9445
9661
  import { spawn, spawnSync as spawnSync5 } from "node:child_process";
9446
9662
  import { existsSync as existsSync13 } from "node:fs";
9447
9663
  import {
@@ -9564,7 +9780,7 @@ function fail(code) {
9564
9780
  throw Object.assign(new Error(code), { code });
9565
9781
  }
9566
9782
  function profileName(identity2) {
9567
- return createHash12("sha256").update(`${identity2.companyId}\0${identity2.bindingId}\0${identity2.localOpaqueRef}`).digest("hex");
9783
+ return createHash13("sha256").update(`${identity2.companyId}\0${identity2.bindingId}\0${identity2.localOpaqueRef}`).digest("hex");
9568
9784
  }
9569
9785
  function expectedMarker(identity2) {
9570
9786
  return {
@@ -9963,7 +10179,7 @@ async function executeBrowserSessionCommand(command, dependencies = {}) {
9963
10179
  }
9964
10180
 
9965
10181
  // src/amaster-runtime-daemon/source-acquisition-invocation.mjs
9966
- import { createHash as createHash13 } from "node:crypto";
10182
+ import { createHash as createHash14 } from "node:crypto";
9967
10183
  var SOURCE_ACQUISITION_PUBLIC_TOOLS = Object.freeze([
9968
10184
  "source_open",
9969
10185
  "source_snapshot",
@@ -10000,7 +10216,7 @@ function serializeSourceAcquisitionProfile(profile) {
10000
10216
  const input = Buffer.from(JSON.stringify(profile), "utf8");
10001
10217
  return {
10002
10218
  input,
10003
- sha256: createHash13("sha256").update(input).digest("hex")
10219
+ sha256: createHash14("sha256").update(input).digest("hex")
10004
10220
  };
10005
10221
  }
10006
10222
  function sourceAcquisitionManagedInputs(options) {
@@ -10036,7 +10252,7 @@ function assertSourceAcquisitionRuntimeAuthority({
10036
10252
  }
10037
10253
 
10038
10254
  // src/amaster-runtime-daemon.mjs
10039
- var CONNECTOR_VERSION = "0.1.1-beta.21";
10255
+ var CONNECTOR_VERSION = "0.1.1-beta.23";
10040
10256
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
10041
10257
  var SOURCE_ACQUISITION_CAPABILITY = "source_acquisition_v1";
10042
10258
  var SOURCE_ACQUISITION_PROFILE_VERSION = "source_acquisition_v1";
@@ -11370,7 +11586,7 @@ function sourceAcquisitionRuntimeProfile(config, command) {
11370
11586
  if (!companyId || !bindingId || !/^profile_[a-z0-9]{16,64}$/i.test(localOpaqueRef ?? "")) {
11371
11587
  throw new Error("source_acquisition_profile_invalid");
11372
11588
  }
11373
- const profileName2 = createHash14("sha256").update(`${companyId}\0${bindingId}\0${localOpaqueRef}`).digest("hex");
11589
+ const profileName2 = createHash15("sha256").update(`${companyId}\0${bindingId}\0${localOpaqueRef}`).digest("hex");
11374
11590
  const stateRoot = resolve12(config.browserSessionStateRoot);
11375
11591
  const userDataDir = resolve12(stateRoot, profileName2);
11376
11592
  if (!pathWithin2(userDataDir, stateRoot)) throw new Error("source_acquisition_browser_profile_invalid");
@@ -11541,6 +11757,7 @@ function buildCommandPrompt(command, workspace, materializedAttachments = [], op
11541
11757
  suppliedFiles: agentInstructionFileNames(agentInstructionsBundle)
11542
11758
  });
11543
11759
  const agentInstructions = renderAgentInstructionsBundle(agentInstructionsBundle, agentInstructionDelivery);
11760
+ const agentInstructionSystemKernelShadow = buildAgentInstructionSystemKernelShadow(agentInstructionsBundle);
11544
11761
  const runtimeAuth = commandRuntimeAuth(command);
11545
11762
  const hasGovernedMcp = Object.keys(asRecord(runtimeAuth.governedMcp)).length > 0;
11546
11763
  const attachmentsText = materializedAttachments.length > 0 ? [
@@ -11597,7 +11814,8 @@ function buildCommandPrompt(command, workspace, materializedAttachments = [], op
11597
11814
  agentInstructionDelivery: agentInstructionDeliveryAudit(
11598
11815
  agentInstructionsBundle,
11599
11816
  agentInstructionDelivery
11600
- )
11817
+ ),
11818
+ agentInstructionSystemKernelShadow: agentInstructionSystemKernelShadow.audit
11601
11819
  }
11602
11820
  };
11603
11821
  }
@@ -11668,7 +11886,30 @@ function copyPiModelCallConfig(sourceRoot, targetRoot, fileName, required) {
11668
11886
  copyFileSync3(source, target);
11669
11887
  chmodSync6(target, 384);
11670
11888
  }
11671
- function preparePiModelCallProfile(commandId, baseEnv) {
11889
+ function copyPiModelCallDefaults(sourceRoot, targetRoot) {
11890
+ const source = join15(sourceRoot, "settings.json");
11891
+ if (!existsSync14(source)) return;
11892
+ const sourceStat = lstatSync7(source);
11893
+ if (!sourceStat.isFile() || sourceStat.isSymbolicLink()) {
11894
+ throw new Error("pi_model_call_profile_unsafe: settings.json");
11895
+ }
11896
+ let settings;
11897
+ try {
11898
+ settings = asRecord(JSON.parse(readFileSync11(source, "utf8")));
11899
+ } catch {
11900
+ throw new Error("pi_model_call_profile_invalid: settings.json");
11901
+ }
11902
+ const defaultProvider = readString(settings.defaultProvider);
11903
+ const defaultModel = normalizePiModelId(settings.defaultModel);
11904
+ const target = join15(targetRoot, "settings.json");
11905
+ writeFileSync9(target, `${JSON.stringify({
11906
+ ...defaultProvider ? { defaultProvider } : {},
11907
+ ...defaultModel ? { defaultModel } : {}
11908
+ }, null, 2)}
11909
+ `, { mode: 384 });
11910
+ chmodSync6(target, 384);
11911
+ }
11912
+ function preparePiModelCallProfile(commandId, baseEnv, options = {}) {
11672
11913
  const sourceRoot = readString(process.env.PI_CODING_AGENT_DIR) ?? readString(process.env.PI_AGENT_HOME) ?? readString(process.env["AMASTER-CLI_CODING_AGENT_DIR"]);
11673
11914
  if (!sourceRoot) throw new Error("pi_model_call_profile_missing: source Pi home");
11674
11915
  const sourceStat = lstatSync7(sourceRoot);
@@ -11686,6 +11927,7 @@ function preparePiModelCallProfile(commandId, baseEnv) {
11686
11927
  try {
11687
11928
  copyPiModelCallConfig(sourceRoot, agentDir, "models.json", true);
11688
11929
  copyPiModelCallConfig(sourceRoot, agentDir, "auth.json", false);
11930
+ if (options.includeDefaults === true) copyPiModelCallDefaults(sourceRoot, agentDir);
11689
11931
  return {
11690
11932
  profileRoot,
11691
11933
  env: {
@@ -11721,6 +11963,16 @@ function sanitizePiExtraArgs(value) {
11721
11963
  function nativeSessionResumeEnabled(session) {
11722
11964
  return process.env.AMASTER_RUNTIME_ENABLE_NATIVE_SESSION_RESUME === "true" || readString(session.mode) === "governed_action_approval" && session.required === true;
11723
11965
  }
11966
+ function modelCallResponseContract(payload) {
11967
+ if (payload.responseContract === void 0) return null;
11968
+ const contract = asRecord(payload.responseContract);
11969
+ const maxOutputTokens = Number(contract.maxOutputTokens);
11970
+ const maxSemanticBytes = Number(contract.maxSemanticBytes);
11971
+ if (readString(contract.format) !== "json" || readString(contract.thinking) !== "off" || !Number.isSafeInteger(maxOutputTokens) || maxOutputTokens < 1 || maxOutputTokens > 131072 || !Number.isSafeInteger(maxSemanticBytes) || maxSemanticBytes < 1024 || maxSemanticBytes > 256 * 1024) {
11972
+ throw new Error("model_call_response_contract_invalid");
11973
+ }
11974
+ return { format: "json", thinking: "off", maxOutputTokens, maxSemanticBytes };
11975
+ }
11724
11976
  function resolveNativeSessionRequest(command, workspace) {
11725
11977
  const payload = asRecord(command.payload);
11726
11978
  const session = asRecord(payload.nativeSession);
@@ -11754,17 +12006,22 @@ function resolveNativeSessionRequest(command, workspace) {
11754
12006
  ...enabled && requested && sessionId && requestedCwd && !cwdMatched ? { skippedReason: "native_session_cwd_mismatch" } : {}
11755
12007
  };
11756
12008
  }
11757
- function buildExecutorInvocation(executor, command = {}, workspace = null) {
12009
+ function buildExecutorInvocation(executor, command = {}, workspace = null, options = {}) {
11758
12010
  const payload = asRecord(command.payload);
11759
12011
  if (command.commandType === "model_call") {
11760
12012
  if (executor.kind === "pi") {
11761
12013
  const args = ["--mode", "json"];
11762
- const provider = readString(payload.provider) ?? readString(process.env.AMASTER_PI_PROVIDER);
11763
- const model = readString(payload.model) ?? readString(process.env.AMASTER_PI_MODEL);
12014
+ const responseContract = options.responseContract ?? null;
12015
+ const modelTarget = asRecord(options.modelTarget);
12016
+ const provider = readString(modelTarget.provider) ?? readString(payload.provider) ?? readString(process.env.AMASTER_PI_PROVIDER);
12017
+ const configuredModel = readString(modelTarget.model) ?? readString(payload.model) ?? readString(process.env.AMASTER_PI_MODEL);
12018
+ const model = responseContract ? normalizePiModelId(configuredModel) : configuredModel;
11764
12019
  if (provider) args.push("--provider", provider);
11765
12020
  if (model) args.push("--model", model);
12021
+ if (responseContract?.thinking) args.push("--thinking", responseContract.thinking);
11766
12022
  args.push(...sanitizePiExtraArgs(process.env.AMASTER_PI_EXTRA_ARGS));
11767
12023
  args.push("--no-extensions", "--no-skills", "--no-session", "--no-tools");
12024
+ if (responseContract) args.push("--no-context-files");
11768
12025
  args.push("-p");
11769
12026
  return { command: executor.command, args, stdin: "prompt" };
11770
12027
  }
@@ -11852,7 +12109,7 @@ async function executeModelCallCommand(config, command, signal) {
11852
12109
  if (!prompt) {
11853
12110
  throw new Error("model_call command requires a prompt");
11854
12111
  }
11855
- const invocation = buildExecutorInvocation(executor, command);
12112
+ const responseContract = modelCallResponseContract(payload);
11856
12113
  const timeoutSeconds = Math.max(1, Math.min(
11857
12114
  config.executorTimeoutSeconds,
11858
12115
  readNumber(payload.timeoutSeconds, Math.min(config.executorTimeoutSeconds, 60))
@@ -11861,14 +12118,9 @@ async function executeModelCallCommand(config, command, signal) {
11861
12118
  config.executorMaxOutputBytes,
11862
12119
  readNumber(payload.maxOutputBytes, 512 * 1024)
11863
12120
  ));
11864
- await ackCommand(config, command, "spawned");
11865
- await ingestLog(config, command, "system", "info", `Starting ${executor.kind} runtime model call`, {
11866
- executorKind: executor.kind,
11867
- args: invocation.args,
11868
- purpose: readString(payload.purpose) ?? null,
11869
- promptBytes: Buffer.byteLength(prompt, "utf8")
11870
- });
11871
12121
  let piModelCallProfile = null;
12122
+ let modelTarget = null;
12123
+ let invocation = null;
11872
12124
  let execution;
11873
12125
  try {
11874
12126
  const baseEnv = buildExecutorEnv(config, command, {
@@ -11876,7 +12128,16 @@ async function executeModelCallCommand(config, command, signal) {
11876
12128
  cwd: process.cwd(),
11877
12129
  sourceWorkspacePath: process.cwd()
11878
12130
  });
11879
- piModelCallProfile = executor.kind === "pi" ? preparePiModelCallProfile(command.commandId, baseEnv) : null;
12131
+ const commandProvider = readString(payload.provider);
12132
+ const commandModel = readString(payload.model);
12133
+ const commandTargetRequested = Boolean(commandProvider || commandModel);
12134
+ const envProvider = readString(process.env.AMASTER_PI_PROVIDER);
12135
+ const envModel = readString(process.env.AMASTER_PI_MODEL);
12136
+ const envTargetRequested = Boolean(envProvider || envModel);
12137
+ const configuredTarget = commandTargetRequested ? { provider: commandProvider, model: commandModel, source: "command" } : { provider: envProvider, model: envModel, source: "runtime_env" };
12138
+ piModelCallProfile = executor.kind === "pi" ? preparePiModelCallProfile(command.commandId, baseEnv, {
12139
+ includeDefaults: Boolean(responseContract && !commandTargetRequested && !envTargetRequested)
12140
+ }) : null;
11880
12141
  if (piModelCallProfile) {
11881
12142
  await syncPiExecutorProviderConfig(
11882
12143
  config,
@@ -11884,7 +12145,29 @@ async function executeModelCallCommand(config, command, signal) {
11884
12145
  piModelCallProfile.env.PI_CODING_AGENT_DIR,
11885
12146
  resolvePiExecutorProviderConfig(config, command, baseEnv)
11886
12147
  );
12148
+ if (responseContract) {
12149
+ modelTarget = resolvePiModelCallTarget(
12150
+ piModelCallProfile.env.PI_CODING_AGENT_DIR,
12151
+ configuredTarget.provider,
12152
+ configuredTarget.model,
12153
+ configuredTarget.source
12154
+ );
12155
+ applyModelCallOutputContract(
12156
+ piModelCallProfile.env.PI_CODING_AGENT_DIR,
12157
+ modelTarget.provider,
12158
+ modelTarget.model,
12159
+ responseContract.maxOutputTokens
12160
+ );
12161
+ }
11887
12162
  }
12163
+ invocation = buildExecutorInvocation(executor, command, null, { responseContract, modelTarget });
12164
+ await ackCommand(config, command, "spawned");
12165
+ await ingestLog(config, command, "system", "info", `Starting ${executor.kind} runtime model call`, {
12166
+ executorKind: executor.kind,
12167
+ args: invocation.args,
12168
+ purpose: readString(payload.purpose) ?? null,
12169
+ promptBytes: Buffer.byteLength(prompt, "utf8")
12170
+ });
11888
12171
  execution = await runExecutor(invocation.command, invocation.args, {
11889
12172
  cwd: process.cwd(),
11890
12173
  env: piModelCallProfile?.env ?? baseEnv,
@@ -11907,9 +12190,13 @@ async function executeModelCallCommand(config, command, signal) {
11907
12190
  const hasOutputFlood = Boolean(readString(outputFlood.stream) && readNumber(outputFlood.bytes, 0) > 0);
11908
12191
  const timedOut = execution.timedOut === true;
11909
12192
  const parsed = hasOutputFlood ? { summary: "", usage: null, errorMessage: null, messages: [] } : executor.kind === "pi" ? parsePiJsonl(execution.stdout) : parseGenericOutput(execution.stdout, execution.stderr);
11910
- const summary = truncateText(parsed.summary || parsed.finalMessage || parsed.messages?.join("\n\n") || "", 8e3);
11911
- const succeeded = !hasOutputFlood && !timedOut && !execution.spawnError && execution.exitCode === 0 && !parsed.errorMessage && Boolean(summary);
11912
- const error = timedOut ? `Runtime model call timed out after ${timeoutSeconds}s` : execution.spawnError ?? parsed.errorMessage ?? (hasOutputFlood ? `Runtime model call output flood: ${readString(outputFlood.stream)} exceeded ${readNumber(outputFlood.limitBytes, 0)} bytes` : succeeded ? null : `Runtime model call exited with code ${execution.exitCode ?? "unknown"}`);
12193
+ const rawSummary = parsed.summary || parsed.finalMessage || parsed.messages?.join("\n\n") || "";
12194
+ const semanticBytes = Buffer.byteLength(rawSummary, "utf8");
12195
+ const semanticOutputExceeded = Boolean(responseContract && semanticBytes > responseContract.maxSemanticBytes);
12196
+ const summary = semanticOutputExceeded ? "" : responseContract ? rawSummary : truncateText(rawSummary, 8e3);
12197
+ const hasTerminalCompletion = !responseContract || executor.kind !== "pi" || Boolean(parsed.terminalEventType);
12198
+ const succeeded = !hasOutputFlood && !timedOut && !semanticOutputExceeded && !execution.spawnError && execution.exitCode === 0 && hasTerminalCompletion && !parsed.errorMessage && Boolean(summary);
12199
+ const error = timedOut ? `Runtime model call timed out after ${timeoutSeconds}s` : execution.spawnError ?? parsed.errorMessage ?? (hasOutputFlood ? `Runtime model call output flood: ${readString(outputFlood.stream)} exceeded ${readNumber(outputFlood.limitBytes, 0)} bytes` : semanticOutputExceeded ? `Runtime model call semantic output exceeded ${responseContract.maxSemanticBytes} bytes` : !hasTerminalCompletion ? "Runtime model call exited without a terminal provider response" : succeeded ? null : `Runtime model call exited with code ${execution.exitCode ?? "unknown"}`);
11913
12200
  await completeCommand(config, command, succeeded ? "succeeded" : "failed", {
11914
12201
  callType: "model_call",
11915
12202
  executorKind: executor.kind,
@@ -11920,7 +12207,26 @@ async function executeModelCallCommand(config, command, signal) {
11920
12207
  timedOut,
11921
12208
  summary,
11922
12209
  usage: parsed.usage,
11923
- stdout: truncateText(execution.stdout, 8e3),
12210
+ ...responseContract ? {
12211
+ driver: "pi_cli_json_v1",
12212
+ responseContract,
12213
+ ...modelTarget ? {
12214
+ provider: modelTarget.provider,
12215
+ model: modelTarget.model,
12216
+ modelTargetSource: modelTarget.source
12217
+ } : {},
12218
+ stopReason: parsed.stopReason ?? null,
12219
+ terminalEventType: parsed.terminalEventType ?? null,
12220
+ semanticBytes,
12221
+ outputBytes: Object.values(execution.outputBytes).reduce((total, bytes) => total + bytes, 0),
12222
+ outputBytesByStream: execution.outputBytes,
12223
+ retainedOutputBytes: Object.values(execution.retainedOutputBytes).reduce((total, bytes) => total + bytes, 0),
12224
+ retainedOutputBytesByStream: execution.retainedOutputBytes
12225
+ } : {},
12226
+ // Contracted model calls persist semantic output and metadata only. Pi's
12227
+ // JSONL stdout may contain provider reasoning/event content, so retaining
12228
+ // even a bounded tail would violate the response-contract data boundary.
12229
+ stdout: responseContract ? "" : truncateText(execution.stdout, 8e3),
11924
12230
  stderr: truncateText(filterExecutionStderrForResult(executor.kind, execution.stderr), 8e3),
11925
12231
  ...hasOutputFlood ? {
11926
12232
  errorCode: "model_call_output_flood",
@@ -11930,6 +12236,12 @@ async function executeModelCallCommand(config, command, signal) {
11930
12236
  bytes: readNumber(outputFlood.bytes, 0),
11931
12237
  limitBytes: readNumber(outputFlood.limitBytes, maxOutputBytes)
11932
12238
  }
12239
+ } : semanticOutputExceeded ? {
12240
+ errorCode: "model_call_semantic_output_exceeded",
12241
+ errorFamily: "validation"
12242
+ } : responseContract && !hasTerminalCompletion ? {
12243
+ errorCode: "model_call_terminal_event_missing",
12244
+ errorFamily: "provider_protocol"
11933
12245
  } : {}
11934
12246
  }, error ?? void 0);
11935
12247
  }
@@ -14202,7 +14514,7 @@ async function materializeIssueAttachments(config, command, workspace) {
14202
14514
  const body = await runtimeApiBuffer(runtimeAuth, contentPath);
14203
14515
  writeFileSync9(targetPath, body);
14204
14516
  const attachmentId = readString(attachment.id);
14205
- const actualSha256 = createHash14("sha256").update(body).digest("hex");
14517
+ const actualSha256 = createHash15("sha256").update(body).digest("hex");
14206
14518
  const lineageCandidates = lineageCandidatesByAttachmentId.get(attachmentId) ?? [];
14207
14519
  const lineage = selectAttachmentLineage(lineageCandidates, actualSha256);
14208
14520
  if (lineageCandidates.length > 0 && !lineage) {
@@ -14283,10 +14595,10 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
14283
14595
  const entry = asRecord(rawEntry);
14284
14596
  const workProductId = readString(entry.workProductId);
14285
14597
  const attachmentId = readString(entry.attachmentId);
14286
- const sha256 = readString(entry.sha256);
14598
+ const sha2562 = readString(entry.sha256);
14287
14599
  const contentPath = readString(entry.contentPath);
14288
14600
  const byteSize = readNumber(entry.byteSize, null);
14289
- if (!workProductId || !attachmentId || !/^[a-f0-9]{64}$/i.test(sha256 ?? "") || !contentPath || byteSize === null) {
14601
+ if (!workProductId || !attachmentId || !/^[a-f0-9]{64}$/i.test(sha2562 ?? "") || !contentPath || byteSize === null) {
14290
14602
  throw new Error(`artifact_input_manifest_invalid: entry ${index} is incomplete`);
14291
14603
  }
14292
14604
  const expectedContentPath = `/api/attachments/${attachmentId}/content`;
@@ -14294,10 +14606,10 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
14294
14606
  throw new Error(`artifact_input_manifest_invalid: entry ${index} contentPath does not match attachmentId`);
14295
14607
  }
14296
14608
  const body = await runtimeApiBuffer(runtimeAuth, contentPath);
14297
- const actualSha256 = createHash14("sha256").update(body).digest("hex");
14298
- if (body.byteLength !== byteSize || actualSha256 !== sha256) {
14609
+ const actualSha256 = createHash15("sha256").update(body).digest("hex");
14610
+ if (body.byteLength !== byteSize || actualSha256 !== sha2562) {
14299
14611
  throw new Error(
14300
- `artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha256} actualSha256=${actualSha256}`
14612
+ `artifact_input_integrity_mismatch: workProductId=${workProductId} expectedBytes=${byteSize} actualBytes=${body.byteLength} expectedSha256=${sha2562} actualSha256=${actualSha256}`
14301
14613
  );
14302
14614
  }
14303
14615
  const sourceDir = safeArtifactInputSourceDir(entry, index);
@@ -14327,7 +14639,7 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
14327
14639
  relativePath,
14328
14640
  contentType: readString(entry.contentType),
14329
14641
  byteSize: body.byteLength,
14330
- sha256,
14642
+ sha256: sha2562,
14331
14643
  contentPath
14332
14644
  });
14333
14645
  }
@@ -14364,7 +14676,7 @@ function safeCheckpointRelativePath(rawPath) {
14364
14676
  return normalized;
14365
14677
  }
14366
14678
  function hashFileSha256(filePath) {
14367
- return createHash14("sha256").update(readFileSync11(filePath)).digest("hex");
14679
+ return createHash15("sha256").update(readFileSync11(filePath)).digest("hex");
14368
14680
  }
14369
14681
  async function materializeIssueCheckpoint(config, command, workspace) {
14370
14682
  const checkpointDir = issueCheckpointDir(workspace);
@@ -6,7 +6,7 @@ import { basename, dirname, join, resolve } from "node:path";
6
6
  import { homedir, hostname } from "node:os";
7
7
  import { fileURLToPath } from "node:url";
8
8
 
9
- const CONNECTOR_VERSION = "0.1.1-beta.21";
9
+ const CONNECTOR_VERSION = "0.1.1-beta.23";
10
10
 
11
11
  const CAPABILITIES = [
12
12
  "remote_registration",
@@ -16,6 +16,7 @@ const CAPABILITIES = [
16
16
  "run_wakeup",
17
17
  "runtime_actions_v2",
18
18
  "model_call",
19
+ "model_call_output_contract_v1",
19
20
  "run_cancel",
20
21
  "run_terminate",
21
22
  "logs_cost_workspace_status",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/employee-runtime-connector",
3
- "version": "0.1.1-beta.21",
3
+ "version": "0.1.1-beta.23",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",