@interf/compiler 0.18.0 → 0.21.0

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.
Files changed (129) hide show
  1. package/README.md +87 -73
  2. package/dist/cli/commands/mcp.d.ts +0 -34
  3. package/dist/cli/commands/mcp.js +246 -45
  4. package/dist/cli/commands/method.js +261 -15
  5. package/dist/cli/commands/prep.js +61 -16
  6. package/dist/cli/commands/runs.js +103 -9
  7. package/dist/cli/commands/status.js +4 -2
  8. package/dist/cli/commands/test.d.ts +10 -0
  9. package/dist/cli/commands/{verify.js → test.js} +16 -18
  10. package/dist/cli/commands/web.js +82 -8
  11. package/dist/cli/commands/wizard.js +36 -37
  12. package/dist/cli/index.d.ts +2 -2
  13. package/dist/cli/index.js +3 -3
  14. package/dist/compiler-ui/404.html +1 -1
  15. package/dist/compiler-ui/__next.__PAGE__.txt +5 -5
  16. package/dist/compiler-ui/__next._full.txt +13 -12
  17. package/dist/compiler-ui/__next._head.txt +3 -3
  18. package/dist/compiler-ui/__next._index.txt +5 -4
  19. package/dist/compiler-ui/__next._tree.txt +4 -3
  20. package/dist/compiler-ui/_next/static/chunks/01646j7yi.w5a.css +1 -0
  21. package/dist/compiler-ui/_next/static/chunks/{0n51hrfoufc7g.js → 02f_.8.ebn556.js} +1 -1
  22. package/dist/compiler-ui/_next/static/chunks/02r7siaw-_p5w.js +1 -0
  23. package/dist/compiler-ui/_next/static/chunks/{08m7vf5asqlsm.js → 04d0ly-7xb~-j.js} +10 -10
  24. package/dist/compiler-ui/_next/static/chunks/0fhs9psnxqd8s.js +1 -0
  25. package/dist/compiler-ui/_next/static/chunks/0mssmhpbifj15.css +2 -0
  26. package/dist/compiler-ui/_next/static/chunks/0nypu~ddwxari.js +116 -0
  27. package/dist/compiler-ui/_next/static/chunks/0p3s8iyhgcww2.js +31 -0
  28. package/dist/compiler-ui/_next/static/chunks/0tjf-vu_rz8s0.css +1 -0
  29. package/dist/compiler-ui/_next/static/chunks/0u6p3fpbbfgtl.js +1 -0
  30. package/dist/compiler-ui/_next/static/chunks/0wpx5..8dnh0w.js +1 -0
  31. package/dist/compiler-ui/_next/static/chunks/0y0uj160p0ts~.js +1 -0
  32. package/dist/compiler-ui/_next/static/chunks/10t8l~_oenf.c.js +1 -0
  33. package/dist/compiler-ui/_next/static/chunks/13gz9e7z~imx1.js +5 -0
  34. package/dist/compiler-ui/_next/static/chunks/156xed-b6czaw.js +1 -0
  35. package/dist/compiler-ui/_next/static/chunks/{turbopack-0.uq1k8c0j4s..js → turbopack-02-3e_c-yz~5g.js} +1 -1
  36. package/dist/compiler-ui/_next/static/chunks/{turbopack-10e~t1yzi4svj.js → turbopack-0apv8vb-nczuy.js} +1 -1
  37. package/dist/compiler-ui/_not-found/__next._full.txt +10 -9
  38. package/dist/compiler-ui/_not-found/__next._head.txt +3 -3
  39. package/dist/compiler-ui/_not-found/__next._index.txt +5 -4
  40. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +2 -2
  41. package/dist/compiler-ui/_not-found/__next._not-found.txt +3 -3
  42. package/dist/compiler-ui/_not-found/__next._tree.txt +3 -2
  43. package/dist/compiler-ui/_not-found.html +1 -1
  44. package/dist/compiler-ui/_not-found.txt +10 -9
  45. package/dist/compiler-ui/index.html +1 -1
  46. package/dist/compiler-ui/index.txt +13 -12
  47. package/dist/packages/contracts/lib/schema.d.ts +4 -0
  48. package/dist/packages/contracts/lib/schema.js +2 -1
  49. package/dist/packages/engine/action-definitions.d.ts +174 -13
  50. package/dist/packages/engine/action-definitions.js +125 -122
  51. package/dist/packages/engine/action-planner.js +4 -11
  52. package/dist/packages/engine/agents/lib/shells.d.ts +3 -1
  53. package/dist/packages/engine/agents/lib/shells.js +8 -4
  54. package/dist/packages/engine/agents/role-executors.js +1 -1
  55. package/dist/packages/engine/compile/compiled-paths.js +6 -6
  56. package/dist/packages/engine/connection-config.js +1 -1
  57. package/dist/packages/engine/execution/lib/schema.d.ts +10 -0
  58. package/dist/packages/engine/instance-paths.d.ts +15 -9
  59. package/dist/packages/engine/instance-paths.js +15 -9
  60. package/dist/packages/engine/lib/schema.d.ts +686 -30
  61. package/dist/packages/engine/lib/schema.js +48 -21
  62. package/dist/packages/engine/native-run-handlers.js +10 -8
  63. package/dist/packages/engine/preparation-store.d.ts +9 -13
  64. package/dist/packages/engine/preparation-store.js +12 -0
  65. package/dist/packages/engine/requested-artifacts.d.ts +5 -0
  66. package/dist/packages/engine/requested-artifacts.js +36 -0
  67. package/dist/packages/engine/routes.d.ts +1 -1
  68. package/dist/packages/engine/routes.js +1 -1
  69. package/dist/packages/engine/run-observability.js +3 -2
  70. package/dist/packages/engine/runtime-proposal-helpers.d.ts +2 -2
  71. package/dist/packages/engine/runtime-proposal-helpers.js +5 -7
  72. package/dist/packages/engine/runtime-resource-builders.d.ts +5 -0
  73. package/dist/packages/engine/runtime-resource-builders.js +13 -2
  74. package/dist/packages/engine/runtime.d.ts +3 -1
  75. package/dist/packages/engine/runtime.js +146 -21
  76. package/dist/packages/engine/server.js +104 -52
  77. package/dist/packages/engine/verify/verify-execution.js +1 -1
  78. package/dist/packages/engine/wire-schemas.d.ts +5 -1
  79. package/dist/packages/engine/wire-schemas.js +1 -1
  80. package/dist/packages/methods/authoring/method-authoring.d.ts +3 -1
  81. package/dist/packages/methods/authoring/method-authoring.js +5 -36
  82. package/dist/packages/methods/package/builtin-compiled-method.js +1 -1
  83. package/dist/packages/methods/package/local-methods.d.ts +1 -0
  84. package/dist/packages/methods/package/local-methods.js +19 -4
  85. package/dist/packages/methods/package/method-definitions.js +1 -1
  86. package/dist/packages/project/interf-detect.js +6 -6
  87. package/dist/packages/project/lib/schema.d.ts +193 -0
  88. package/dist/packages/project/lib/schema.js +46 -1
  89. package/dist/packages/project/source-config.js +4 -0
  90. package/dist/packages/project/source-folders.js +1 -1
  91. package/package.json +7 -8
  92. package/public-repo/CONTRIBUTING.md +47 -0
  93. package/public-repo/LICENSE.md +1 -0
  94. package/public-repo/README.md +325 -0
  95. package/public-repo/SECURITY.md +67 -0
  96. package/public-repo/TRADEMARKS.md +8 -0
  97. package/{builtin-methods → public-repo/methods}/interf-default/README.md +4 -0
  98. package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/shape/SKILL.md +4 -8
  99. package/{builtin-methods → public-repo/methods}/interf-default/method.json +1 -1
  100. package/public-repo/methods/interf-default/use/query/SKILL.md +23 -0
  101. package/public-repo/plugins/README.md +9 -0
  102. package/public-repo/plugins/interf/.claude-plugin/plugin.json +21 -0
  103. package/public-repo/plugins/interf/.mcp.json +12 -0
  104. package/public-repo/plugins/interf/README.md +29 -0
  105. package/public-repo/plugins/interf/skills/interf/SKILL.md +477 -0
  106. package/public-repo/skills/interf/SKILL.md +477 -0
  107. package/agent-skills/interf-actions/SKILL.md +0 -185
  108. package/agent-skills/interf-actions/references/cli.md +0 -243
  109. package/builtin-methods/interf-default/use/query/SKILL.md +0 -28
  110. package/dist/cli/commands/verify.d.ts +0 -10
  111. package/dist/compiler-ui/_next/static/chunks/06yhdspx~ca5-.js +0 -5
  112. package/dist/compiler-ui/_next/static/chunks/06z~l3kwb891e.js +0 -1
  113. package/dist/compiler-ui/_next/static/chunks/08g7lvje.te.u.js +0 -1
  114. package/dist/compiler-ui/_next/static/chunks/0_c_tvh-cukjz.css +0 -3
  115. package/dist/compiler-ui/_next/static/chunks/0_i-3_5l9t2qe.js +0 -1
  116. package/dist/compiler-ui/_next/static/chunks/0b-ywny_j0g~0.js +0 -1
  117. package/dist/compiler-ui/_next/static/chunks/0b52v41o1gixx.js +0 -1
  118. package/dist/compiler-ui/_next/static/chunks/0f_geuwdesg_c.js +0 -114
  119. package/dist/compiler-ui/_next/static/chunks/0gpzgsv0w.q~m.js +0 -31
  120. package/dist/compiler-ui/_next/static/chunks/0ilwfezfvu6~-.js +0 -1
  121. package/dist/compiler-ui/_next/static/chunks/0xxmf45eskdt~.css +0 -1
  122. package/dist/compiler-ui/_next/static/chunks/14wtz~vq25~qq.js +0 -1
  123. /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_buildManifest.js +0 -0
  124. /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_clientMiddlewareManifest.js +0 -0
  125. /package/dist/compiler-ui/_next/static/{6qyE1u9m_oBUkvAhhoCmO → tYHMLL9oKds1yDoNYgkPV}/_ssgManifest.js +0 -0
  126. /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/structure/SKILL.md +0 -0
  127. /package/{builtin-methods → public-repo/methods}/interf-default/compile/stages/summarize/SKILL.md +0 -0
  128. /package/{builtin-methods → public-repo/methods}/interf-default/improve/SKILL.md +0 -0
  129. /package/{builtin-methods → public-repo/methods}/interf-default/method.schema.json +0 -0
@@ -16,7 +16,7 @@ import { findSourcePreparationConfig, fingerprintReadinessChecks, listSourcePrep
16
16
  import { listSourceFolderChoices, } from "../project/source-folders.js";
17
17
  import { asPreparationDataDir, preparationPortableContextPath, userMethodsRoot, preparationConfigPath, preparationMethodPackagePath, preparationMethodsRoot, } from "../contracts/lib/preparation-paths.js";
18
18
  import { getCompiledMethod, listCompiledMethodChoices, } from "../methods/package/method-definitions.js";
19
- import { computeArtifactStatuses, } from "./compile/artifact-status.js";
19
+ import { aggregateArtifactVerdict, computeArtifactStatuses, } from "./compile/artifact-status.js";
20
20
  import { JsonlBillingEventSink, buildCompilationEventsForRun, defaultBillingEventLogPath, } from "./compile/billing-events.js";
21
21
  import { methodDefinitionPath, resolveMethodPackageSourcePath, } from "../methods/package/local-methods.js";
22
22
  import { seedLocalMethodPackageFromBase, } from "../methods/package/interf-method-package.js";
@@ -30,14 +30,33 @@ import { ActionProposalApprovalRequestSchema, ActionProposalCreateRequestSchema,
30
30
  import { buildLocalServiceUrl, } from "./routes.js";
31
31
  import { MethodAuthoringActionValuesSchema, PreparationSetupActionValuesSchema, } from "./action-values.js";
32
32
  import { compileRunToObservability, jobRunToObservability, verifyRunToObservability, uniqueArtifacts, } from "./run-observability.js";
33
+ import { artifactRequirementsFromRequestedArtifacts } from "./requested-artifacts.js";
33
34
  /** TTL for `POST /v1/compile-runs` idempotency-key dedupe entries. */
34
35
  const IDEMPOTENCY_TTL_MS = 60 * 60 * 1000;
35
36
  /** Idempotency cache size at which to schedule an opportunistic prune. */
36
37
  const IDEMPOTENCY_PRUNE_THRESHOLD = 64;
37
38
  const INTERRUPTED_COMPILE_RUN_MESSAGE = "Compile run interrupted because the Interf engine stopped before the run reached a terminal state.";
39
+ const INTERRUPTED_JOB_RUN_MESSAGE = "Job interrupted because the Interf engine stopped before the job reached a terminal state.";
38
40
  function isTerminalCompileRunStatus(status) {
39
41
  return status === "succeeded" || status === "failed" || status === "cancelled";
40
42
  }
43
+ function isTerminalJobStatus(status) {
44
+ return status === "succeeded" || status === "failed" || status === "cancelled";
45
+ }
46
+ function countsFromCompiledState(state) {
47
+ const counts = {};
48
+ for (const stage of Object.values(state.stages ?? {})) {
49
+ for (const [key, value] of Object.entries(stage.counts ?? {})) {
50
+ if (Number.isFinite(value))
51
+ counts[key] = Math.max(counts[key] ?? 0, value);
52
+ }
53
+ for (const [key, value] of Object.entries(stage.artifact_counts ?? {})) {
54
+ if (Number.isFinite(value))
55
+ counts[key] = Math.max(counts[key] ?? 0, value);
56
+ }
57
+ }
58
+ return counts;
59
+ }
41
60
  export class LocalServiceRuntime {
42
61
  host;
43
62
  port;
@@ -173,6 +192,7 @@ export class LocalServiceRuntime {
173
192
  };
174
193
  this.preparationContexts.set(resolved, context);
175
194
  this.finalizeInterruptedCompileRuns(resolved);
195
+ this.finalizeInterruptedJobRuns(resolved);
176
196
  this.onRegistryChanged?.();
177
197
  return context;
178
198
  }
@@ -342,6 +362,13 @@ export class LocalServiceRuntime {
342
362
  const compileRun = this.listCompileRunsForPreparation(prepDataDir, preparation.name)[0] ?? null;
343
363
  const verifyRun = this.listVerifyRunsForPreparation(prepDataDir, preparation.name)[0] ?? null;
344
364
  const readinessRun = this.readLatestReadinessRun(prepDataDir, preparation.name);
365
+ const artifactStatuses = compileRun?.artifacts ?? [];
366
+ const hasArtifactContract = artifactStatuses.length > 0;
367
+ const artifactVerdict = aggregateArtifactVerdict(artifactStatuses);
368
+ const artifactFailures = artifactStatuses.filter((artifact) => artifact.status !== "ready");
369
+ const artifactProofs = artifactStatuses.flatMap((artifact) => artifact.proofs ?? []);
370
+ const requiredArtifactProofs = artifactProofs.filter((proof) => proof.required !== false);
371
+ const passedArtifactProofs = requiredArtifactProofs.filter((proof) => proof.passed);
345
372
  const configuredChecks = preparation.checks.length;
346
373
  const currentFingerprint = configuredChecks > 0 ? fingerprintReadinessChecks(preparation.checks) : null;
347
374
  const readinessRunFingerprint = readinessRun?.checks_fingerprint ?? null;
@@ -407,13 +434,25 @@ export class LocalServiceRuntime {
407
434
  artifact_path: contextReady ? compiledPath : null,
408
435
  },
409
436
  compileCheck,
437
+ {
438
+ gate: "artifact-checks",
439
+ ok: !hasArtifactContract || artifactVerdict === "ready",
440
+ status: !hasArtifactContract
441
+ ? "not-configured"
442
+ : artifactVerdict === "ready" ? "ready" : "not-ready",
443
+ summary: !hasArtifactContract
444
+ ? "No Artifacts are declared by the selected Build Plan."
445
+ : artifactVerdict === "ready"
446
+ ? `${artifactStatuses.length} Artifact${artifactStatuses.length === 1 ? "" : "s"} ready; ${passedArtifactProofs.length}/${requiredArtifactProofs.length} required Artifact check${requiredArtifactProofs.length === 1 ? "" : "s"} passed.`
447
+ : `${artifactFailures.length} Artifact${artifactFailures.length === 1 ? "" : "s"} not ready.`,
448
+ },
410
449
  {
411
450
  gate: "readiness-checks",
412
- ok: configuredChecks > 0,
451
+ ok: true,
413
452
  status: configuredChecks > 0 ? "built" : "not-configured",
414
453
  summary: configuredChecks > 0
415
454
  ? `${configuredChecks} readiness check${configuredChecks === 1 ? "" : "s"} configured.`
416
- : "No readiness checks are configured.",
455
+ : "No optional readiness checks are configured.",
417
456
  },
418
457
  {
419
458
  gate: "checks-current",
@@ -433,10 +472,12 @@ export class LocalServiceRuntime {
433
472
  return "failed";
434
473
  if (!compileRun || !contextReady)
435
474
  return "not-built";
436
- if (configuredChecks === 0)
437
- return "not-configured";
475
+ if (hasArtifactContract && artifactVerdict !== "ready")
476
+ return "not-ready";
438
477
  if (checksStale)
439
478
  return "stale";
479
+ if (configuredChecks === 0)
480
+ return hasArtifactContract ? "ready" : "built";
440
481
  if (!contextResult)
441
482
  return "built";
442
483
  return contextResult.total > 0 && contextResult.passed === contextResult.total ? "ready" : "not-ready";
@@ -535,7 +576,7 @@ export class LocalServiceRuntime {
535
576
  // method roots. Key the cache off mtimes for the three roots; if
536
577
  // any of them changes (a new local Method, an edit to the user
537
578
  // library, etc.) the cache misses and we re-resolve.
538
- const builtinRoot = join(PACKAGE_ROOT, "builtin-methods");
579
+ const builtinRoot = join(PACKAGE_ROOT, "public-repo", "methods");
539
580
  const localRoot = preparationMethodsRoot(asPreparationDataDir(prepDataDir));
540
581
  const userRoot = userMethodsRoot();
541
582
  return this.methodListingCache.get(prepDataDir, [builtinRoot, localRoot, userRoot], () => {
@@ -550,6 +591,8 @@ export class LocalServiceRuntime {
550
591
  path: resolveMethodPackageSourcePath(prepDataDir, method.id) ?? method.id,
551
592
  label: method.label,
552
593
  hint: method.hint,
594
+ purpose: method.purpose,
595
+ inputs: method.inputs,
553
596
  source_kind: method.scope === "builtin" ? "builtin" : "local",
554
597
  built_in: method.scope === "builtin",
555
598
  active_for_preparations: activeForPreparations,
@@ -754,7 +797,10 @@ export class LocalServiceRuntime {
754
797
  }
755
798
  listRunObservability(prepDataDir) {
756
799
  return [
757
- ...this.listCompileRuns(prepDataDir).map((resource) => compileRunToObservability(resource.run)),
800
+ ...this.listCompileRuns(prepDataDir).map((resource) => compileRunToObservability({
801
+ ...resource.run,
802
+ readiness: this.getReadiness(prepDataDir, resource.run.preparation),
803
+ })),
758
804
  ...this.listVerifyRuns(prepDataDir).map(verifyRunToObservability),
759
805
  ...this.listJobs(prepDataDir).map(jobRunToObservability),
760
806
  ].sort((left, right) => {
@@ -767,7 +813,7 @@ export class LocalServiceRuntime {
767
813
  return this.listRunObservability(prepDataDir).find((run) => run.run_id === runId) ?? null;
768
814
  }
769
815
  /**
770
- * Method-scoped runs: every method-authoring or method-improvement job
816
+ * Method Activity runs: every method-authoring or method-improvement job
771
817
  * whose `method` matches `methodId`. Surfaced through
772
818
  * `GET /v1/methods/<id>/runs` so Method Detail can show the full audit
773
819
  * trail of authoring + improvement work for a Method.
@@ -966,11 +1012,16 @@ export class LocalServiceRuntime {
966
1012
  applyPreparationSetup(prepDataDir, requestValue) {
967
1013
  const request = PreparationSetupCreateRequestSchema.parse(requestValue);
968
1014
  const preparationConfig = request.preparation;
969
- const methodId = methodIdForSourcePreparationConfig(preparationConfig) ?? DEFAULT_METHOD_ID;
970
- const normalizedPreparationConfig = {
971
- ...preparationConfig,
972
- method: methodId,
973
- };
1015
+ const methodId = methodIdForSourcePreparationConfig(preparationConfig);
1016
+ if (request.setup_mode === "select-method" && !methodId) {
1017
+ throw new Error("Build Plan is required when selecting a Build Plan for a Preparation.");
1018
+ }
1019
+ const normalizedPreparationConfig = methodId
1020
+ ? { ...preparationConfig, method: methodId }
1021
+ : (() => {
1022
+ const { method: _method, ...withoutMethod } = preparationConfig;
1023
+ return withoutMethod;
1024
+ })();
974
1025
  const sourceFolderPath = resolveSourcePreparationPath(prepDataDir, normalizedPreparationConfig);
975
1026
  if (!existsSync(sourceFolderPath) || !statSync(sourceFolderPath).isDirectory()) {
976
1027
  throw new Error(`Source folder "${preparationConfig.path}" is not available.`);
@@ -989,14 +1040,16 @@ export class LocalServiceRuntime {
989
1040
  version: 1,
990
1041
  operation,
991
1042
  preparation: normalizedPreparationConfig.name,
992
- method: methodId,
1043
+ method: methodId ?? null,
993
1044
  source_folder_path: sourceFolderPath,
994
1045
  config_path: preparationConfigPath(asPreparationDataDir(prepDataDir)),
995
1046
  portable_context_path: preparationPortableContextPath(asPreparationDataDir(prepDataDir), normalizedPreparationConfig.name),
996
1047
  changed: true,
997
1048
  message: operation === "select-method"
998
- ? `Preparation ${normalizedPreparationConfig.name} now uses Method ${methodId}.`
999
- : `Preparation ${normalizedPreparationConfig.name} is saved.`,
1049
+ ? `Preparation ${normalizedPreparationConfig.name} now uses Build Plan ${methodId}.`
1050
+ : methodId
1051
+ ? `Preparation ${normalizedPreparationConfig.name} is saved with Build Plan ${methodId}.`
1052
+ : `Preparation ${normalizedPreparationConfig.name} is saved. Draft or select a Build Plan before compiling.`,
1000
1053
  });
1001
1054
  }
1002
1055
  applyPreparationChange(prepDataDir, requestValue) {
@@ -1051,7 +1104,17 @@ export class LocalServiceRuntime {
1051
1104
  });
1052
1105
  }
1053
1106
  async createMethodAuthoringRun(prepDataDir, requestValue, jobType = "method-authoring") {
1054
- const request = MethodAuthoringCreateRequestSchema.parse(requestValue);
1107
+ const parsedRequest = MethodAuthoringCreateRequestSchema.parse(requestValue);
1108
+ const savedPreparation = parsedRequest.preparation
1109
+ ? findSourcePreparationConfig(loadSourceFolderConfig(prepDataDir), parsedRequest.preparation)
1110
+ : null;
1111
+ const request = {
1112
+ ...parsedRequest,
1113
+ requested_artifacts: parsedRequest.requested_artifacts.length > 0
1114
+ ? parsedRequest.requested_artifacts
1115
+ : savedPreparation?.requested_artifacts ?? [],
1116
+ source_profile: parsedRequest.source_profile ?? savedPreparation?.source_profile ?? null,
1117
+ };
1055
1118
  const isImprovement = jobType === "method-improvement";
1056
1119
  const job = this.createJobRun(prepDataDir, {
1057
1120
  job_type: jobType,
@@ -1068,6 +1131,7 @@ export class LocalServiceRuntime {
1068
1131
  preparation: request.preparation ?? null,
1069
1132
  source_folder_path: request.source_folder_path,
1070
1133
  checks: request.checks.length,
1134
+ requested_artifacts: request.requested_artifacts.length,
1071
1135
  },
1072
1136
  },
1073
1137
  {
@@ -1077,6 +1141,7 @@ export class LocalServiceRuntime {
1077
1141
  method_id: request.method_id,
1078
1142
  label: request.label,
1079
1143
  task_prompt: request.task_prompt,
1144
+ requested_artifacts: request.requested_artifacts.length,
1080
1145
  artifact_requirements: request.artifact_requirements.length,
1081
1146
  },
1082
1147
  },
@@ -1097,6 +1162,7 @@ export class LocalServiceRuntime {
1097
1162
  preparation: request.preparation ?? null,
1098
1163
  source_folder_path: request.source_folder_path,
1099
1164
  checks: request.checks.length,
1165
+ requested_artifacts: request.requested_artifacts.length,
1100
1166
  },
1101
1167
  });
1102
1168
  this.appendJobRunEvent(prepDataDir, job.run_id, {
@@ -1106,6 +1172,7 @@ export class LocalServiceRuntime {
1106
1172
  output: {
1107
1173
  source_folder_path: request.source_folder_path,
1108
1174
  checks: request.checks.length,
1175
+ requested_artifacts: request.requested_artifacts.length,
1109
1176
  },
1110
1177
  });
1111
1178
  this.appendJobRunEvent(prepDataDir, job.run_id, {
@@ -1116,6 +1183,7 @@ export class LocalServiceRuntime {
1116
1183
  method_id: request.method_id,
1117
1184
  label: request.label,
1118
1185
  task_prompt: request.task_prompt,
1186
+ requested_artifacts: request.requested_artifacts.length,
1119
1187
  artifact_requirements: request.artifact_requirements.length,
1120
1188
  },
1121
1189
  });
@@ -1157,7 +1225,7 @@ export class LocalServiceRuntime {
1157
1225
  const compiledPath = preparationPortableContextPath(asPreparationDataDir(prepDataDir), preparationName);
1158
1226
  return byCreatedAtDesc(listJsonFiles(compileRunsRoot(compiledPath))
1159
1227
  .map(readCompileRunAt)
1160
- .filter((run) => run !== null));
1228
+ .filter((run) => run !== null)).map((run) => this.hydrateCompileRunFromRuntime(prepDataDir, compiledPath, run));
1161
1229
  }, (run) => run.run_id);
1162
1230
  }
1163
1231
  getCompileRun(prepDataDir, runId) {
@@ -1633,18 +1701,35 @@ export class LocalServiceRuntime {
1633
1701
  },
1634
1702
  });
1635
1703
  if (result.status === "updated" || result.status === "no-change") {
1704
+ let selectedPreparation = null;
1705
+ if (request.preparation) {
1706
+ const selected = this.resolvePreparationConfig(prepDataDir, request.preparation, {
1707
+ method: request.method_id,
1708
+ });
1709
+ upsertSourcePreparationConfig(prepDataDir, selected);
1710
+ this.readinessCache.invalidatePreparation(prepDataDir, selected.name);
1711
+ this.compileRunCache.invalidatePreparation(prepDataDir, selected.name);
1712
+ this.verifyRunCache.invalidatePreparation(prepDataDir, selected.name);
1713
+ this.methodListingCache.invalidate(prepDataDir);
1714
+ selectedPreparation = selected.name;
1715
+ }
1636
1716
  this.appendJobRunEvent(prepDataDir, runId, {
1637
1717
  type: "step.completed",
1638
1718
  step_id: "validate-package",
1639
- message: result.summary,
1719
+ message: selectedPreparation
1720
+ ? `${result.summary} Selected Build Plan ${request.method_id} for Preparation ${selectedPreparation}.`
1721
+ : result.summary,
1640
1722
  output: {
1641
1723
  status: result.status,
1642
1724
  validation: result.validation ?? null,
1725
+ selected_preparation: selectedPreparation,
1643
1726
  },
1644
1727
  });
1645
1728
  this.appendJobRunEvent(prepDataDir, runId, {
1646
1729
  type: "job.completed",
1647
- message: result.summary,
1730
+ message: selectedPreparation
1731
+ ? `${result.summary} Selected Build Plan ${request.method_id} for Preparation ${selectedPreparation}.`
1732
+ : result.summary,
1648
1733
  });
1649
1734
  }
1650
1735
  else {
@@ -1700,7 +1785,7 @@ export class LocalServiceRuntime {
1700
1785
  return ActionProposalPlanSchema.parse({
1701
1786
  action_type: "clarification",
1702
1787
  ...(request.preparation ? { preparation: request.preparation } : {}),
1703
- assistant_message: "No local action planner is configured for this Interf Workspace.",
1788
+ assistant_message: "No local action planner is configured for this Interf instance.",
1704
1789
  });
1705
1790
  }
1706
1791
  const preparations = listSourcePreparationConfigs(loadSourceFolderConfig(prepDataDir));
@@ -1885,6 +1970,9 @@ export class LocalServiceRuntime {
1885
1970
  hint,
1886
1971
  task_prompt: taskPrompt,
1887
1972
  checks: preparationConfig?.checks ?? [],
1973
+ requested_artifacts: preparationConfig?.requested_artifacts ?? [],
1974
+ source_profile: preparationConfig?.source_profile ?? null,
1975
+ artifact_requirements: artifactRequirementsFromRequestedArtifacts(preparationConfig?.requested_artifacts ?? []),
1888
1976
  };
1889
1977
  const commandPreview = (usePlannerText ? plan.command_preview : undefined) ??
1890
1978
  actionCommandPreview(actionType, preparationConfig?.name ?? null, methodId, proposalValues);
@@ -2002,6 +2090,9 @@ export class LocalServiceRuntime {
2002
2090
  hint,
2003
2091
  task_prompt: taskPrompt,
2004
2092
  checks: preparationConfig.checks ?? [],
2093
+ requested_artifacts: preparationConfig.requested_artifacts ?? [],
2094
+ source_profile: preparationConfig.source_profile ?? null,
2095
+ artifact_requirements: artifactRequirementsFromRequestedArtifacts(preparationConfig.requested_artifacts ?? []),
2005
2096
  };
2006
2097
  })();
2007
2098
  const title = (() => {
@@ -2108,6 +2199,12 @@ export class LocalServiceRuntime {
2108
2199
  readCompileRun(compiledPath, runId) {
2109
2200
  return readCompileRunAt(compileRunPath(compiledPath, runId));
2110
2201
  }
2202
+ hydrateCompileRunFromRuntime(prepDataDir, compiledPath, run) {
2203
+ if (!isTerminalCompileRunStatus(run.status))
2204
+ return run;
2205
+ this.refreshCompileRunFromRuntime(prepDataDir, compiledPath, run.run_id);
2206
+ return this.readCompileRun(compiledPath, run.run_id) ?? run;
2207
+ }
2111
2208
  finalizeInterruptedCompileRuns(prepDataDir) {
2112
2209
  let preparations;
2113
2210
  try {
@@ -2148,6 +2245,33 @@ export class LocalServiceRuntime {
2148
2245
  }
2149
2246
  }
2150
2247
  }
2248
+ finalizeInterruptedJobRuns(prepDataDir) {
2249
+ for (const run of this.listJobs(prepDataDir)) {
2250
+ if (isTerminalJobStatus(run.status))
2251
+ continue;
2252
+ const timestamp = createRunEventTimestamp();
2253
+ const interruptedRun = LocalJobRunResourceSchema.parse({
2254
+ ...run,
2255
+ steps: run.steps.map((step) => {
2256
+ if (step.status !== "running")
2257
+ return step;
2258
+ return {
2259
+ ...step,
2260
+ status: "failed",
2261
+ finished_at: step.finished_at ?? timestamp,
2262
+ summary: step.summary ?? INTERRUPTED_JOB_RUN_MESSAGE,
2263
+ };
2264
+ }),
2265
+ });
2266
+ this.writeJobRun(prepDataDir, applyEventToLocalJob(interruptedRun, {
2267
+ type: "job.failed",
2268
+ event_id: createRunEventId("event"),
2269
+ run_id: run.run_id,
2270
+ timestamp,
2271
+ message: INTERRUPTED_JOB_RUN_MESSAGE,
2272
+ }));
2273
+ }
2274
+ }
2151
2275
  /**
2152
2276
  * 0.17 — emit per-Artifact billing events when a compile run reaches
2153
2277
  * a terminal state. STUB FORM: writes a JSONL file alongside the run
@@ -2281,6 +2405,7 @@ export class LocalServiceRuntime {
2281
2405
  method,
2282
2406
  compiledPath,
2283
2407
  stageRuns: next.stages,
2408
+ counts: countsFromCompiledState(state),
2284
2409
  });
2285
2410
  }
2286
2411
  catch {
@@ -4,7 +4,7 @@ import { randomBytes } from "node:crypto";
4
4
  import { existsSync, statSync, readFileSync } from "node:fs";
5
5
  import { dirname, extname, join, normalize, resolve, sep } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { LOCAL_SERVICE_LOOPBACK_HOSTS, LocalServiceConfigSchema, LocalServiceDiscoverySchema, LocalServiceErrorSchema, OpenPathRequestSchema, ServiceRegistryEntrySchema, } from "./lib/schema.js";
7
+ import { LOCAL_SERVICE_LOOPBACK_HOSTS, LocalServiceConfigSchema, LocalServiceDiscoverySchema, LocalServiceErrorSchema, OpenPathRequestSchema, PreparationCreateRequestSchema, PreparationUpdateRequestSchema, ServiceRegistryEntrySchema, } from "./lib/schema.js";
8
8
  import { assertPathWithinRoot, } from "../contracts/utils/path-guards.js";
9
9
  import { createLocalServiceRuntime, } from "./runtime.js";
10
10
  import { buildLocalServiceUrl, LOCAL_SERVICE_DEFAULT_HOST, LOCAL_SERVICE_DEFAULT_PORT, LOCAL_SERVICE_ROUTES, PREPARATION_SUBRESOURCES, } from "./routes.js";
@@ -124,7 +124,7 @@ function packageRoot() {
124
124
  }
125
125
  export function resolveCompilerUiStaticRoot(rootPath = packageRoot()) {
126
126
  const distRoot = join(rootPath, "dist", "compiler-ui");
127
- const sourceExportRoot = join(rootPath, "apps", "compiler-ui", "out");
127
+ const sourceExportRoot = join(rootPath, "src", "apps", "compiler-ui", "out");
128
128
  if (existsSync(join(distRoot, "index.html")))
129
129
  return distRoot;
130
130
  if (existsSync(join(sourceExportRoot, "index.html")))
@@ -384,6 +384,78 @@ async function routeApi(req, res, runtime) {
384
384
  const method = req.method ?? "GET";
385
385
  const origin = originHeaderValue(req);
386
386
  const allowed = buildAllowedOrigins(runtime.host, runtime.port);
387
+ const prepDataDirsForInstance = () => {
388
+ const dirs = listStoredPreparations().map((prep) => prep.prepDataDir);
389
+ return dirs.length > 0 ? dirs : [runtime.rootPath];
390
+ };
391
+ const listInstanceRuns = () => {
392
+ return prepDataDirsForInstance()
393
+ .flatMap((prepDataDir) => runtime.listRunObservability(prepDataDir))
394
+ .sort((left, right) => {
395
+ const leftMs = Date.parse(left.started_at ?? left.created_at ?? left.finished_at ?? "");
396
+ const rightMs = Date.parse(right.started_at ?? right.created_at ?? right.finished_at ?? "");
397
+ return (Number.isFinite(rightMs) ? rightMs : 0) - (Number.isFinite(leftMs) ? leftMs : 0);
398
+ });
399
+ };
400
+ const findInstanceRun = (runId) => {
401
+ for (const prepDataDir of prepDataDirsForInstance()) {
402
+ const run = runtime.getRunObservability(prepDataDir, runId);
403
+ if (run)
404
+ return run;
405
+ }
406
+ return null;
407
+ };
408
+ const findInstanceJob = (runId) => {
409
+ for (const prepDataDir of prepDataDirsForInstance()) {
410
+ const job = runtime.getJob(prepDataDir, runId);
411
+ if (job)
412
+ return { job, prepDataDir };
413
+ }
414
+ return null;
415
+ };
416
+ const listInstanceMethods = () => {
417
+ const byId = new Map();
418
+ for (const prepDataDir of prepDataDirsForInstance()) {
419
+ for (const methodResource of runtime.listMethods(prepDataDir)) {
420
+ const existing = byId.get(methodResource.id);
421
+ if (!existing) {
422
+ byId.set(methodResource.id, methodResource);
423
+ continue;
424
+ }
425
+ const preferred = existing.built_in && !methodResource.built_in
426
+ ? methodResource
427
+ : existing;
428
+ byId.set(methodResource.id, {
429
+ ...preferred,
430
+ active_for_preparations: Array.from(new Set([
431
+ ...existing.active_for_preparations,
432
+ ...methodResource.active_for_preparations,
433
+ ])).sort(),
434
+ });
435
+ }
436
+ }
437
+ return [...byId.values()].sort((left, right) => left.id.localeCompare(right.id));
438
+ };
439
+ const findInstanceMethod = (methodId) => {
440
+ return listInstanceMethods().find((methodResource) => methodResource.id === methodId) ?? null;
441
+ };
442
+ const listInstanceMethodRuns = (methodId) => {
443
+ return prepDataDirsForInstance()
444
+ .flatMap((prepDataDir) => runtime.listMethodRuns(prepDataDir, methodId))
445
+ .sort((left, right) => {
446
+ const leftMs = Date.parse(left.started_at ?? left.created_at ?? left.finished_at ?? "");
447
+ const rightMs = Date.parse(right.started_at ?? right.created_at ?? right.finished_at ?? "");
448
+ return (Number.isFinite(rightMs) ? rightMs : 0) - (Number.isFinite(leftMs) ? leftMs : 0);
449
+ });
450
+ };
451
+ const resolveInstanceMethodPackageRoot = (methodId) => {
452
+ for (const prepDataDir of prepDataDirsForInstance()) {
453
+ const localPath = methodDefinitionPath(prepDataDir, methodId);
454
+ if (existsSync(join(localPath, "method.json")))
455
+ return localPath;
456
+ }
457
+ return resolveMethodPackageRoot(methodId);
458
+ };
387
459
  // CORS preflight — answered for allowed origins, refused otherwise.
388
460
  if (method === "OPTIONS") {
389
461
  if (!isOriginAllowed(origin, allowed)) {
@@ -489,32 +561,15 @@ async function routeApi(req, res, runtime) {
489
561
  // POST /v1/preparations — create a new preparation.
490
562
  if (method === "POST" && path === LOCAL_SERVICE_ROUTES.preparations) {
491
563
  try {
492
- const body = (await readJsonBody(req));
493
- if (!body || typeof body !== "object") {
494
- sendError(res, 400, "Request body must be a JSON object.");
495
- return true;
496
- }
497
- if (!body.id || typeof body.id !== "string") {
498
- sendError(res, 400, "Missing required field: id");
499
- return true;
500
- }
501
- if (!body.method_id || typeof body.method_id !== "string") {
502
- sendError(res, 400, "Missing required field: method_id");
503
- return true;
504
- }
505
- if (!body.source || typeof body.source !== "object" || !body.source.locator) {
506
- sendError(res, 400, "Missing required field: source.locator");
507
- return true;
508
- }
564
+ const body = PreparationCreateRequestSchema.parse(await readJsonBody(req));
509
565
  // TODO(cloud): activate remote-folder validator branch when the
510
566
  // cloud variant lands. The local binary only knows how to read
511
567
  // bytes from a local path; a `remote-folder` binding requires
512
568
  // the cloud variant's per-account object-storage mount layer.
513
569
  // Until then, reject any kind other than `local-folder` so the
514
570
  // wire shape and runtime stay consistent.
515
- const requestedKind = typeof body.source.kind === "string" ? body.source.kind : "local-folder";
516
- if (requestedKind !== "local-folder") {
517
- sendError(res, 400, `Unsupported source kind: ${requestedKind}. The local engine only accepts local-folder bindings; remote-folder requires the cloud variant.`);
571
+ if (body.source.kind !== "local-folder") {
572
+ sendError(res, 400, `Unsupported source kind: ${body.source.kind}. The local engine only accepts local-folder bindings; remote-folder requires the cloud variant.`);
518
573
  return true;
519
574
  }
520
575
  const stored = createStoredPreparation(runtime, {
@@ -522,6 +577,8 @@ async function routeApi(req, res, runtime) {
522
577
  source: { kind: "local-folder", locator: body.source.locator },
523
578
  method_id: body.method_id,
524
579
  about: body.about,
580
+ requested_artifacts: body.requested_artifacts,
581
+ source_profile: body.source_profile,
525
582
  checks: body.checks,
526
583
  max_attempts: body.max_attempts,
527
584
  max_loops: body.max_loops,
@@ -551,20 +608,26 @@ async function routeApi(req, res, runtime) {
551
608
  if (subPath === "") {
552
609
  // Bare /v1/preparations/{id}
553
610
  if (method === "GET") {
554
- sendJson(res, 200, preparationWireShape(storedPrep));
611
+ const preparation = runtime.getPreparation(storedPrep.prepDataDir, storedPrep.id);
612
+ sendJson(res, 200, preparation
613
+ ? {
614
+ ...preparation,
615
+ source: storedPrep.source,
616
+ about: storedPrep.about,
617
+ config_path: storedPrep.configPath,
618
+ }
619
+ : preparationWireShape(storedPrep));
555
620
  return true;
556
621
  }
557
622
  if (method === "PATCH") {
558
623
  try {
559
- const body = (await readJsonBody(req));
560
- if (!body || typeof body !== "object") {
561
- sendError(res, 400, "Request body must be a JSON object.");
562
- return true;
563
- }
624
+ const body = PreparationUpdateRequestSchema.parse(await readJsonBody(req));
564
625
  const updated = updateStoredPreparation(decodedPrepId, {
565
626
  method_id: body.method_id,
566
627
  about: body.about,
567
628
  ...(body.checks !== undefined ? { checks: body.checks } : {}),
629
+ ...(body.requested_artifacts !== undefined ? { requested_artifacts: body.requested_artifacts } : {}),
630
+ ...(body.source_profile !== undefined ? { source_profile: body.source_profile } : {}),
568
631
  });
569
632
  sendJson(res, 200, preparationWireShape(updated));
570
633
  }
@@ -582,7 +645,7 @@ async function routeApi(req, res, runtime) {
582
645
  else if (subPath === PREPARATION_SUBRESOURCES.compileRuns) {
583
646
  if (method === "POST") {
584
647
  if (!storedPrep.methodId) {
585
- sendError(res, 400, `Preparation ${storedPrep.id} has no method bound. Set one via PATCH /v1/preparations/${storedPrep.id} { "method_id": "<id>" } before compiling.`);
648
+ sendError(res, 400, `Preparation ${storedPrep.id} has no Build Plan selected. Select one via PATCH /v1/preparations/${storedPrep.id} { "method_id": "<id>" } before compiling.`);
586
649
  return true;
587
650
  }
588
651
  try {
@@ -618,7 +681,7 @@ async function routeApi(req, res, runtime) {
618
681
  else if (subPath === PREPARATION_SUBRESOURCES.verifyRuns) {
619
682
  if (method === "POST") {
620
683
  if (!storedPrep.methodId) {
621
- sendError(res, 400, `Preparation ${storedPrep.id} has no method bound. Set one via PATCH /v1/preparations/${storedPrep.id} { "method_id": "<id>" } before verifying.`);
684
+ sendError(res, 400, `Preparation ${storedPrep.id} has no Build Plan selected. Select one via PATCH /v1/preparations/${storedPrep.id} { "method_id": "<id>" } before verifying.`);
622
685
  return true;
623
686
  }
624
687
  try {
@@ -789,17 +852,12 @@ async function routeApi(req, res, runtime) {
789
852
  // Method resources — preparation-independent (workspace draft + user lib + bundled).
790
853
  // ─────────────────────────────────────────────────────────────────────────
791
854
  if (method === "GET" && path === LOCAL_SERVICE_ROUTES.methods) {
792
- // The runtime needs SOME prep data dir to discover preparation-draft methods.
793
- // Fall back to the first registered preparation (if any) so user-library
794
- // and bundled methods still surface even when no preparation has drafts.
795
- const firstPrep = listStoredPreparations()[0];
796
- sendJson(res, 200, { methods: runtime.listMethods(firstPrep?.prepDataDir ?? runtime.rootPath) });
855
+ sendJson(res, 200, { methods: listInstanceMethods() });
797
856
  return true;
798
857
  }
799
858
  const methodMatch = path.match(/^\/v1\/methods\/([^/]+)$/);
800
859
  if (method === "GET" && methodMatch?.[1]) {
801
- const firstPrep = listStoredPreparations()[0];
802
- const methodResource = runtime.getMethod(firstPrep?.prepDataDir ?? runtime.rootPath, decodeURIComponent(methodMatch[1]));
860
+ const methodResource = findInstanceMethod(decodeURIComponent(methodMatch[1]));
803
861
  if (!methodResource)
804
862
  sendError(res, 404, "Method not found.");
805
863
  else
@@ -808,8 +866,7 @@ async function routeApi(req, res, runtime) {
808
866
  }
809
867
  const methodRunsMatch = path.match(/^\/v1\/methods\/([^/]+)\/runs$/);
810
868
  if (method === "GET" && methodRunsMatch?.[1]) {
811
- const firstPrep = listStoredPreparations()[0];
812
- const runs = runtime.listMethodRuns(firstPrep?.prepDataDir ?? runtime.rootPath, decodeURIComponent(methodRunsMatch[1]));
869
+ const runs = listInstanceMethodRuns(decodeURIComponent(methodRunsMatch[1]));
813
870
  sendJson(res, 200, { runs });
814
871
  return true;
815
872
  }
@@ -834,8 +891,7 @@ async function routeApi(req, res, runtime) {
834
891
  sendError(res, 400, "File path escapes method root.");
835
892
  return true;
836
893
  }
837
- const firstPrep = listStoredPreparations()[0];
838
- const root = resolveMethodPackageRoot(methodId, firstPrep?.prepDataDir);
894
+ const root = resolveInstanceMethodPackageRoot(methodId);
839
895
  if (!root) {
840
896
  sendError(res, 404, `Method not found: ${methodId}`);
841
897
  return true;
@@ -855,14 +911,12 @@ async function routeApi(req, res, runtime) {
855
911
  // so the runtime takes a "first prep" hint to scan registered preparations.
856
912
  // ─────────────────────────────────────────────────────────────────────────
857
913
  if (method === "GET" && path === LOCAL_SERVICE_ROUTES.runs) {
858
- const firstPrep = listStoredPreparations()[0];
859
- sendJson(res, 200, { runs: runtime.listRunObservability(firstPrep?.prepDataDir ?? runtime.rootPath) });
914
+ sendJson(res, 200, { runs: listInstanceRuns() });
860
915
  return true;
861
916
  }
862
917
  const observableRunMatch = path.match(/^\/v1\/runs\/([^/]+)$/);
863
918
  if (method === "GET" && observableRunMatch?.[1]) {
864
- const firstPrep = listStoredPreparations()[0];
865
- const run = runtime.getRunObservability(firstPrep?.prepDataDir ?? runtime.rootPath, decodeURIComponent(observableRunMatch[1]));
919
+ const run = findInstanceRun(decodeURIComponent(observableRunMatch[1]));
866
920
  if (!run)
867
921
  sendError(res, 404, "Run not found.");
868
922
  else
@@ -975,18 +1029,16 @@ async function routeApi(req, res, runtime) {
975
1029
  if (jobMatch?.[1]) {
976
1030
  const runId = decodeURIComponent(jobMatch[1]);
977
1031
  const child = jobMatch[2];
978
- const firstPrep = listStoredPreparations()[0];
979
- const prepDataDir = firstPrep?.prepDataDir ?? runtime.rootPath;
1032
+ const found = findInstanceJob(runId);
980
1033
  if (method === "GET" && !child) {
981
- const job = runtime.getJob(prepDataDir, runId);
982
- if (!job)
1034
+ if (!found)
983
1035
  sendError(res, 404, "Job run not found.");
984
1036
  else
985
- sendJson(res, 200, job);
1037
+ sendJson(res, 200, found.job);
986
1038
  return true;
987
1039
  }
988
1040
  if (method === "GET" && child === "events") {
989
- const events = runtime.getJobEvents(prepDataDir, runId);
1041
+ const events = found ? runtime.getJobEvents(found.prepDataDir, runId) : null;
990
1042
  if (!events)
991
1043
  sendError(res, 404, "Job run not found.");
992
1044
  else
@@ -1118,7 +1170,7 @@ async function routeApi(req, res, runtime) {
1118
1170
  allowedRoots.push(stored.source.locator);
1119
1171
  }
1120
1172
  allowedRoots.push(userMethodsRoot());
1121
- allowedRoots.push(packageRoot()); // covers <pkg>/builtin-methods/...
1173
+ allowedRoots.push(packageRoot()); // covers <pkg>/public-repo/methods/...
1122
1174
  const openedPath = await openLocalPath(allowedRoots, body.path);
1123
1175
  sendJson(res, 202, { opened: true, path: openedPath });
1124
1176
  return true;
@@ -203,7 +203,7 @@ function buildTestQueryPrompt(target, testCase, answerPath, tracePath) {
203
203
  "Answer the check question the same way you would answer a real user inside this portable context.",
204
204
  "Prefer the Method-declared portable-context outputs before consulting source references.",
205
205
  "This sandbox is self-contained: the copied portable context has source references in `.interf/runtime/source-snapshot.json`.",
206
- "The original Interf Workspace is intentionally absent from this sandbox. Use the source locators only when the portable context needs verification.",
206
+ "The original Interf instance state is intentionally absent from this sandbox. Use the source locators only when the portable context needs verification.",
207
207
  ]
208
208
  : [
209
209
  "You are running an Interf baseline test inside an isolated source-files test shell.",