@tangle-network/agent-runtime 0.337.2 → 0.339.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 (155) hide show
  1. package/dist/{activation-DRHM55Oo.d.ts → activation-CJIIl_Ey.d.ts} +90 -22
  2. package/dist/activation-CVSFxis9.js +876 -0
  3. package/dist/activation-CVSFxis9.js.map +1 -0
  4. package/dist/agent.d.ts +4 -4
  5. package/dist/agent.js +4 -7
  6. package/dist/agent.js.map +1 -1
  7. package/dist/{bundle-BPGjESee.js → bundle-DVOhBTic.js} +2 -2
  8. package/dist/{bundle-BPGjESee.js.map → bundle-DVOhBTic.js.map} +1 -1
  9. package/dist/candidate-execution/index.d.ts +4 -63
  10. package/dist/candidate-execution/index.js +6 -146
  11. package/dist/candidate-execution/index.js.map +1 -1
  12. package/dist/content-digest-sBTLujlK.js +9 -0
  13. package/dist/content-digest-sBTLujlK.js.map +1 -0
  14. package/dist/{delegate-B-T_ZB50.js → delegate-CCWE_AkU.js} +2 -2
  15. package/dist/{delegate-B-T_ZB50.js.map → delegate-CCWE_AkU.js.map} +1 -1
  16. package/dist/{coordination-driver-BHkFVqIq.js → driver-control-acknowledgers-C53ggdJ6.js} +4520 -4442
  17. package/dist/driver-control-acknowledgers-C53ggdJ6.js.map +1 -0
  18. package/dist/{durable-file-B_eJr6Mb.js → durable-file-gNI9ILAn.js} +1 -3
  19. package/dist/durable-file-gNI9ILAn.js.map +1 -0
  20. package/dist/durable.d.ts +3 -35
  21. package/dist/durable.js +225 -229
  22. package/dist/durable.js.map +1 -1
  23. package/dist/{graph-C4RFlWAJ.js → graph-CI9JXKqO.js} +65 -18
  24. package/dist/graph-CI9JXKqO.js.map +1 -0
  25. package/dist/{graph-registry-DAI6KNXB.js → graph-registry-BnO64cn8.js} +18 -17
  26. package/dist/graph-registry-BnO64cn8.js.map +1 -0
  27. package/dist/{improvement-cycle-D1I4hQvf.js → improve-BOXTLWJ3.js} +76 -1248
  28. package/dist/improve-BOXTLWJ3.js.map +1 -0
  29. package/dist/{improvement-adapter-D5gwwoXQ.d.ts → improvement-adapter-HUt_-cWA.d.ts} +2 -20
  30. package/dist/index.d.ts +10 -207
  31. package/dist/index.js +91 -305
  32. package/dist/index.js.map +1 -1
  33. package/dist/intelligence.d.ts +10 -229
  34. package/dist/intelligence.js +506 -88
  35. package/dist/intelligence.js.map +1 -1
  36. package/dist/{jsonl-file-DBv31uPi.js → jsonl-file-C9Kde_0Z.js} +2 -2
  37. package/dist/{jsonl-file-DBv31uPi.js.map → jsonl-file-C9Kde_0Z.js.map} +1 -1
  38. package/dist/kernel.d.ts +4 -3
  39. package/dist/kernel.js +12 -13
  40. package/dist/loop-runner-CWzG1bH4.d.ts +32 -0
  41. package/dist/loop-runner-bin.d.ts +32 -2
  42. package/dist/loop-runner-bin.js +93 -1
  43. package/dist/loop-runner-bin.js.map +1 -0
  44. package/dist/loop-runner-pmPIHFVY.js +59 -0
  45. package/dist/loop-runner-pmPIHFVY.js.map +1 -0
  46. package/dist/mcp/bin.js +3 -3
  47. package/dist/mcp/bin.js.map +1 -1
  48. package/dist/mcp/index.d.ts +101 -416
  49. package/dist/mcp/index.js +122 -206
  50. package/dist/mcp/index.js.map +1 -1
  51. package/dist/mcp/memory-bin.js +231 -1
  52. package/dist/mcp/memory-bin.js.map +1 -1
  53. package/dist/model-policy-CyCUwHed.js.map +1 -1
  54. package/dist/placement.d.ts +2 -9
  55. package/dist/placement.js +1 -1
  56. package/dist/placement.js.map +1 -1
  57. package/dist/platform.d.ts +194 -2
  58. package/dist/platform.js +145 -9
  59. package/dist/platform.js.map +1 -1
  60. package/dist/{prepare-CER-ZkPp.js → prepare-bXkvPMJA.js} +1213 -710
  61. package/dist/prepare-bXkvPMJA.js.map +1 -0
  62. package/dist/{profile-gNUsHNIJ.js → profile-Dpei_Sq0.js} +89 -3
  63. package/dist/profile-Dpei_Sq0.js.map +1 -0
  64. package/dist/{profile-materialization-BnoEf1co.d.ts → profile-materialization-B1wm2SPT.d.ts} +3 -5
  65. package/dist/profiles.d.ts +2 -2
  66. package/dist/profiles.js +4 -43
  67. package/dist/profiles.js.map +1 -1
  68. package/dist/{protected-model-port-BhpQRTw-.d.ts → protected-model-port-BGgpy2r9.d.ts} +4 -30
  69. package/dist/protected-redaction-DFCeo4vg.js.map +1 -1
  70. package/dist/{provision-supervisor-DGegCUH4.js → provision-supervisor-CJ6Zz6dz.js} +13 -10
  71. package/dist/provision-supervisor-CJ6Zz6dz.js.map +1 -0
  72. package/dist/record-value-B6bwJxLa.js +12 -0
  73. package/dist/record-value-B6bwJxLa.js.map +1 -0
  74. package/dist/{run-layout-Cu8H7aeh.js → run-cancellation-C9oL62sW.js} +175 -100
  75. package/dist/run-cancellation-C9oL62sW.js.map +1 -0
  76. package/dist/{runtime-BOGpotnH.js → runtime-B2fjL9Oi.js} +2639 -3187
  77. package/dist/runtime-B2fjL9Oi.js.map +1 -0
  78. package/dist/{runtime-hooks-Bj6wJHlH.d.ts → runtime-hooks-nsqxSUFL.d.ts} +2 -6
  79. package/dist/{sandbox-profile-compat-QTkLe1Z6.js → sandbox-profile-compat-BzVBFqrz.js} +690 -699
  80. package/dist/sandbox-profile-compat-BzVBFqrz.js.map +1 -0
  81. package/dist/search-executor-zMumiak_.js +1916 -0
  82. package/dist/search-executor-zMumiak_.js.map +1 -0
  83. package/dist/{server-hZWM-G8w.js → server-_4voDNrl.js} +362 -67
  84. package/dist/server-_4voDNrl.js.map +1 -0
  85. package/dist/{search-executor-Cm1WZmL-.js → structural-rollout-DpLCXzaL.js} +1680 -3403
  86. package/dist/structural-rollout-DpLCXzaL.js.map +1 -0
  87. package/dist/{substrate-B0TYNrXn.js → substrate-CGDFTSRh.js} +2 -9
  88. package/dist/substrate-CGDFTSRh.js.map +1 -0
  89. package/dist/{supervise-CvAKVfue.js → supervise-qAwXmPtD.js} +7768 -5360
  90. package/dist/supervise-qAwXmPtD.js.map +1 -0
  91. package/dist/{supervisor-Rz8AGpYb.js → supervisor-DHrUJhEZ.js} +26301 -26964
  92. package/dist/supervisor-DHrUJhEZ.js.map +1 -0
  93. package/dist/testing.d.ts +227 -2
  94. package/dist/testing.js +13 -14
  95. package/dist/testing.js.map +1 -1
  96. package/dist/tool-loop.d.ts +1 -1
  97. package/dist/{tool-server-Dqer2M4_.js → tool-server-XV4aJwoQ.js} +2 -2
  98. package/dist/tool-server-XV4aJwoQ.js.map +1 -0
  99. package/dist/top-snapshot-CbZE1JsU.js +502 -0
  100. package/dist/top-snapshot-CbZE1JsU.js.map +1 -0
  101. package/dist/tui/bin.js +711 -1
  102. package/dist/tui/bin.js.map +1 -1
  103. package/dist/tui/index.d.ts +5 -71
  104. package/dist/tui/index.js +3 -3
  105. package/dist/{types-Dl5L4r8Z.d.ts → types-CaOXqRTq.d.ts} +16230 -17376
  106. package/dist/workspace-store/index.d.ts +2 -27
  107. package/dist/workspace-store/index.js +2 -2
  108. package/dist/workspace-store/index.js.map +1 -1
  109. package/dist/{workspace-streams-JLjh5DC6.d.ts → workspace-streams-BiS4ABah.d.ts} +19 -32
  110. package/package.json +2 -2
  111. package/skills/agent-graphs/SKILL.md +10 -3
  112. package/skills/agent-graphs/references/authoring.md +18 -0
  113. package/skills/profile-authoring/SKILL.md +3 -3
  114. package/skills/supervise/SKILL.md +2 -2
  115. package/dist/activation-BDP6Eivv.js +0 -234
  116. package/dist/activation-BDP6Eivv.js.map +0 -1
  117. package/dist/coder-yhVWbdWc.js +0 -40
  118. package/dist/coder-yhVWbdWc.js.map +0 -1
  119. package/dist/coordination-driver-BHkFVqIq.js.map +0 -1
  120. package/dist/delegation-status-CF4D0NZ_.js +0 -358
  121. package/dist/delegation-status-CF4D0NZ_.js.map +0 -1
  122. package/dist/durable-file-B_eJr6Mb.js.map +0 -1
  123. package/dist/graph-C4RFlWAJ.js.map +0 -1
  124. package/dist/graph-registry-DAI6KNXB.js.map +0 -1
  125. package/dist/improvement-cycle-D1I4hQvf.js.map +0 -1
  126. package/dist/integrations-DopfCC2a.d.ts +0 -190
  127. package/dist/integrations-dFi-ALk7.js +0 -132
  128. package/dist/integrations-dFi-ALk7.js.map +0 -1
  129. package/dist/kb-gate-C8z2juK8.d.ts +0 -80
  130. package/dist/kb-gate-DpaSwXVx.js +0 -80
  131. package/dist/kb-gate-DpaSwXVx.js.map +0 -1
  132. package/dist/loop-runner-bin-DOuBIJ2O.d.ts +0 -164
  133. package/dist/loop-runner-bin-Dv5QvYDH.js +0 -246
  134. package/dist/loop-runner-bin-Dv5QvYDH.js.map +0 -1
  135. package/dist/memory-server-DXQ8IxGR.js +0 -234
  136. package/dist/memory-server-DXQ8IxGR.js.map +0 -1
  137. package/dist/openai-tools-DoQ32vpe.js +0 -44
  138. package/dist/openai-tools-DoQ32vpe.js.map +0 -1
  139. package/dist/openai-tools-Oxk4KQrY.d.ts +0 -24
  140. package/dist/prepare-CER-ZkPp.js.map +0 -1
  141. package/dist/profile-gNUsHNIJ.js.map +0 -1
  142. package/dist/protected-model-port-BuRsviSL.js +0 -766
  143. package/dist/protected-model-port-BuRsviSL.js.map +0 -1
  144. package/dist/provision-supervisor-DGegCUH4.js.map +0 -1
  145. package/dist/run-layout-Cu8H7aeh.js.map +0 -1
  146. package/dist/runtime-BOGpotnH.js.map +0 -1
  147. package/dist/sandbox-profile-compat-QTkLe1Z6.js.map +0 -1
  148. package/dist/search-executor-Cm1WZmL-.js.map +0 -1
  149. package/dist/server-hZWM-G8w.js.map +0 -1
  150. package/dist/substrate-B0TYNrXn.js.map +0 -1
  151. package/dist/supervise-CvAKVfue.js.map +0 -1
  152. package/dist/supervisor-Rz8AGpYb.js.map +0 -1
  153. package/dist/tool-server-Dqer2M4_.js.map +0 -1
  154. package/dist/top-app-BaMw1W2z.js +0 -1212
  155. package/dist/top-app-BaMw1W2z.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { m as ValidationError } from "./errors-DodWX-cb.js";
2
- import { B as omitTopLevelDigest, F as canonicalCandidateDigest$1, I as canonicalCandidateDocument, P as canonicalCandidateBytes$1, R as embeddedCandidateArtifact, V as sha256Bytes$1, n as refuseSandboxProfileField, t as assertSandboxProfileCompatibility, z as immutableCandidateValue } from "./sandbox-profile-compat-QTkLe1Z6.js";
2
+ import { B as omitTopLevelDigest, F as canonicalCandidateDigest$1, I as canonicalCandidateDocument, P as canonicalCandidateBytes$1, R as embeddedCandidateArtifact, V as sha256Bytes$1, n as refuseSandboxProfileField, t as assertSandboxProfileCompatibility, z as immutableCandidateValue } from "./sandbox-profile-compat-BzVBFqrz.js";
3
3
  import { agentCandidateProfileActivationSchema, agentCandidateProfileSchema, agentProfileDiffSchema, agentProfileSchema, applyAgentProfileDiff } from "@tangle-network/agent-interface";
4
4
  import { posix } from "node:path";
5
5
  import { isMaterializerHarness, materializeCandidateProfile, resolvePiRuntimePaths } from "@tangle-network/agent-profile-materialize";
@@ -450,7 +450,93 @@ function shellQuote(value) {
450
450
  function unsupportedProfileField(path) {
451
451
  throw new Error(`generic AgentProfile field ${path} is not representable in a sealed candidate profile`);
452
452
  }
453
+ function buildLaunch(candidate, task, profileFlags) {
454
+ const launch = candidate.bundle.execution.launch;
455
+ if (launch.kind === "container-command") return {
456
+ executable: launch.executable,
457
+ args: [...launch.args ?? [], ...profileFlags]
458
+ };
459
+ const candidateRoot = task.executionRoots.candidateRoot;
460
+ if (!candidateRoot) throw new Error("candidate entrypoint requires a container candidate root");
461
+ const entrypoint = posix.join(candidateRoot, launch.entrypoint);
462
+ const candidateArgs = launch.args ?? [];
463
+ if (launch.interpreter) return {
464
+ executable: launch.interpreter,
465
+ args: [
466
+ {
467
+ kind: "public",
468
+ value: entrypoint
469
+ },
470
+ ...candidateArgs,
471
+ ...profileFlags
472
+ ]
473
+ };
474
+ return {
475
+ executable: entrypoint,
476
+ args: [...candidateArgs, ...profileFlags]
477
+ };
478
+ }
479
+ function modelRoutes(profile, requested) {
480
+ const routes = [{
481
+ kind: "primary",
482
+ requested
483
+ }];
484
+ if (profile.model?.small) routes.push({
485
+ kind: "small",
486
+ requested
487
+ });
488
+ for (const name of Object.keys(profile.modes ?? {}).sort()) if (profile.modes?.[name]?.model) routes.push({
489
+ kind: "mode",
490
+ name,
491
+ requested
492
+ });
493
+ for (const name of Object.keys(profile.subagents ?? {}).sort()) if (profile.subagents?.[name]?.model) routes.push({
494
+ kind: "subagent",
495
+ name,
496
+ requested
497
+ });
498
+ return routes;
499
+ }
500
+ function candidateEntrypointReceipt(candidate) {
501
+ const launch = candidate.bundle.execution.launch;
502
+ const workspace = candidate.bundle.execution.workspace;
503
+ if (launch.kind !== "candidate-entrypoint" || !workspace) return void 0;
504
+ const file = workspace.material.files.find((entry) => entry.path === launch.entrypoint);
505
+ if (!file) throw new Error("candidate entrypoint is absent from the verified workspace");
506
+ return {
507
+ path: file.path,
508
+ sha256: file.sha256,
509
+ byteLength: file.byteLength
510
+ };
511
+ }
512
+ function absoluteExecutionCwd(cwd, roots) {
513
+ const root = workspaceExecutionRoot(cwd.workspace, roots);
514
+ const absolute = cwd.path === "." ? root : posix.join(root, cwd.path);
515
+ if (absolute !== root && !absolute.startsWith(`${root}/`)) throw new Error("candidate cwd escapes its execution workspace");
516
+ return absolute;
517
+ }
518
+ function workspaceExecutionRoot(workspace, roots) {
519
+ const root = workspace === "task" ? roots.taskRoot : roots.candidateRoot;
520
+ if (!root) throw new Error(`candidate ${workspace} workspace root is missing`);
521
+ return root;
522
+ }
523
+ function exactProfileExecutorFiles(sourceFiles, expectedFiles) {
524
+ const byIdentity = new Map(sourceFiles.map((file) => [profileFileIdentity(file.root, file.relPath), file]));
525
+ if (byIdentity.size !== sourceFiles.length || sourceFiles.length !== expectedFiles.length) throw new Error("profile source files do not match the signed profile plan");
526
+ return expectedFiles.map((expected) => {
527
+ const source = byIdentity.get(profileFileIdentity(expected.root, expected.relPath));
528
+ const mode = source?.mode ?? 420;
529
+ const bytes = Buffer.from(source?.content ?? "", "utf8");
530
+ if (!source || !Number.isInteger(mode) || mode < 0 || mode > 511 || mode !== expected.mode || sha256Bytes$1(bytes) !== expected.contentSha256) throw new Error("profile source files do not match the signed profile plan");
531
+ return {
532
+ path: expected.relPath,
533
+ mode,
534
+ ...expected.root === "agent" ? { root: "agent" } : {},
535
+ bytes: Uint8Array.from(bytes)
536
+ };
537
+ });
538
+ }
453
539
  //#endregion
454
- export { assertCandidateProfileBinding as a, createAgentCandidateProfileActivation as c, omitUndefinedObjectFields as d, parseAgentCandidateProfileActivation as f, requirePublicCandidateConfigValue as g, parseExactCandidateProfile as h, applyExactAgentProfileDiff as i, freezeGenericAgentCandidateProfile as l, parseExactAgentProfileDiff as m, PI_CANDIDATE_SESSION_DIR_ENV as n, assertCandidateProfileExecutionSupport as o, parseExactAgentProfile as p, agentCandidateProfileAsAgentProfile as r, candidateProfileAgentPaths as s, PI_CANDIDATE_AGENT_DIR_ENV as t, materializeAgentCandidateProfilePlan as u };
540
+ export { parseAgentCandidateProfileActivation as _, applyExactAgentProfileDiff as a, parseExactCandidateProfile as b, buildLaunch as c, createAgentCandidateProfileActivation as d, exactProfileExecutorFiles as f, omitUndefinedObjectFields as g, modelRoutes as h, agentCandidateProfileAsAgentProfile as i, candidateEntrypointReceipt as l, materializeAgentCandidateProfilePlan as m, PI_CANDIDATE_SESSION_DIR_ENV as n, assertCandidateProfileBinding as o, freezeGenericAgentCandidateProfile as p, absoluteExecutionCwd as r, assertCandidateProfileExecutionSupport as s, PI_CANDIDATE_AGENT_DIR_ENV as t, candidateProfileAgentPaths as u, parseExactAgentProfile as v, requirePublicCandidateConfigValue as x, parseExactAgentProfileDiff as y };
455
541
 
456
- //# sourceMappingURL=profile-gNUsHNIJ.js.map
542
+ //# sourceMappingURL=profile-Dpei_Sq0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-Dpei_Sq0.js","names":["canonicalCandidateBytes","sha256Bytes","canonicalCandidateDigest"],"sources":["../src/candidate-execution/public-config.ts","../src/candidate-execution/system-prompt.ts","../src/candidate-execution/profile.ts"],"sourcesContent":["import type { AgentCandidateConfigValue } from '@tangle-network/agent-interface'\nimport { ValidationError } from '../errors'\n\n/** Candidate execution has no private secret resolver; never lower a reference to argv or env. */\nexport function requirePublicCandidateConfigValue(\n value: AgentCandidateConfigValue,\n path: string,\n): string {\n if (value.kind !== 'public') {\n throw new ValidationError(\n `candidate ${path} requires a public value; secret references are unsupported`,\n )\n }\n return value.value\n}\n","import { posix } from 'node:path'\n\nimport type {\n AgentCandidateConfigValue,\n AgentCandidateLaunch,\n} from '@tangle-network/agent-interface'\nimport type {\n AgentCandidateWorkspacePlan,\n HarnessId,\n} from '@tangle-network/agent-profile-materialize'\nimport { requirePublicCandidateConfigValue } from './public-config'\n\nconst SYSTEM_PROMPT_FILE = '.tangle/system-prompt.md'\nconst APPEND_SYSTEM_PROMPT_FILE = '.tangle/append-system-prompt.md'\n\n/**\n * One row describes the native process control for each prompt intent this adapter owns.\n * A row with no executor projection means the shared materializer already lowered the intent into\n * the signed workspace plan; this adapter still proves that the launch reaches the native binary.\n */\ninterface HarnessSystemPrompt {\n /** The native binary the launch must run for this projection to be provable. */\n readonly executable: string\n /** Apply a replacement prompt to the harness's own control. */\n readonly project: (\n plan: AgentCandidateWorkspacePlan,\n systemPrompt: string,\n systemPromptFilePath: string,\n ) => AgentCandidateWorkspacePlan\n /** Apply an addition without replacing the harness's own prompt. */\n readonly projectAppend?: (\n plan: AgentCandidateWorkspacePlan,\n appendSystemPrompt: string,\n appendSystemPromptFilePath: string,\n ) => AgentCandidateWorkspacePlan\n /** The materializer already projected replacement text into native plan files and flags. */\n readonly retainsProjectedSystemPrompt?: boolean\n /** Does caller argv already set a replacement control this projection would shadow? */\n readonly conflictsWithArgs: (values: readonly string[]) => boolean\n /** Does caller argv already set an additive control this projection would shadow? */\n readonly conflictsWithAppendArgs: (values: readonly string[]) => boolean\n}\n\nconst SYSTEM_PROMPT_FLAGS = ['--system-prompt', '--system-prompt-file'] as const\nconst APPEND_SYSTEM_PROMPT_FLAGS = [\n '--append-system-prompt',\n '--append-system-prompt-file',\n] as const\n\nfunction argsSetSystemPromptFlag(values: readonly string[]): boolean {\n return values.some((value) =>\n SYSTEM_PROMPT_FLAGS.some((flag) => value === flag || value.startsWith(`${flag}=`)),\n )\n}\n\nfunction argsSetAppendSystemPromptFlag(values: readonly string[]): boolean {\n return values.some((value) =>\n APPEND_SYSTEM_PROMPT_FLAGS.some((flag) => value === flag || value.startsWith(`${flag}=`)),\n )\n}\n\n/** Codex keys that can replace or contaminate the materializer's sealed instructions file. */\nconst CODEX_INSTRUCTION_KEYS = ['model_instructions_file', 'developer_instructions'] as const\n\nfunction argsSetCodexInstructionOverride(values: readonly string[]): boolean {\n for (let index = 0; index < values.length; index++) {\n const value = values[index]!\n const config =\n value === '-c' || value === '--config'\n ? values[index + 1]\n : value.startsWith('--config=')\n ? value.slice('--config='.length)\n : undefined\n if (\n config !== undefined &&\n CODEX_INSTRUCTION_KEYS.some((key) => config.trimStart().startsWith(`${key}=`))\n ) {\n return true\n }\n }\n return false\n}\n\nconst HARNESS_SYSTEM_PROMPTS = {\n 'claude-code': {\n executable: 'claude',\n project: (plan, systemPrompt, path) =>\n appendFlags(\n addPromptFile(plan, SYSTEM_PROMPT_FILE, systemPrompt),\n '--system-prompt-file',\n path,\n ),\n projectAppend: (plan, appendSystemPrompt, path) =>\n appendFlags(\n addPromptFile(plan, APPEND_SYSTEM_PROMPT_FILE, appendSystemPrompt),\n '--append-system-prompt-file',\n path,\n ),\n conflictsWithArgs: argsSetSystemPromptFlag,\n conflictsWithAppendArgs: argsSetAppendSystemPromptFlag,\n },\n /** OpenCode's bound primary agent is already selected by the materializer's --agent flag. */\n opencode: {\n executable: 'opencode',\n project: (plan) => plan,\n retainsProjectedSystemPrompt: true,\n conflictsWithArgs: (values) =>\n values.some((value) => value === '--agent' || value.startsWith('--agent=')),\n conflictsWithAppendArgs: argsSetAppendSystemPromptFlag,\n },\n pi: {\n executable: 'pi',\n project: (plan, systemPrompt, path) =>\n appendFlags(addPromptFile(plan, SYSTEM_PROMPT_FILE, systemPrompt), '--system-prompt', path),\n projectAppend: (plan, appendSystemPrompt, path) =>\n appendFlags(\n addPromptFile(plan, APPEND_SYSTEM_PROMPT_FILE, appendSystemPrompt),\n '--append-system-prompt',\n path,\n ),\n conflictsWithArgs: argsSetSystemPromptFlag,\n conflictsWithAppendArgs: argsSetAppendSystemPromptFlag,\n },\n prime: {\n executable: 'prime-agent',\n project: (plan, systemPrompt, path) =>\n appendFlags(addPromptFile(plan, SYSTEM_PROMPT_FILE, systemPrompt), '--system-prompt', path),\n projectAppend: (plan, appendSystemPrompt, path) =>\n appendFlags(\n addPromptFile(plan, APPEND_SYSTEM_PROMPT_FILE, appendSystemPrompt),\n '--append-system-prompt',\n path,\n ),\n conflictsWithArgs: argsSetSystemPromptFlag,\n conflictsWithAppendArgs: argsSetAppendSystemPromptFlag,\n },\n /** Gemini's file and env lowering is materializer-owned; this row supplies the launch proof. */\n gemini: {\n executable: 'gemini',\n project: (plan) => plan,\n conflictsWithArgs: argsSetSystemPromptFlag,\n conflictsWithAppendArgs: argsSetAppendSystemPromptFlag,\n },\n} as const satisfies Partial<Record<HarnessId, HarnessSystemPrompt>>\n\ninterface MaterializedPromptDelivery {\n readonly executable: string\n readonly delivered: (plan: AgentCandidateWorkspacePlan) => boolean\n readonly conflictsWithArgs: (values: readonly string[]) => boolean\n}\n\n/**\n * These controls are lowered by agent-profile-materialize into files plus launch inputs. The\n * candidate adapter does not own the spawn, so it must reject an arbitrary entrypoint even when\n * the plan has the right bytes: only the native binary can make those inputs effective.\n */\nconst MATERIALIZED_PROMPT_DELIVERIES = {\n codex: {\n executable: 'codex',\n delivered: (plan) =>\n plan.files.some((file) => file.relPath === '.codex/system-prompt.md') &&\n plan.flags.some(\n (flag) =>\n requirePublicCandidateConfigValue(flag, 'profile.flags') ===\n 'model_instructions_file=.codex/system-prompt.md',\n ),\n conflictsWithArgs: argsSetCodexInstructionOverride,\n },\n gemini: {\n executable: 'gemini',\n delivered: (plan) => {\n const env = plan.env.GEMINI_SYSTEM_MD\n return (\n plan.files.some((file) => file.relPath === '.gemini/system.md') &&\n env !== undefined &&\n requirePublicCandidateConfigValue(env, 'profile.env.GEMINI_SYSTEM_MD') === '1'\n )\n },\n conflictsWithArgs: argsSetSystemPromptFlag,\n },\n} as const satisfies Partial<Record<HarnessId, MaterializedPromptDelivery>>\n\n/** Project both prompt intents onto their distinct native process controls. */\nexport function projectCandidatePromptIntents(\n plan: AgentCandidateWorkspacePlan,\n launch: AgentCandidateLaunch,\n systemPromptFilePath: string,\n requestedSystemPrompt: string | undefined = plan.systemPrompt === undefined\n ? undefined\n : requirePublicCandidateConfigValue(plan.systemPrompt, 'profile.systemPrompt'),\n requestedAppendSystemPrompt: string | undefined = plan.appendSystemPrompt === undefined\n ? undefined\n : requirePublicCandidateConfigValue(plan.appendSystemPrompt, 'profile.appendSystemPrompt'),\n): AgentCandidateWorkspacePlan {\n const systemPrompt = plan.systemPrompt\n const appendSystemPrompt = plan.appendSystemPrompt\n const delivery = MATERIALIZED_PROMPT_DELIVERIES[\n plan.harness as keyof typeof MATERIALIZED_PROMPT_DELIVERIES\n ] as MaterializedPromptDelivery | undefined\n\n if (systemPrompt === undefined && delivery?.delivered(plan)) {\n assertProvableNativeLaunch(plan.harness, delivery.executable, launch, 'replacement')\n assertNoShadowingArgs(plan.harness, delivery.conflictsWithArgs, launch, 'replacement')\n if (requestedSystemPrompt === undefined) return plan\n return plan\n }\n\n if (requestedSystemPrompt === undefined && requestedAppendSystemPrompt === undefined) {\n return plan\n }\n\n const projection = HARNESS_SYSTEM_PROMPTS[plan.harness as keyof typeof HARNESS_SYSTEM_PROMPTS] as\n | HarnessSystemPrompt\n | undefined\n if (!projection) {\n throw new Error(`candidate system prompt has no native launch projection for ${plan.harness}`)\n }\n\n const requestedReplacement = requestedSystemPrompt !== undefined\n if (requestedReplacement && systemPrompt === undefined) {\n throw new Error(\n `profile materializer did not deliver the candidate system prompt for ${plan.harness}`,\n )\n }\n if (systemPrompt !== undefined && requestedSystemPrompt === undefined) {\n throw new Error(\n `profile materializer added an unexpected candidate system prompt for ${plan.harness}`,\n )\n }\n if (\n systemPrompt !== undefined &&\n requirePublicCandidateConfigValue(systemPrompt, 'profile.systemPrompt') !==\n requestedSystemPrompt\n ) {\n throw new Error('profile materializer changed the candidate system prompt')\n }\n if (\n appendSystemPrompt !== undefined &&\n requirePublicCandidateConfigValue(appendSystemPrompt, 'profile.appendSystemPrompt') !==\n requestedAppendSystemPrompt\n ) {\n throw new Error('profile materializer changed the candidate append system prompt')\n }\n\n const intent = requestedReplacement ? 'replacement' : 'addition'\n assertProvableNativeLaunch(plan.harness, projection.executable, launch, intent)\n const launchArgs = (launch.args ?? []).map((value, index) =>\n requirePublicCandidateConfigValue(value, `launch.args[${index}]`),\n )\n if (requestedReplacement && projection.conflictsWithArgs(launchArgs)) {\n throw new Error(\n `${plan.harness} launch arguments conflict with the candidate profile system prompt`,\n )\n }\n if (requestedAppendSystemPrompt !== undefined && projection.conflictsWithAppendArgs(launchArgs)) {\n throw new Error(\n `${plan.harness} launch arguments conflict with the candidate profile append system prompt`,\n )\n }\n\n let projected = plan\n if (systemPrompt !== undefined) {\n projected = projection.project(\n projection.retainsProjectedSystemPrompt\n ? projected\n : omitPromptIntent(projected, 'systemPrompt'),\n requirePublicCandidateConfigValue(systemPrompt, 'profile.systemPrompt'),\n systemPromptFilePath,\n )\n }\n if (appendSystemPrompt !== undefined) {\n if (!projection.projectAppend) {\n throw new Error(\n `candidate append system prompt has no native launch projection for ${plan.harness}`,\n )\n }\n projected = projection.projectAppend(\n omitPromptIntent(projected, 'appendSystemPrompt'),\n requirePublicCandidateConfigValue(appendSystemPrompt, 'profile.appendSystemPrompt'),\n posix.join(posix.dirname(systemPromptFilePath), 'append-system-prompt.md'),\n )\n }\n // The source-profile digest binds authored values. Remove executor handoff fields only after\n // converting them into native controls; materializer-owned controls remain visible in the plan.\n return projected\n}\n\nfunction assertProvableNativeLaunch(\n harness: string,\n expectedExecutable: string,\n launch: AgentCandidateLaunch,\n intent: 'replacement' | 'addition',\n): asserts launch is AgentCandidateLaunch & { kind: 'container-command' } {\n if (launch.kind !== 'container-command') {\n throw new Error(`candidate-entrypoint launch cannot prove ${harness} system-prompt ${intent}`)\n }\n if (\n launch.executable !== expectedExecutable &&\n !(\n posix.isAbsolute(launch.executable) &&\n posix.basename(launch.executable) === expectedExecutable\n )\n ) {\n throw new Error(\n `${harness} system-prompt ${intent} requires the native ${expectedExecutable} executable`,\n )\n }\n}\n\nfunction assertNoShadowingArgs(\n harness: string,\n conflictsWithArgs: (values: readonly string[]) => boolean,\n launch: Extract<AgentCandidateLaunch, { kind: 'container-command' }>,\n intent: 'replacement' | 'addition',\n): void {\n if (\n conflictsWithArgs(\n (launch.args ?? []).map((value, index) =>\n requirePublicCandidateConfigValue(value, `launch.args[${index}]`),\n ),\n )\n ) {\n throw new Error(\n `${harness} launch arguments conflict with the candidate profile ${intent === 'replacement' ? 'system' : 'append system'} prompt`,\n )\n }\n}\n\nfunction omitPromptIntent(\n plan: AgentCandidateWorkspacePlan,\n intent: 'systemPrompt' | 'appendSystemPrompt',\n): AgentCandidateWorkspacePlan {\n const projected = { ...plan }\n delete projected[intent]\n return projected\n}\n\nfunction appendFlags(\n plan: AgentCandidateWorkspacePlan,\n ...values: string[]\n): AgentCandidateWorkspacePlan {\n return {\n ...plan,\n flags: [...plan.flags, ...values.map(publicValue)],\n }\n}\n\nfunction publicValue(value: string): AgentCandidateConfigValue {\n return { kind: 'public', value }\n}\n\nfunction addPromptFile(\n plan: AgentCandidateWorkspacePlan,\n relPath: string,\n prompt: string,\n): AgentCandidateWorkspacePlan {\n // Candidate argv rejects control characters. Native prompt-file loading preserves multiline\n // bytes without weakening the shared process schema.\n if (plan.files.some((file) => file.relPath === relPath)) {\n throw new Error(`candidate profile conflicts with reserved ${relPath}`)\n }\n return {\n ...plan,\n files: [\n ...plan.files,\n {\n relPath,\n content: prompt,\n source: 'generated',\n },\n ],\n }\n}\n","import { posix } from 'node:path'\nimport type {\n AgentCandidateConfigValue,\n AgentCandidateExecutionPlanMaterial,\n AgentCandidateLaunch,\n AgentCandidateProfile,\n AgentCandidateProfileActivation,\n AgentCandidateProfilePlanEvidence,\n AgentCandidateResourceRef,\n AgentProfile,\n AgentProfileConfigValue,\n AgentProfileDiff,\n AgentProfileMcpServer,\n AgentProfileResourceRef,\n HarnessType,\n Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport {\n agentCandidateProfileActivationSchema,\n agentCandidateProfileSchema,\n agentProfileDiffSchema,\n agentProfileSchema,\n applyAgentProfileDiff,\n} from '@tangle-network/agent-interface'\nimport type {\n AgentCandidateWorkspacePlan,\n HarnessId,\n} from '@tangle-network/agent-profile-materialize'\nimport {\n isMaterializerHarness,\n materializeCandidateProfile,\n resolvePiRuntimePaths,\n} from '@tangle-network/agent-profile-materialize'\nimport {\n assertSandboxProfileCompatibility,\n refuseSandboxProfileField,\n} from '../runtime/sandbox-profile-compat'\nimport {\n canonicalCandidateBytes,\n canonicalCandidateDigest,\n canonicalCandidateDocument,\n embeddedCandidateArtifact,\n immutableCandidateValue,\n omitTopLevelDigest,\n sha256Bytes,\n} from './digest'\nimport { requirePublicCandidateConfigValue } from './public-config'\nimport { projectCandidatePromptIntents } from './system-prompt'\nimport type { AgentCandidateTaskExecution, VerifiedAgentCandidate } from './types'\n\nexport function candidateMaterializerHarness(harness: HarnessType): HarnessId {\n if (!isMaterializerHarness(harness)) {\n throw new Error(\n `sealed candidate profile materialization is unsupported for harness ${harness}`,\n )\n }\n return harness\n}\n\n/** Runtime applies the materializer's launch flags to the candidate process. */\nconst CANDIDATE_PROFILE_MATERIALIZER_BINDS = ['systemPrompt'] as const\nexport const PI_CANDIDATE_AGENT_DIR_ENV = 'PI_CODING_AGENT_DIR'\nexport const PI_CANDIDATE_SESSION_DIR_ENV = 'PI_CODING_AGENT_SESSION_DIR'\n\ninterface MaterializeAgentCandidateProfilePlanOptions {\n profile: AgentCandidateProfile\n harness: HarnessType\n launch: AgentCandidateLaunch\n workspace: 'task' | 'candidate'\n workspaces: {\n taskRoot: string\n candidateRoot?: string\n }\n resolvedResources?: ReadonlyMap<Sha256Digest, string>\n}\n\n/** Derive the exact native profile plan used by preparation and later evidence checks. */\nexport function materializeAgentCandidateProfilePlan(\n options: MaterializeAgentCandidateProfilePlanOptions,\n): AgentCandidateWorkspacePlan {\n const root =\n options.workspace === 'task' ? options.workspaces.taskRoot : options.workspaces.candidateRoot\n if (!root) throw new Error('candidate profile target is missing its execution workspace root')\n const plan = materializeCandidateProfile(\n options.profile,\n candidateMaterializerHarness(options.harness),\n {\n binds: CANDIDATE_PROFILE_MATERIALIZER_BINDS,\n resolvedResources: options.resolvedResources,\n },\n )\n return projectCandidatePromptIntents(\n plan,\n options.launch,\n posix.join(root, '.tangle/system-prompt.md'),\n options.profile.prompt?.systemPrompt,\n options.profile.prompt?.appendSystemPrompt,\n )\n}\n\n/** Resolve the private Pi roots needed by an agent-root profile plan. */\nexport function candidateProfileAgentPaths(\n plan: {\n harness: HarnessType\n files: ReadonlyArray<{ root?: 'agent' | 'workspace' }>\n },\n runtimeHome: string | undefined,\n): { agentDir: string; sessionDir: string } | undefined {\n if (!plan.files.some((file) => file.root === 'agent')) return undefined\n if (plan.harness !== 'pi') {\n throw new Error(`candidate profile agent-root files are unsupported for ${plan.harness}`)\n }\n if (runtimeHome === undefined) {\n throw new Error('candidate profile agent-root files require executionRoots.profileRoot')\n }\n return resolvePiRuntimePaths(runtimeHome)\n}\n\n/** Bind exact native profile text to the canonical plan captured during preparation. */\nexport function createAgentCandidateProfileActivation(\n plan: AgentCandidateWorkspacePlan,\n profilePlan: AgentCandidateProfilePlanEvidence,\n): AgentCandidateProfileActivation {\n const sourceByIdentity = new Map(\n plan.files.map((file) => [profileFileIdentity(file.root, file.relPath), file]),\n )\n if (sourceByIdentity.size !== plan.files.length) {\n throw new Error('candidate profile activation contains duplicate rooted native file paths')\n }\n const files = profilePlan.material.files.map((expected) => {\n const source = sourceByIdentity.get(profileFileIdentity(expected.root, expected.relPath))\n if (!source) {\n throw new Error(\n `candidate profile activation is missing ${profileFileLabel(expected.root, expected.relPath)}`,\n )\n }\n const mode = source.mode ?? 0o644\n if (!Number.isSafeInteger(mode) || mode < 0 || mode > 0o777) {\n throw new Error(\n `candidate profile activation has invalid mode for ${profileFileLabel(expected.root, expected.relPath)}`,\n )\n }\n return { path: expected.relPath, mode, content: source.content }\n })\n if (files.length !== plan.files.length) {\n throw new Error('candidate profile activation contains unplanned native files')\n }\n return parseAgentCandidateProfileActivation(\n canonicalCandidateDocument<AgentCandidateProfileActivation>({\n kind: 'agent-candidate-profile-activation',\n profilePlan,\n files,\n }).value,\n profilePlan.digest,\n )\n}\n\nfunction profileFileIdentity(root: 'agent' | 'workspace' | undefined, relPath: string): string {\n return `${root ?? 'workspace'}\\0${relPath}`\n}\n\nfunction profileFileLabel(root: 'agent' | 'workspace' | undefined, relPath: string): string {\n return root === 'agent' ? `agent:${relPath}` : relPath\n}\n\n/** Parse and check every native file hash plus both canonical document digests. */\nexport function parseAgentCandidateProfileActivation(\n input: unknown,\n expectedProfilePlanDigest?: AgentCandidateProfilePlanEvidence['digest'],\n): AgentCandidateProfileActivation {\n const activation = agentCandidateProfileActivationSchema.parse(input)\n const planBytes = canonicalCandidateBytes(activation.profilePlan.material)\n const profilePlanArtifact = activation.profilePlan.artifact\n if (\n sha256Bytes(planBytes) !== activation.profilePlan.digest ||\n profilePlanArtifact.sha256 !== activation.profilePlan.digest ||\n profilePlanArtifact.byteLength !== planBytes.byteLength ||\n ('content' in profilePlanArtifact &&\n !Buffer.from(profilePlanArtifact.content, 'base64').equals(Buffer.from(planBytes))) ||\n (expectedProfilePlanDigest !== undefined &&\n activation.profilePlan.digest !== expectedProfilePlanDigest)\n ) {\n throw new Error('candidate profile activation has an invalid canonical profile plan')\n }\n if (canonicalCandidateDigest(omitTopLevelDigest(activation)) !== activation.digest) {\n throw new Error('candidate profile activation digest does not match')\n }\n return immutableCandidateValue(activation)\n}\n\nconst CANDIDATE_PROFILE_DIRECT_FIELDS = [\n 'name',\n 'description',\n 'version',\n 'tags',\n 'prompt',\n 'harness',\n 'permissions',\n 'tools',\n 'confidential',\n] as const\n\n/** Convert only behavior-preserving generic profile fields into the closed candidate contract. */\nexport function freezeGenericAgentCandidateProfile(input: AgentProfile): AgentCandidateProfile {\n assertSandboxProfileCompatibility(input)\n const profile = parseExactAgentProfile(input, 'profile')\n return candidateProfileFromGenericProfile(profile)\n}\n\n/**\n * Keep every generic-profile-to-candidate conversion in one place.\n * Callers use this both when sealing a new bundle and when proving a measured\n * profile is exactly the profile in an existing candidate.\n */\nfunction candidateProfileFromGenericProfile(profile: AgentProfile): AgentCandidateProfile {\n assertResolvedKnowledgeResources(profile.resources)\n if (profile.connections !== undefined) unsupportedProfileField('connections')\n if (profile.metadata !== undefined) unsupportedProfileField('metadata')\n if (profile.extensions !== undefined) unsupportedProfileField('extensions')\n if (profile.model?.metadata !== undefined) unsupportedProfileField('model.metadata')\n\n const candidate: Record<string, unknown> = {}\n copyDirectProfileFields(candidate, profile as Record<string, unknown>)\n if (profile.model) {\n const { metadata: _metadata, ...model } = profile.model\n candidate.model = model\n }\n if (profile.mcp) candidate.mcp = freezeMcpServers(profile.mcp)\n if (profile.subagents) {\n candidate.subagents = Object.fromEntries(\n Object.entries(profile.subagents).map(([name, subagent]) => {\n if (subagent.metadata !== undefined) unsupportedProfileField(`subagents.${name}.metadata`)\n const { metadata: _metadata, ...value } = subagent\n return [name, value]\n }),\n )\n }\n if (profile.resources) candidate.resources = freezeResources(profile.resources)\n if (profile.hooks && Object.values(profile.hooks).some((commands) => commands.length > 0)) {\n throw new Error(\n 'generic AgentProfile hooks cannot be safely tokenized; use a candidate-profile source with executable/args',\n )\n }\n if (profile.hooks) candidate.hooks = profile.hooks\n if (profile.modes) {\n candidate.modes = Object.fromEntries(\n Object.entries(profile.modes).map(([name, mode]) => {\n if (mode.metadata !== undefined) unsupportedProfileField(`modes.${name}.metadata`)\n const { metadata: _metadata, ...value } = mode\n return [name, value]\n }),\n )\n }\n const parsed = parseExactCandidateProfile(candidate)\n return parsed\n}\n\n/** Prove the measured generic profile and sealed candidate profile describe the same behavior. */\nexport function assertCandidateProfileBinding(\n measuredInput: unknown,\n bundled: AgentCandidateProfile,\n): void {\n assertSandboxProfileCompatibility(measuredInput)\n const measured = parseExactAgentProfile(measuredInput, 'measured agent profile')\n const expected = candidateProfileFromGenericProfile(measured)\n if (canonicalCandidateDigest(expected) !== canonicalCandidateDigest(bundled)) {\n throw new Error('measured agent profile does not match sealed candidate profile')\n }\n}\n\n/** Parse a complete profile without silently discarding unsupported fields. */\nexport function parseExactAgentProfile(input: unknown, label: string): AgentProfile {\n let parsed: AgentProfile\n try {\n parsed = agentProfileSchema.parse(input) as AgentProfile\n } catch (cause) {\n throw new Error(`${label} contains unsupported or non-canonical fields`, { cause })\n }\n assertCanonicalParse(input, parsed, label)\n return parsed\n}\n\n/** Parse a profile diff without silently discarding unsupported fields. */\nexport function parseExactAgentProfileDiff(input: unknown, label: string): AgentProfileDiff {\n let parsed: AgentProfileDiff\n try {\n parsed = agentProfileDiffSchema.parse(input) as AgentProfileDiff\n } catch (cause) {\n throw new Error(`${label} contains unsupported or non-canonical fields`, { cause })\n }\n assertCanonicalParse(input, parsed, label)\n return parsed\n}\n\n/** Apply one exact diff and reject any value that cannot be preserved canonically. */\nexport function applyExactAgentProfileDiff(\n baseInput: unknown,\n diffInput: unknown,\n label: string,\n): AgentProfile {\n const base = parseExactAgentProfile(baseInput, `${label} base profile`)\n const diff = parseExactAgentProfileDiff(diffInput, `${label} diff`)\n const applied = omitUndefinedObjectFields(applyAgentProfileDiff(base, diff), label)\n return parseExactAgentProfile(applied, `${label} result`)\n}\n\n/** Parse a candidate profile without silently discarding unsupported or non-canonical fields. */\nexport function parseExactCandidateProfile(input: unknown): AgentCandidateProfile {\n const parsed = agentCandidateProfileSchema.parse(input)\n assertCanonicalParse(input, parsed, 'candidate profile')\n return parsed\n}\n\n/** Reject profile fields whose behavioral effect is not yet proven by candidate executors. */\nexport function assertCandidateProfileExecutionSupport(profile: AgentCandidateProfile): void {\n assertResolvedKnowledgeResources(profile.resources)\n assertSandboxProfileCompatibility(profile)\n const fields = ['tools', 'permissions', 'modes', 'confidential'] as const\n const unsupported = fields.filter((field) => hasEntries(profile[field]))\n if (unsupported.length > 0) {\n throw new Error(\n `candidate execution cannot prove in-session effects for non-empty AgentProfile fields: ${unsupported.join(', ')}`,\n )\n }\n}\n\n/** Convert the candidate profile contract into the portable interface profile it represents. */\nexport function agentCandidateProfileAsAgentProfile(\n candidate: AgentCandidateProfile,\n): AgentProfile {\n assertResolvedKnowledgeResources(candidate.resources)\n assertSandboxProfileCompatibility(candidate)\n const output: Record<string, unknown> = {}\n copyDirectProfileFields(output, candidate as unknown as Record<string, unknown>)\n if (candidate.model) output.model = { ...candidate.model }\n if (candidate.mcp) {\n output.mcp = Object.fromEntries(\n Object.entries(candidate.mcp).map(([name, server]) => [\n name,\n {\n ...server,\n // Candidate config values ({kind:'public', value}) are already valid\n // AgentProfileConfigValue entries under interface >=0.40 — clone them\n // rather than unwrapping to plain strings, which the 0.40 profile\n // schema rejects.\n ...(server.args ? { args: server.args.map((value) => ({ ...value })) } : {}),\n ...(server.env ? { env: cloneRecord(server.env) } : {}),\n },\n ]),\n )\n }\n if (candidate.subagents) output.subagents = cloneRecord(candidate.subagents)\n if (candidate.modes) output.modes = cloneRecord(candidate.modes)\n if (candidate.hooks) {\n output.hooks = Object.fromEntries(\n Object.entries(candidate.hooks).map(([event, hooks]) => [\n event,\n hooks.map(({ executable, args, env, ...hook }) => ({\n ...hook,\n command: [\n executable,\n ...(args ?? []).map((value, index) =>\n requirePublicCandidateConfigValue(value, `hooks.${event}.args[${index}]`),\n ),\n ]\n .map(shellQuote)\n .join(' '),\n // Hook env stays in config-value form: the 0.40 profile hook contract\n // types env as Record<string, AgentProfileConfigValue>.\n ...(env ? { env: cloneRecord(env) } : {}),\n })),\n ]),\n )\n }\n if (candidate.resources) {\n if (candidate.resources.failOnError !== true) {\n throw new Error('sealed candidate profile contains fields unsupported by generic profiles')\n }\n output.resources = {\n failOnError: true,\n ...(candidate.resources.files\n ? {\n files: candidate.resources.files.map((file) => ({\n ...file,\n resource: publicResource(file.resource),\n })),\n }\n : {}),\n ...(candidate.resources.tools\n ? { tools: candidate.resources.tools.map(publicResource) }\n : {}),\n ...(candidate.resources.skills\n ? { skills: candidate.resources.skills.map(publicResource) }\n : {}),\n ...(candidate.resources.agents\n ? { agents: candidate.resources.agents.map(publicResource) }\n : {}),\n ...(candidate.resources.commands\n ? { commands: candidate.resources.commands.map(publicResource) }\n : {}),\n ...(candidate.resources.instructions !== undefined\n ? {\n instructions:\n typeof candidate.resources.instructions === 'string'\n ? candidate.resources.instructions\n : publicResource(candidate.resources.instructions),\n }\n : {}),\n }\n }\n return output as AgentProfile\n}\n\n/** Recursively remove undefined object fields while refusing undefined array entries. */\nexport function omitUndefinedObjectFields(value: unknown, path: string): unknown {\n if (Array.isArray(value)) {\n return value.map((entry, index) => {\n if (entry === undefined) {\n throw new Error(`${path} produced an undefined array entry at ${index}`)\n }\n return omitUndefinedObjectFields(entry, `${path}[${index}]`)\n })\n }\n if (value === null || typeof value !== 'object') return value\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .filter(([, entry]) => entry !== undefined)\n .map(([key, entry]) => [key, omitUndefinedObjectFields(entry, `${path}.${key}`)]),\n )\n}\n\nfunction freezeMcpServers(servers: Record<string, AgentProfileMcpServer>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(servers).map(([name, server]) => {\n if (server.transport !== undefined && server.transport !== 'stdio') {\n unsupportedProfileField(`mcp.${name}.transport=${server.transport}`)\n }\n if (server.url !== undefined) unsupportedProfileField(`mcp.${name}.url`)\n if (server.headers !== undefined) unsupportedProfileField(`mcp.${name}.headers`)\n if (server.metadata !== undefined) unsupportedProfileField(`mcp.${name}.metadata`)\n return [\n name,\n {\n ...(server.transport ? { transport: server.transport } : {}),\n ...(server.command ? { command: server.command } : {}),\n ...(server.args\n ? {\n args: server.args.map((value, index) =>\n candidatePublicValue(value, `mcp.${name}.args[${index}]`),\n ),\n }\n : {}),\n ...(server.env ? { env: mapCandidatePublicValues(server.env, `mcp.${name}.env`) } : {}),\n ...(server.cwd ? { cwd: server.cwd } : {}),\n ...(server.enabled === undefined ? {} : { enabled: server.enabled }),\n },\n ]\n }),\n )\n}\n\n/** A newer peer may admit knowledge pins that these candidate conversions cannot preserve. */\nfunction assertResolvedKnowledgeResources(resources: unknown): void {\n if (\n resources !== null &&\n typeof resources === 'object' &&\n 'knowledge' in resources &&\n resources.knowledge !== undefined\n ) {\n throw new Error(\n 'candidate profile resources.knowledge must be owner-authorized and resolved before candidate conversion or execution',\n )\n }\n}\n\nfunction freezeResources(resources: NonNullable<AgentProfile['resources']>): unknown {\n if (resources.failOnError !== true) {\n throw new Error('candidate profile resources require failOnError: true')\n }\n return {\n failOnError: true,\n ...(resources.files\n ? {\n files: resources.files.map((file) => ({\n ...file,\n resource: freezeResource(file.resource),\n })),\n }\n : {}),\n ...(resources.tools ? { tools: resources.tools.map(freezeResource) } : {}),\n ...(resources.skills ? { skills: resources.skills.map(freezeResource) } : {}),\n ...(resources.agents ? { agents: resources.agents.map(freezeResource) } : {}),\n ...(resources.commands ? { commands: resources.commands.map(freezeResource) } : {}),\n ...(resources.instructions === undefined\n ? {}\n : {\n instructions:\n typeof resources.instructions === 'string'\n ? resources.instructions\n : freezeResource(resources.instructions),\n }),\n }\n}\n\nfunction freezeResource(resource: AgentProfileResourceRef): AgentCandidateResourceRef {\n if (resource.kind === 'github') {\n throw new Error(\n 'generic GitHub profile resources do not carry byte identity; use a candidate-profile source with a pinned commit, digest, and byte length',\n )\n }\n const bytes = Buffer.from(resource.content, 'utf8')\n return {\n ...resource,\n sha256: embeddedCandidateArtifact(bytes).sha256,\n byteLength: bytes.byteLength,\n }\n}\n\nfunction copyDirectProfileFields(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n): void {\n for (const key of CANDIDATE_PROFILE_DIRECT_FIELDS) {\n if (source[key] !== undefined) target[key] = source[key]\n }\n}\n\nfunction assertCanonicalParse(input: unknown, parsed: unknown, label: string): void {\n if (!Buffer.from(canonicalCandidateBytes(input)).equals(canonicalCandidateBytes(parsed))) {\n throw new Error(`${label} contains unsupported or non-canonical fields`)\n }\n}\n\nfunction publicResource(resource: AgentCandidateResourceRef): unknown {\n if (resource.kind === 'inline') {\n return { kind: 'inline', name: resource.name, content: resource.content }\n }\n return {\n kind: 'github',\n repository: `${resource.repository.owner}/${resource.repository.repo}`,\n path: resource.path,\n ref: resource.commit,\n ...(resource.name ? { name: resource.name } : {}),\n }\n}\n\n/** Freeze one profile config value into the candidate's PUBLIC-only config\n * shape. A secret-ref is refused, never silently dropped or unwrapped. */\nfunction candidatePublicValue(\n value: AgentProfileConfigValue,\n path: string,\n): { kind: 'public'; value: string } {\n if (value.kind !== 'public') refuseSandboxProfileField(`${path} (${value.kind})`)\n return { kind: 'public', value: value.value }\n}\n\nfunction mapCandidatePublicValues(\n values: Record<string, AgentProfileConfigValue>,\n pathPrefix: string,\n): Record<string, { kind: 'public'; value: string }> {\n return Object.fromEntries(\n Object.entries(values).map(([name, value]) => [\n name,\n candidatePublicValue(value, `${pathPrefix}.${name}`),\n ]),\n )\n}\n\nfunction cloneRecord<T>(values: Record<string, T>): Record<string, T> {\n return Object.fromEntries(\n Object.entries(values).map(([key, value]) => [key, { ...value }]),\n ) as Record<string, T>\n}\n\nfunction hasEntries(value: unknown): boolean {\n return value !== undefined && value !== null && typeof value === 'object'\n ? Object.keys(value).length > 0\n : false\n}\n\nfunction shellQuote(value: string): string {\n return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : `'${value.replaceAll(\"'\", `'\"'\"'`)}'`\n}\n\nfunction unsupportedProfileField(path: string): never {\n throw new Error(\n `generic AgentProfile field ${path} is not representable in a sealed candidate profile`,\n )\n}\n\nexport function buildLaunch(\n candidate: VerifiedAgentCandidate,\n task: AgentCandidateTaskExecution,\n profileFlags: AgentCandidateConfigValue[],\n): { executable: string; args: AgentCandidateConfigValue[] } {\n const launch = candidate.bundle.execution.launch\n if (launch.kind === 'container-command') {\n return { executable: launch.executable, args: [...(launch.args ?? []), ...profileFlags] }\n }\n const candidateRoot = task.executionRoots.candidateRoot\n if (!candidateRoot) throw new Error('candidate entrypoint requires a container candidate root')\n const entrypoint = posix.join(candidateRoot, launch.entrypoint)\n const candidateArgs = launch.args ?? []\n if (launch.interpreter) {\n return {\n executable: launch.interpreter,\n args: [{ kind: 'public', value: entrypoint }, ...candidateArgs, ...profileFlags],\n }\n }\n return { executable: entrypoint, args: [...candidateArgs, ...profileFlags] }\n}\n\nexport function modelRoutes(\n profile: VerifiedAgentCandidate['bundle']['profile'],\n requested: string,\n): AgentCandidateExecutionPlanMaterial['model']['routes'] {\n const routes: AgentCandidateExecutionPlanMaterial['model']['routes'] = [\n { kind: 'primary', requested },\n ]\n if (profile.model?.small) routes.push({ kind: 'small', requested })\n for (const name of Object.keys(profile.modes ?? {}).sort()) {\n if (profile.modes?.[name]?.model) routes.push({ kind: 'mode', name, requested })\n }\n for (const name of Object.keys(profile.subagents ?? {}).sort()) {\n if (profile.subagents?.[name]?.model) routes.push({ kind: 'subagent', name, requested })\n }\n return routes\n}\n\nexport function candidateEntrypointReceipt(\n candidate: VerifiedAgentCandidate,\n): { path: string; sha256: `sha256:${string}`; byteLength: number } | undefined {\n const launch = candidate.bundle.execution.launch\n const workspace = candidate.bundle.execution.workspace\n if (launch.kind !== 'candidate-entrypoint' || !workspace) return undefined\n const file = workspace.material.files.find((entry) => entry.path === launch.entrypoint)\n if (!file) throw new Error('candidate entrypoint is absent from the verified workspace')\n return { path: file.path, sha256: file.sha256, byteLength: file.byteLength }\n}\n\nexport function absoluteExecutionCwd(\n cwd: VerifiedAgentCandidate['bundle']['execution']['cwd'],\n roots: AgentCandidateTaskExecution['executionRoots'],\n): string {\n const root = workspaceExecutionRoot(cwd.workspace, roots)\n const absolute = cwd.path === '.' ? root : posix.join(root, cwd.path)\n if (absolute !== root && !absolute.startsWith(`${root}/`)) {\n throw new Error('candidate cwd escapes its execution workspace')\n }\n return absolute\n}\n\nfunction workspaceExecutionRoot(\n workspace: 'task' | 'candidate',\n roots: AgentCandidateTaskExecution['executionRoots'],\n): string {\n const root = workspace === 'task' ? roots.taskRoot : roots.candidateRoot\n if (!root) throw new Error(`candidate ${workspace} workspace root is missing`)\n return root\n}\n\nexport function exactProfileExecutorFiles(\n sourceFiles: ReadonlyArray<{\n relPath: string\n content: string\n mode?: number\n root?: 'agent' | 'workspace'\n }>,\n expectedFiles: ReadonlyArray<{\n relPath: string\n mode: number\n contentSha256: string\n root?: 'agent'\n }>,\n): Array<{ path: string; mode: number; root?: 'agent'; bytes: Uint8Array }> {\n const byIdentity = new Map(\n sourceFiles.map((file) => [profileFileIdentity(file.root, file.relPath), file]),\n )\n if (byIdentity.size !== sourceFiles.length || sourceFiles.length !== expectedFiles.length) {\n throw new Error('profile source files do not match the signed profile plan')\n }\n return expectedFiles.map((expected) => {\n const source = byIdentity.get(profileFileIdentity(expected.root, expected.relPath))\n const mode = source?.mode ?? 0o644\n const bytes = Buffer.from(source?.content ?? '', 'utf8')\n if (\n !source ||\n !Number.isInteger(mode) ||\n mode < 0 ||\n mode > 0o777 ||\n mode !== expected.mode ||\n sha256Bytes(bytes) !== expected.contentSha256\n ) {\n throw new Error('profile source files do not match the signed profile plan')\n }\n return {\n path: expected.relPath,\n mode,\n ...(expected.root === 'agent' ? { root: 'agent' as const } : {}),\n bytes: Uint8Array.from(bytes),\n }\n })\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AGENT_PROFILE_MATERIALIZATION_AXES, AgentProfile, CanonicalAgentProfileMaterializationAxis, profileMaterializationAxes as profileMaterializationAxes$1 } from "@tangle-network/agent-interface";
1
+ import { AgentProfile, CanonicalAgentProfileMaterializationAxis, profileMaterializationAxes as profileMaterializationAxes$1 } from "@tangle-network/agent-interface";
2
2
  import { HarnessId, SkippableDimension, WorkspacePlan } from "@tangle-network/agent-profile-materialize";
3
3
  //#region src/agent/profile-materialization.d.ts
4
4
  type KnownAgentProfileMaterializationAxis = CanonicalAgentProfileMaterializationAxis;
@@ -89,8 +89,6 @@ declare function assertProfileMaterialization(options: AssertProfileMaterializat
89
89
  * not the plan's to lower.
90
90
  */
91
91
  declare function assertProfileMaterializes(profile: AgentProfile, harness: HarnessId, context: string, skip?: readonly SkippableDimension[]): WorkspacePlan;
92
- /** Format profile-axis drop issues into a concise operator-facing error. */
93
- declare function renderProfileMaterializationIssues(issues: readonly ProfileMaterializationIssue[], context?: string): string;
94
92
  //#endregion
95
- export { worktreeCliProfileMaterialization as C, validateProfileMaterialization as S, promptModelProfileMaterialization as _, DefineProfileMaterializationContractOptions as a, renderProfileMaterializationIssues as b, ProfileMaterializationIssue as c, assertProfileMaterializes as d, controlProfileMaterialization as f, promptControlProfileMaterialization as g, profileMaterializationAxes$1 as h, CanonicalAgentProfileMaterializationAxis as i, ValidateProfileMaterializationOptions as l, fullProfileMaterialization as m, AgentProfileMaterializationAxis as n, KnownAgentProfileMaterializationAxis as o, defineProfileMaterializationContract as p, AssertProfileMaterializationOptions as r, ProfileMaterializationContract as s, AGENT_PROFILE_MATERIALIZATION_AXES as t, assertProfileMaterialization as u, promptOnlyProfileMaterialization as v, sandboxActProfileMaterialization as x, promptResourceProfileMaterialization as y };
96
- //# sourceMappingURL=profile-materialization-BnoEf1co.d.ts.map
93
+ export { promptResourceProfileMaterialization as _, ProfileMaterializationContract as a, worktreeCliProfileMaterialization as b, assertProfileMaterialization as c, defineProfileMaterializationContract as d, fullProfileMaterialization as f, promptOnlyProfileMaterialization as g, promptModelProfileMaterialization as h, KnownAgentProfileMaterializationAxis as i, assertProfileMaterializes as l, promptControlProfileMaterialization as m, AssertProfileMaterializationOptions as n, ProfileMaterializationIssue as o, profileMaterializationAxes$1 as p, DefineProfileMaterializationContractOptions as r, ValidateProfileMaterializationOptions as s, AgentProfileMaterializationAxis as t, controlProfileMaterialization as u, sandboxActProfileMaterialization as v, validateProfileMaterialization as y };
94
+ //# sourceMappingURL=profile-materialization-B1wm2SPT.d.ts.map
@@ -1,4 +1,4 @@
1
- import { Hb as coderTaskToPrompt, Vb as CoderTask, _b as multiHarnessResearcherFanout, ab as UiFinding, cb as UiLens, db as MultiHarnessResearcherFanoutOptions, fb as ResearchOutput, gb as createResearcherValidator, hb as ResearcherProfileOptions, ib as UI_LENSES, lb as KnowledgeItem, mb as ResearchTask, ob as UiFindingScreenshot, pb as ResearchSource, rb as UI_FINDING_SEVERITIES, sb as UiFindingSeverity, ub as KnowledgeUpdate, vb as researcherProfile } from "./types-Dl5L4r8Z.js";
1
+ import { $h as ResearcherProfileOptions, Gh as UiFindingScreenshot, Jh as KnowledgeItem, Kh as UiFindingSeverity, Qh as ResearchTask, Wh as UiFinding, Xh as ResearchOutput, Yh as KnowledgeUpdate, Zh as ResearchSource, eg as researcherProfile, qh as UiLens } from "./types-CaOXqRTq.js";
2
2
  import { SandboxEvent } from "@tangle-network/sandbox";
3
3
  //#region src/profiles/ui-auditor/lens-prompts.d.ts
4
4
  /** Cross-lens rules injected into every UI audit iteration: finding quality standards and scope limits. @experimental */
@@ -99,5 +99,5 @@ interface UiAuditOutput {
99
99
  /** Parse raw `SandboxEvent` emissions from an audit iteration into structured `UiAuditOutput`. @experimental */
100
100
  declare function parseAuditorEvents(events: SandboxEvent[]): UiAuditOutput;
101
101
  //#endregion
102
- export { type CoderTask, type KnowledgeItem, type KnowledgeUpdate, LENS_BRIEFS, type MultiHarnessResearcherFanoutOptions, type ResearchOutput, type ResearchSource, type ResearchTask, type ResearcherProfileOptions, SHARED_AUDITOR_RULES, UI_FINDING_SEVERITIES, UI_LENSES, type UiAuditCapture, type UiAuditCaptureRequest, type UiAuditOutput, type UiAuditTask, type UiAuditViewport, type UiFinding, type UiFindingScreenshot, type UiFindingSeverity, type UiLens, buildAuditorSystemPrompt, coderTaskToPrompt, createResearcherValidator, multiHarnessResearcherFanout, parseAuditorEvents, researcherProfile };
102
+ export { type KnowledgeItem, type KnowledgeUpdate, LENS_BRIEFS, type ResearchOutput, type ResearchSource, type ResearchTask, type ResearcherProfileOptions, SHARED_AUDITOR_RULES, type UiAuditCapture, type UiAuditCaptureRequest, type UiAuditOutput, type UiAuditTask, type UiAuditViewport, type UiFinding, type UiFindingScreenshot, type UiFindingSeverity, type UiLens, buildAuditorSystemPrompt, parseAuditorEvents, researcherProfile };
103
103
  //# sourceMappingURL=profiles.d.ts.map
package/dist/profiles.js CHANGED
@@ -1,7 +1,7 @@
1
- import { i as ConfigError } from "./errors-DodWX-cb.js";
1
+ import "./errors-DodWX-cb.js";
2
+ import { t as isRecord } from "./record-value-B6bwJxLa.js";
2
3
  import { t as assertExecutableAgentProfile } from "./model-policy-CyCUwHed.js";
3
- import { t as coderTaskToPrompt } from "./coder-yhVWbdWc.js";
4
- import { n as UI_LENSES, t as UI_FINDING_SEVERITIES } from "./substrate-B0TYNrXn.js";
4
+ import { t as UI_LENSES } from "./substrate-CGDFTSRh.js";
5
5
  import { agentProfileSchema } from "@tangle-network/agent-interface";
6
6
  //#region src/profiles/researcher.ts
7
7
  /**
@@ -73,42 +73,6 @@ function researcherProfile(options) {
73
73
  };
74
74
  }
75
75
  /**
76
- * Build a fanout topology over multiple harnesses. The kernel round-robins
77
- * `agentRuns` across the N parallel iterations and the `FanoutVote` driver
78
- * picks the highest-scoring valid output.
79
- *
80
- * @experimental
81
- */
82
- function multiHarnessResearcherFanout(options) {
83
- if (options.profiles.length === 0) throw new ConfigError("multiHarnessResearcherFanout: at least one exact profile is required");
84
- const agentRuns = options.profiles.map((profile) => {
85
- const { agentRunSpec } = researcherProfile({ profile });
86
- return agentRunSpec;
87
- });
88
- const { output, validator } = researcherProfile({
89
- profile: options.profiles[0],
90
- citationDensityMin: options.citationDensityMin,
91
- task: options.task
92
- });
93
- return {
94
- agentRuns,
95
- output,
96
- validator,
97
- driver: {
98
- name: "researcher-fanout",
99
- async plan(task, history) {
100
- return history.length === 0 ? Array.from({ length: agentRuns.length }, () => task) : [];
101
- },
102
- decide() {
103
- return "done";
104
- },
105
- describePlan() {
106
- return { kind: "fanout" };
107
- }
108
- }
109
- };
110
- }
111
- /**
112
76
  * Build a validator that closes over a specific `ResearchTask`'s constraints.
113
77
  *
114
78
  * Checks in order:
@@ -281,9 +245,6 @@ function parseResearcherEvents(events) {
281
245
  proposedWrites: []
282
246
  };
283
247
  }
284
- function isRecord(value) {
285
- return value !== null && typeof value === "object" && !Array.isArray(value);
286
- }
287
248
  /** A coerced output that carries no items, citations, or proposed writes. */
288
249
  function isEmptyOutput(o) {
289
250
  return o.items.length === 0 && o.citations.length === 0 && o.proposedWrites.length === 0;
@@ -636,6 +597,6 @@ function parseAuditorEvents(events) {
636
597
  return out;
637
598
  }
638
599
  //#endregion
639
- export { LENS_BRIEFS, SHARED_AUDITOR_RULES, UI_FINDING_SEVERITIES, UI_LENSES, buildAuditorSystemPrompt, coderTaskToPrompt, createResearcherValidator, multiHarnessResearcherFanout, parseAuditorEvents, researcherProfile };
600
+ export { LENS_BRIEFS, SHARED_AUDITOR_RULES, buildAuditorSystemPrompt, parseAuditorEvents, researcherProfile };
640
601
 
641
602
  //# sourceMappingURL=profiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.js","names":[],"sources":["../src/profiles/researcher.ts","../src/profiles/ui-auditor/lens-prompts.ts","../src/profiles/ui-auditor/output-adapter.ts"],"sourcesContent":["/**\n * Opinionated preset for source-grounded research\n * tasks. The agent is told to:\n * - bound its work to a single `knowledgeNamespace`\n * - emit `items[]` carrying provenance + confidence\n * - emit `citations[]` linking quotes back to source urls\n * - emit `proposedWrites[]` — never call materialize itself\n * - describe `gaps` it could not answer\n *\n * The profile is stateless and agent-agnostic. The caller supplies the exact execution profile;\n * this preset adds only the researcher prompt, tools, parser, and validator.\n *\n * Propose-don't-apply: the profile NEVER writes to the knowledge base.\n * It produces `proposedWrites: KnowledgeUpdate[]` in the output. The\n * caller (gtm-agent, journey-eval, user) decides whether to feed those\n * updates through `applyKnowledgeWriteBlocks` / a KbStore put.\n *\n * Namespace isolation: every `KnowledgeItem` + `KnowledgeUpdate` in the\n * output carries `namespace`. The validator hard-fails when any item\n * touches a namespace other than `task.knowledgeNamespace`.\n *\n * @experimental\n */\n\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type {\n AgentRunSpec,\n DefaultVerdict,\n Driver,\n OutputAdapter,\n Validator,\n} from '../runtime/types'\n\n/** Source families a researcher profile may prefer for a task. One owner: the delegation\n * vocabulary (`DelegateResearchArgs.sources`) re-exports this type rather than restating it.\n * @experimental */\nexport type ResearchSource = 'web' | 'corpus' | 'twitter' | 'github' | 'docs'\n\n/** Task contract for a source-grounded research agent. @experimental */\nexport interface ResearchTask {\n /** The research question to answer. */\n question: string\n /** Bound: e.g. \"audience for cpg-founder ICP\". */\n scope?: string\n /** Multi-tenant scope (customer-id, workspace-id). Validator enforces. */\n knowledgeNamespace: string\n sources?: ResearchSource[]\n recencyWindow?: { since?: Date; until?: Date }\n maxItems?: number\n /** Per-item minimum confidence in [0, 1]. Validator scores recall vs this. */\n minConfidence?: number\n}\n\n/**\n * Knowledge item emitted by the researcher.\n *\n * Profile-local type. When agent-knowledge promotes `KnowledgeClaim` →\n * top-level `KnowledgeItem` substrate-wide, these fields collapse 1:1.\n *\n * @experimental\n */\nexport interface KnowledgeItem {\n id: string\n /** Multi-tenant scope. MUST equal `task.knowledgeNamespace`. */\n namespace: string\n /** The factual claim, in the researcher's words. */\n claim: string\n /** Provenance — at least one entry required. */\n evidence: Array<{ source: string; quote?: string; url?: string; capturedAt: number }>\n /** Researcher's self-reported confidence in [0, 1]. */\n confidence: number\n /** Prior item ids this supersedes (chain). */\n supersedes?: string[]\n /** Set if the agent is retracting an earlier item. Unix ms. */\n retractedAt?: number\n authoredBy: { kind: 'human' | 'agent'; id: string }\n}\n\n/**\n * A proposed write to the knowledge base. The profile does NOT apply\n * these — the caller decides.\n *\n * @experimental\n */\nexport type KnowledgeUpdate =\n | { kind: 'insert'; namespace: string; item: KnowledgeItem }\n | { kind: 'supersede'; namespace: string; previousId: string; item: KnowledgeItem }\n | { kind: 'retract'; namespace: string; itemId: string; reason: string }\n\n/**\n * Researcher output. Required fields are typed; optional fields preserve\n * the agent's free-form intelligence (`notes`, `raw`). The validator\n * enforces the typed minimum.\n *\n * @experimental\n */\nexport interface ResearchOutput {\n items: KnowledgeItem[]\n citations: Array<{ url: string; quote: string; confidence: number }>\n proposedWrites: KnowledgeUpdate[]\n gaps?: string[]\n notes?: string\n /** Anything the agent emitted beyond the typed fields. */\n raw?: unknown\n}\n\n/** Options for the source-grounded researcher profile preset. @experimental */\nexport interface ResearcherProfileOptions {\n /** Caller-owned exact harness/provider/model identity. */\n profile: AgentProfile\n /** Custom system prompt replacement. Default = built-in researcher preset. */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `profile.name`. */\n name?: string\n /**\n * Default 0.7. Minimum (citations with quote) / items ratio for `valid=true`.\n * Below this floor, citation_density scores < 1 and the item set is gated.\n */\n citationDensityMin?: number\n}\n\nconst DEFAULT_CITATION_DENSITY_MIN = 0.7\n\n/** Build a source-grounded researcher profile with output parsing and validation. @experimental */\nexport function researcherProfile(options: ResearcherProfileOptions & { task?: ResearchTask }): {\n profile: AgentProfile\n taskToPrompt: (task: ResearchTask) => string\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n agentRunSpec: AgentRunSpec<ResearchTask>\n} {\n const base = agentProfileSchema.parse(options.profile) as AgentProfile\n assertExecutableAgentProfile(base, 'researcherProfile')\n const name = options.name ?? base.name\n const systemPrompt = options.systemPrompt ?? RESEARCHER_SYSTEM_PROMPT\n const citationDensityMin = options.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const profile: AgentProfile = {\n ...base,\n name,\n description: base.description ?? \"Source-grounded research agent. Propose-don't-apply.\",\n prompt: { ...base.prompt, systemPrompt },\n tools: { web_search: true, fs: true, shell: true, ...base.tools },\n metadata: { ...base.metadata, specialty: 'researcher' },\n }\n const output: OutputAdapter<ResearchOutput> = { parse: parseResearcherEvents }\n const validator: Validator<ResearchOutput> = options.task\n ? createResearcherValidator(options.task, { citationDensityMin })\n : createResearcherValidator(\n { question: '', knowledgeNamespace: '' },\n { citationDensityMin, namespaceCheck: false },\n )\n const agentRunSpec: AgentRunSpec<ResearchTask> = {\n name,\n profile,\n taskToPrompt: formatResearcherPrompt,\n }\n return { profile, taskToPrompt: formatResearcherPrompt, output, validator, agentRunSpec }\n}\n\n/** @experimental */\nexport interface MultiHarnessResearcherFanoutOptions {\n /** Exact execution profiles, one per parallel researcher. */\n profiles: ReadonlyArray<AgentProfile>\n /** Default citation density floor for the shared validator. */\n citationDensityMin?: number\n /** Optional task — narrows the validator's namespace check. */\n task?: ResearchTask\n}\n\n/**\n * Build a fanout topology over multiple harnesses. The kernel round-robins\n * `agentRuns` across the N parallel iterations and the `FanoutVote` driver\n * picks the highest-scoring valid output.\n *\n * @experimental\n */\nexport function multiHarnessResearcherFanout(options: MultiHarnessResearcherFanoutOptions): {\n agentRuns: AgentRunSpec<ResearchTask>[]\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n driver: Driver<ResearchTask, ResearchOutput, 'done'>\n} {\n if (options.profiles.length === 0) {\n throw new ConfigError('multiHarnessResearcherFanout: at least one exact profile is required')\n }\n const agentRuns = options.profiles.map((profile) => {\n const { agentRunSpec } = researcherProfile({ profile })\n return agentRunSpec\n })\n const { output, validator } = researcherProfile({\n profile: options.profiles[0]!,\n citationDensityMin: options.citationDensityMin,\n task: options.task,\n })\n // Single fanout round across the N harnesses, then stop: the kernel\n // round-robins `agentRuns` over the N branches and selects the winner\n // (best valid score) across all iterations via `defaultSelectWinner`.\n const driver: Driver<ResearchTask, ResearchOutput, 'done'> = {\n name: 'researcher-fanout',\n async plan(task, history) {\n return history.length === 0 ? Array.from({ length: agentRuns.length }, () => task) : []\n },\n // 'done' is a terminal decision in the kernel; the loop finalizes after\n // the single fanout round and selects the winner via `defaultSelectWinner`.\n decide() {\n return 'done'\n },\n describePlan() {\n return { kind: 'fanout' }\n },\n }\n return { agentRuns, output, validator, driver }\n}\n\n/**\n * Build a validator that closes over a specific `ResearchTask`'s constraints.\n *\n * Checks in order:\n * 1. Items must be non-empty.\n * 2. Every item carries `evidence.length >= 1`.\n * 3. Every item + proposedWrite is scoped to `task.knowledgeNamespace`\n * (hard-fail on any namespace mismatch — defence in depth for the\n * multi-tenant invariant).\n * 4. Citation density (citations with quote / items) >= floor.\n *\n * Aggregate score:\n * 0.4 · citation_density\n * + 0.2 · source_diversity (distinct sources / max(items, 1))\n * + 0.2 · recency_match (mean fraction within `recencyWindow`)\n * + 0.2 · (1 − gaps/maxGaps), maxGaps = max(items, 1)\n *\n * @experimental\n */\nexport function createResearcherValidator(\n task: ResearchTask,\n config: { citationDensityMin?: number; namespaceCheck?: boolean } = {},\n): Validator<ResearchOutput> {\n const citationDensityMin = config.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const namespaceCheck = config.namespaceCheck ?? true\n return {\n async validate(output) {\n const notes: string[] = []\n const scores: Record<string, number> = {}\n let pass = true\n\n if (!Array.isArray(output.items) || output.items.length === 0) {\n pass = false\n notes.push('no items')\n scores.items = 0\n } else {\n scores.items = 1\n }\n\n const missingEvidence = (output.items ?? []).filter(\n (item) => !Array.isArray(item.evidence) || item.evidence.length === 0,\n )\n if (missingEvidence.length > 0) {\n pass = false\n notes.push(`${missingEvidence.length} item(s) without evidence`)\n scores.provenance = 0\n } else {\n scores.provenance = 1\n }\n\n if (namespaceCheck) {\n const foreignItems = (output.items ?? []).filter(\n (item) => item.namespace !== task.knowledgeNamespace,\n )\n const foreignWrites = (output.proposedWrites ?? []).filter(\n (write) => write.namespace !== task.knowledgeNamespace,\n )\n if (foreignItems.length > 0 || foreignWrites.length > 0) {\n pass = false\n notes.push(\n `namespace violation: ${foreignItems.length} item(s) + ${foreignWrites.length} write(s) ` +\n `outside ${task.knowledgeNamespace}`,\n )\n scores.namespace = 0\n } else {\n scores.namespace = 1\n }\n }\n\n const itemCount = Math.max(output.items?.length ?? 0, 1)\n const citationsWithQuote = (output.citations ?? []).filter(\n (citation) => typeof citation.quote === 'string' && citation.quote.length > 0,\n ).length\n const citationDensity = Math.min(1, citationsWithQuote / itemCount)\n if (citationDensity < citationDensityMin) {\n pass = false\n notes.push(\n `citation density ${citationDensity.toFixed(2)} below floor ${citationDensityMin.toFixed(2)}`,\n )\n }\n scores.citation_density = citationDensity\n\n const sourceSet = new Set<string>()\n for (const item of output.items ?? []) {\n for (const evidence of item.evidence ?? []) {\n if (evidence.source) sourceSet.add(evidence.source)\n }\n }\n scores.source_diversity = Math.min(1, sourceSet.size / itemCount)\n\n scores.recency_match = recencyMatchScore(output.items ?? [], task.recencyWindow)\n\n const maxGaps = itemCount\n const gapCount = output.gaps?.length ?? 0\n scores.gap_coverage = Math.max(0, 1 - gapCount / maxGaps)\n\n const score =\n 0.4 * scores.citation_density +\n 0.2 * scores.source_diversity +\n 0.2 * scores.recency_match +\n 0.2 * scores.gap_coverage\n\n const verdict: DefaultVerdict = {\n valid: pass,\n score: Number.isFinite(score) ? score : 0,\n scores,\n }\n if (notes.length > 0) verdict.notes = notes.join('; ')\n return verdict\n },\n }\n}\n\nfunction recencyMatchScore(items: KnowledgeItem[], window: ResearchTask['recencyWindow']): number {\n if (!window || (window.since === undefined && window.until === undefined)) return 1\n if (items.length === 0) return 0\n const sinceMs = window.since?.getTime() ?? Number.NEGATIVE_INFINITY\n const untilMs = window.until?.getTime() ?? Number.POSITIVE_INFINITY\n let hits = 0\n let total = 0\n for (const item of items) {\n for (const evidence of item.evidence ?? []) {\n if (typeof evidence.capturedAt !== 'number') continue\n total += 1\n if (evidence.capturedAt >= sinceMs && evidence.capturedAt <= untilMs) hits += 1\n }\n }\n return total === 0 ? 0 : hits / total\n}\n\n/** Built-in source-grounded research contract added to a caller-owned exact profile. */\nexport const RESEARCHER_SYSTEM_PROMPT = [\n 'You are a research agent. Your job is to answer a research question with',\n 'source-grounded knowledge items that the caller will choose whether to',\n 'persist to a multi-tenant knowledge base.',\n '',\n 'Hard rules:',\n \" 1. Every item you emit MUST carry the task's knowledgeNamespace exactly.\",\n ' Never write to a different namespace.',\n ' 2. Every item MUST carry at least one evidence entry with a source.',\n ' A quote + url is strongly preferred; capturedAt is unix ms.',\n ' 3. You propose writes — you do NOT apply them. The caller decides.',\n ' 4. Self-report confidence honestly in [0, 1]. Do not inflate.',\n ' 5. List what you could not answer in `gaps`. Better to admit a gap',\n ' than fabricate.',\n '',\n 'When you finish, emit a single final structured message of the shape:',\n ' ```json',\n ' { \"items\": [{ \"id\": \"...\", \"namespace\": \"...\", \"claim\": \"...\",',\n ' \"evidence\": [{ \"source\": \"...\", \"quote\": \"...\",',\n ' \"url\": \"...\", \"capturedAt\": 0 }],',\n ' \"confidence\": 0.0,',\n ' \"authoredBy\": { \"kind\": \"agent\", \"id\": \"...\" } }],',\n ' \"citations\": [{ \"url\": \"...\", \"quote\": \"...\", \"confidence\": 0.0 }],',\n ' \"proposedWrites\": [{ \"kind\": \"insert\", \"namespace\": \"...\",',\n ' \"item\": { /* same shape as items[] */ } }],',\n ' \"gaps\": [\"...\"],',\n ' \"notes\": \"free-form commentary\" }',\n ' ```',\n].join('\\n')\n\nfunction formatResearcherPrompt(task: ResearchTask): string {\n const sources = task.sources?.length ? task.sources.join(', ') : '(no preference)'\n const window = formatRecencyWindow(task.recencyWindow)\n return [\n `Question: ${task.question}`,\n `Knowledge namespace (DO NOT cross): ${task.knowledgeNamespace}`,\n `Scope: ${task.scope ?? '(unspecified)'}`,\n `Preferred sources: ${sources}`,\n `Recency window: ${window}`,\n `Max items: ${task.maxItems ?? '(no cap)'}`,\n `Per-item minimum confidence: ${task.minConfidence ?? '(no floor)'}`,\n '',\n 'Produce knowledge items with provenance + citations + proposed writes.',\n 'List gaps for anything you could not answer. Emit the final JSON',\n 'result block exactly as instructed.',\n ].join('\\n')\n}\n\nfunction formatRecencyWindow(window: ResearchTask['recencyWindow']): string {\n if (!window) return '(none)'\n const since = window.since ? window.since.toISOString() : '-∞'\n const until = window.until ? window.until.toISOString() : 'now'\n return `${since} .. ${until}`\n}\n\n/**\n * Walk the event stream and return the last structured `research.result`\n * payload. Falls back to scanning text deltas for a fenced JSON block.\n */\nfunction parseResearcherEvents(events: SandboxEvent[]): ResearchOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'research.result') {\n const direct = coerceResearchOutput(data.result ?? data.output ?? data)\n // opencode reports the agent's terminal answer in `finalText` (not result/output).\n // Parse it too, and prefer it when `direct` is an all-empty shape — otherwise an\n // event carrying both `{items:[],citations:[],proposedWrites:[]}` and a rich\n // finalText would silently drop the real answer.\n const finalText = pickString(data.finalText)\n const fenced = finalText ? extractFencedJson(finalText) : undefined\n const fromFinalText = fenced ? coerceResearchOutput(fenced) : undefined\n if (direct && !isEmptyOutput(direct)) return direct\n if (fromFinalText) return fromFinalText\n if (direct) return direct\n }\n }\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n const text = pickString(data.text) ?? pickString(data.delta) ?? pickString(data.finalText)\n if (!text) continue\n const fenced = extractFencedJson(text)\n if (!fenced) continue\n const coerced = coerceResearchOutput(fenced)\n if (coerced) return coerced\n }\n return { items: [], citations: [], proposedWrites: [] }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** A coerced output that carries no items, citations, or proposed writes. */\nfunction isEmptyOutput(o: ResearchOutput): boolean {\n return o.items.length === 0 && o.citations.length === 0 && o.proposedWrites.length === 0\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction extractFencedJson(text: string): unknown | undefined {\n const match = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)\n if (!match) return undefined\n const body = (match[1] ?? '').trim()\n if (!body) return undefined\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction coerceResearchOutput(value: unknown): ResearchOutput | undefined {\n if (!isRecord(value)) return undefined\n const items = coerceItems(value.items)\n const citations = coerceCitations(value.citations)\n const proposedWrites = coerceProposedWrites(value.proposedWrites)\n // Reject completely empty payloads — those signal \"no result block\",\n // not \"a valid empty result\".\n if (items === undefined && citations === undefined && proposedWrites === undefined) {\n return undefined\n }\n const output: ResearchOutput = {\n items: items ?? [],\n citations: citations ?? [],\n proposedWrites: proposedWrites ?? [],\n }\n if (Array.isArray(value.gaps)) {\n output.gaps = value.gaps.filter((entry): entry is string => typeof entry === 'string')\n }\n const notes = pickString(value.notes)\n if (notes) output.notes = notes\n // Preserve any extra fields the agent emitted that don't fit the typed\n // surface — callers can inspect `raw` without forcing them through the\n // typed coercion. We only include `raw` when the agent emitted fields\n // beyond the known set.\n const known = new Set(['items', 'citations', 'proposedWrites', 'gaps', 'notes'])\n const extras: Record<string, unknown> = {}\n let extrasCount = 0\n for (const [key, val] of Object.entries(value)) {\n if (known.has(key)) continue\n extras[key] = val\n extrasCount += 1\n }\n if (extrasCount > 0) output.raw = extras\n return output\n}\n\nfunction coerceItems(value: unknown): KnowledgeItem[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeItem[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const id = pickString(entry.id)\n const namespace = pickString(entry.namespace)\n const claim = pickString(entry.claim)\n const evidence = coerceEvidence(entry.evidence)\n const confidence = toFiniteNumber(entry.confidence)\n const authoredBy = coerceAuthoredBy(entry.authoredBy)\n if (!id || !namespace || !claim || !authoredBy) continue\n const item: KnowledgeItem = {\n id,\n namespace,\n claim,\n evidence,\n confidence: clamp01(confidence),\n authoredBy,\n }\n if (Array.isArray(entry.supersedes)) {\n item.supersedes = entry.supersedes.filter((s): s is string => typeof s === 'string')\n }\n const retractedAt = toFiniteNumber(entry.retractedAt)\n if (retractedAt > 0) item.retractedAt = retractedAt\n out.push(item)\n }\n return out\n}\n\nfunction coerceEvidence(value: unknown): KnowledgeItem['evidence'] {\n if (!Array.isArray(value)) return []\n const out: KnowledgeItem['evidence'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const source = pickString(entry.source)\n if (!source) continue\n const item: KnowledgeItem['evidence'][number] = {\n source,\n capturedAt: toFiniteNumber(entry.capturedAt),\n }\n const quote = pickString(entry.quote)\n if (quote) item.quote = quote\n const url = pickString(entry.url)\n if (url) item.url = url\n out.push(item)\n }\n return out\n}\n\nfunction coerceAuthoredBy(value: unknown): KnowledgeItem['authoredBy'] | undefined {\n if (!isRecord(value)) return undefined\n const kind = value.kind === 'human' || value.kind === 'agent' ? value.kind : undefined\n const id = pickString(value.id)\n if (!kind || !id) return undefined\n return { kind, id }\n}\n\nfunction coerceCitations(value: unknown): ResearchOutput['citations'] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: ResearchOutput['citations'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const url = pickString(entry.url)\n const quote = pickString(entry.quote)\n if (!url || !quote) continue\n out.push({ url, quote, confidence: clamp01(toFiniteNumber(entry.confidence)) })\n }\n return out\n}\n\nfunction coerceProposedWrites(value: unknown): KnowledgeUpdate[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeUpdate[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const namespace = pickString(entry.namespace)\n if (!namespace) continue\n if (entry.kind === 'insert') {\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!item) continue\n out.push({ kind: 'insert', namespace, item })\n } else if (entry.kind === 'supersede') {\n const previousId = pickString(entry.previousId)\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!previousId || !item) continue\n out.push({ kind: 'supersede', namespace, previousId, item })\n } else if (entry.kind === 'retract') {\n const itemId = pickString(entry.itemId)\n const reason = pickString(entry.reason)\n if (!itemId || !reason) continue\n out.push({ kind: 'retract', namespace, itemId, reason })\n }\n }\n return out\n}\n\nfunction toFiniteNumber(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n if (value < 0) return 0\n if (value > 1) return 1\n return value\n}\n","/**\n *\n * Per-lens guidance the auditor inlines into its system prompt for an\n * iteration. Each entry is a self-contained brief — the same content the\n * standalone ui-issue-finder skill ships, embedded as a string constant so\n * agent-runtime carries no runtime dep on that external workspace.\n *\n * Briefs are deliberately concrete: they enumerate the SIGNALS to look for\n * and the cross-lens distinctions to respect, so the judge files fewer\n * pile-on findings under generic labels.\n *\n * @experimental\n */\n\nimport type { UiLens } from './substrate'\n\n/** Cross-lens rules injected into every UI audit iteration: finding quality standards and scope limits. @experimental */\nexport const SHARED_AUDITOR_RULES = `\nYou are auditing a UI for a specific class of problems. Stay strictly in your assigned lens — do not file issues that belong to another lens (a separate iteration will catch those).\n\nA finding is only valid if a thoughtful product designer would agree the screenshot shows something that should change. Avoid:\n- Personal taste (\"I'd prefer brand blue\").\n- Hallucinated text or controls you cannot actually see in the screenshot.\n- Suggestions that depend on requirements you don't have access to.\n- Pile-on findings about the same root cause — file ONE finding and use \\`similarTo\\` to link the rest.\n\nRequired for every finding:\n- title: concrete, names the offending element AND what's wrong (NOT \"improve UX\").\n- severity: critical=blocks a core task or accessibility blocker; high=noticeable friction; med=visible polish issue; low=nitpick.\n- observation: 1–3 sentences describing exactly what you see that is wrong.\n- impact: who is affected and how (concrete).\n- suggestedFix: a specific change a developer could apply without asking you back.\n- screenshots: refer to the captures attached to this iteration by path.\n- selector: when you can pin the offending element with a CSS selector.\n\nMost findings are med or low. Reserve high/critical for genuine blockers.\n`.trim()\n\n/** Per-lens auditor briefs: concrete signals to look for and cross-lens distinctions to respect. @experimental */\nexport const LENS_BRIEFS: Record<UiLens, string> = {\n consistency: `\nLENS: consistency\nLook for inconsistencies in the design system — things that look like they came from different products glued together.\nSignals: multiple font families, inconsistent weights/sizes for the same role, two shades of \"primary\", arbitrary paddings/margins that don't snap to a scale (4/8/12/16/24), same control with different border-radius or shadow on different pages, mixed icon styles (filled vs outlined), inconsistent button heights/padding for the same variant, inconsistent capitalization (Title Case vs sentence case) for the same role.\nNOT this lens: layout misalignment (use \\`layout\\`), confusing user flow (use \\`ux-flow\\`), contrast/keyboard issues (use \\`accessibility\\`).\nTitle format: \\`Inconsistent <thing> between <A> and <B>\\`.\n`.trim(),\n hierarchy: `\nLENS: hierarchy\nLook for broken visual hierarchy — places where the eye does not land on what matters most.\nSignals: primary CTA same weight as secondary/tertiary controls, headings (H1/H2/H3) nearly the same size, important data buried (headline number smaller than its label), decoration outshining content, too many emphases competing, wrong scan order, missing or overly heavy section dividers.\nNOT this lens: same-role styled differently (\\`consistency\\`), grid/alignment (\\`layout\\`), contrast-failing text (\\`accessibility\\`).\nTitle format: \\`Weak hierarchy: <element> does not read as the <intended-role>\\`.\n`.trim(),\n layout: `\nLENS: layout\nLook for layout and organization problems — alignment, grouping, whitespace, structural choices that hurt scannability.\nSignals: misalignment within rows, inconsistent gutters in grids, orphan whitespace next to crammed regions, poor grouping (related fields separated, unrelated fields adjacent), no visual sections (long wall of content), container overflow (text/content punching out of card boundaries), cramped or oversized hit targets, sidebars/headers sized wrong relative to main content.\nNOT this lens: same-role styled differently (\\`consistency\\`), click-distance/friction (\\`ux-flow\\`), overflow specifically at small viewports (\\`responsive\\`).\nTitle format: \\`<Region> alignment/spacing problem\\` or \\`<Region> grouping unclear\\`.\n`.trim(),\n 'ux-flow': `\nLENS: ux-flow\nLook for interaction-flow friction — action sequences that are slower, more annoying, or more error-prone than necessary.\nSignals: sequential clicks far apart (e.g. Next top-right while user is bottom-left), destructive action adjacent to primary with same weight, confirmations that don't say what's being confirmed, primary CTA below the fold or hidden in a kebab menu, silent state changes (toggle gives no feedback), form ordering that fights real-world order, dead-end states after submit, lost inputs on back-navigation, hidden pre-selected options.\nNOT this lens: visual style only (\\`consistency\\`), component arrangement without a flow problem (\\`layout\\`), microcopy clarity (\\`content\\`).\nTitle format: \\`<Action A> → <Action B> friction: <root cause>\\`.\n`.trim(),\n duplication: `\nLENS: duplication\nLook for redundancy — the same control, link, or piece of content appearing more than once with no good reason.\nSignals: two ways to do the same action on the same screen with no difference, repeated nav (same links in sidebar AND top nav), drifted duplicates (two copies that have diverged), content repeated verbatim, icon + label saying the same thing twice in one row, per-row + bulk actions that overlap confusingly, multiple status indicators conveying the same status.\nNOT this lens: inconsistent styling of duplicates (\\`consistency\\`) — this lens is about the existence of duplicates.\nTitle format: \\`Duplicate <thing> in <location A> and <location B>\\`.\n`.trim(),\n accessibility: `\nLENS: accessibility\nLook for accessibility blockers and degradations. Be conservative — do not assume violations you cannot see.\nSignals: insufficient contrast on body text or controls, missing/invisible focus styles, tiny tap targets (<24px on mobile), color as sole signal (red border with no message), form labels missing or not associated (placeholders standing in for labels), broken heading order (H1 → H4), modals that don't trap focus, decorative elements that take focus, errors not announced, important text rendered inside images.\nNOT this lens: generic \"looks confusing\" (\\`hierarchy\\` or \\`content\\`), layout overflow at small viewports (\\`responsive\\`).\nTitle format: \\`Accessibility: <specific blocker> in <element>\\`.\n`.trim(),\n responsive: `\nLENS: responsive\nLook for layout breakage across viewport sizes — content that works at one width but degrades at another. This iteration's captures should include the same surface at >=2 viewports; compare across them.\nSignals: horizontal scroll where content should reflow, overlapping elements (header overlaps content, fixed footer covers inputs), desktop nav crammed into mobile without collapsing, table columns that don't truncate, tap targets too close at touch sizes, controls vanishing at certain widths, layout flips that break grouping order, modals exceeding viewport height (confirm button unreachable).\nNOT this lens: issues present at every viewport (\\`consistency\\` / \\`hierarchy\\` instead).\nTitle format: \\`<Element/Region> breaks at <viewport>\\`.\n`.trim(),\n states: `\nLENS: states\nLook for missing or broken UI states — the not-happy-paths that make a product feel finished or unfinished. The iteration's captures should depict at least one non-default state.\nSignals: empty lists with no guidance, skeletons that don't match final layout (CLS on settle), error states with no message or recovery action, disabled buttons with no explanation, toasts that disappear before being read, success states that don't confirm, missing hover/focus/active/disabled variants on primary controls, no long-content view, no-permission state broken.\nNOT this lens: generic polish on the happy path (other lenses), missing focus rings specifically (\\`accessibility\\`).\nTitle format: \\`Missing/broken <state> state on <surface>\\`.\n`.trim(),\n content: `\nLENS: content\nLook for microcopy and content problems — text that is unclear, inconsistent, condescending, jargon-heavy, or wrong.\nSignals: jargon/internal language leaking (\"Provisioning a Tenant\" instead of \"Setting up your account\"), inconsistent terminology (workspace vs team), verbose button labels, empty-state copy that's just \"No results\", error messages blaming the user, tone inconsistency, truncation without affordance, mixed date/number formats on one page, placeholder used as a label, \"Saved!\" toast appearing before save completes, typos and grammar errors.\nNOT this lens: visual treatment of text (\\`hierarchy\\` / \\`consistency\\`), missing labels for a11y (\\`accessibility\\`).\nTitle format: \\`Copy: \"<actual text>\" in <location>\\` or \\`Inconsistent term: \"<A>\" vs \"<B>\"\\`.\n`.trim(),\n interaction: `\nLENS: interaction\nLook for interaction quality problems — affordances, feedback, and micro-interactions.\nSignals: no affordance (clickable areas not looking clickable, non-clickable areas looking clickable), missing feedback (>100ms click with no progress), hover surprises (whole row highlights but only title clickable), cursor inconsistency, animations that block input, missing transitions where they're needed (accordion snaps open), drag-and-drop without indicators, scroll-jacking, click-through bugs (card click handler firing alongside button), hover-only revelations on touch.\nNOT this lens: position of controls (\\`layout\\` / \\`ux-flow\\`), missing focus styles (\\`accessibility\\`).\nTitle format: \\`<Action> on <element>: <missing/wrong> feedback\\`.\n`.trim(),\n 'performance-perceived': `\nLENS: performance-perceived\nLook for perceived-performance problems — visible jank a real user would notice, not benchmark numbers. This iteration's captures should include >=2 frames during load to show shift.\nSignals: layout shift (CLS) when late-arriving images/fonts/banners settle, FOUC (flash of unstyled content), font swap jumps, late-loading hero images that shift everything, skeletons that don't match final shape, spinners on instant local actions, loading state reappearing after content paints (refetch on focus), modal open animation longer than the operation it precedes.\nNOT this lens: slow API calls (file separately), stale data after navigation (\\`states\\`).\nTitle format: \\`Layout shift / late paint on <route>: <root cause>\\`.\n`.trim(),\n other: `\nLENS: other\nUse ONLY when a finding is clearly a UI quality issue but does not fit any other lens. Strongly prefer a specific lens — \\`other\\` should be rare. Title must still be concrete.\n`.trim(),\n}\n\n/**\n * Build a system prompt for a single auditor iteration.\n *\n * @experimental\n */\nexport function buildAuditorSystemPrompt(lens: UiLens): string {\n const brief = LENS_BRIEFS[lens]\n return `${SHARED_AUDITOR_RULES}\\n\\n${brief}`\n}\n","/**\n *\n * Sandbox-event stream → UiAuditOutput decoder. The custom auditor\n * `SandboxClient` emits events of the form:\n *\n * { type: 'audit.capture', data: UiAuditCapture }\n * { type: 'audit.finding', data: UiFinding }\n * { type: 'audit.notes', data: { notes: string } }\n * { type: 'audit.lens', data: { lens: UiLens } }\n * { type: 'done', data: { tokenUsage: { ... }, totalCostUsd?: number } }\n *\n * Other event types are tolerated and ignored. The adapter is pure: it\n * folds an already-collected event array into a UiAuditOutput.\n *\n * @experimental\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { UI_LENSES, type UiFinding, type UiLens } from './substrate'\nimport type { UiAuditCapture, UiAuditOutput } from './task'\n\n// Build the lens-validation set from the canonical UI_LENSES tuple so adding\n// a lens to the substrate automatically extends the parser; otherwise a new\n// lens would silently fail isUiLens() and parseAuditorEvents would drop\n// every event using it.\nconst KNOWN_LENS_VALUES = new Set<UiLens>(UI_LENSES)\n\nfunction isUiLens(v: unknown): v is UiLens {\n return typeof v === 'string' && KNOWN_LENS_VALUES.has(v as UiLens)\n}\n\n/** Parse raw `SandboxEvent` emissions from an audit iteration into structured `UiAuditOutput`. @experimental */\nexport function parseAuditorEvents(events: SandboxEvent[]): UiAuditOutput {\n const findings: UiFinding[] = []\n const captures: UiAuditCapture[] = []\n let lens: UiLens | undefined\n let notes: string | undefined\n\n for (const evt of events) {\n if (!evt || typeof evt !== 'object') continue\n const type = String(evt.type ?? '')\n const data =\n evt.data && typeof evt.data === 'object' ? (evt.data as Record<string, unknown>) : undefined\n if (!data) continue\n\n switch (type) {\n case 'audit.lens': {\n const v = data.lens\n if (isUiLens(v)) lens = v\n break\n }\n case 'audit.capture': {\n const cap = data as unknown as Partial<UiAuditCapture>\n if (\n typeof cap.path === 'string' &&\n typeof cap.viewport === 'string' &&\n typeof cap.fullPage === 'boolean' &&\n typeof cap.route === 'string' &&\n typeof cap.url === 'string' &&\n typeof cap.capturedAt === 'string'\n ) {\n const out: UiAuditCapture = {\n path: cap.path,\n viewport: cap.viewport,\n fullPage: cap.fullPage,\n route: cap.route,\n url: cap.url,\n capturedAt: cap.capturedAt,\n }\n if (cap.elementSelector) out.elementSelector = cap.elementSelector\n if (cap.label) out.label = cap.label\n captures.push(out)\n }\n break\n }\n case 'audit.finding': {\n const f = data as unknown as Partial<UiFinding>\n // Hard requirement: all the actionable fields must be present and\n // non-empty for a finding to enter the output. The validator does the\n // softer scoring; the adapter only filters structural junk.\n if (\n typeof f.title === 'string' &&\n f.title.trim().length > 0 &&\n isUiLens(f.lens) &&\n typeof f.severity === 'string' &&\n ['low', 'med', 'high', 'critical'].includes(f.severity) &&\n typeof f.route === 'string' &&\n typeof f.observation === 'string' &&\n typeof f.impact === 'string' &&\n typeof f.suggestedFix === 'string' &&\n Array.isArray(f.screenshots)\n ) {\n findings.push(f as UiFinding)\n }\n break\n }\n case 'audit.notes': {\n const n = data.notes\n if (typeof n === 'string' && n.trim().length > 0) notes = n\n break\n }\n default:\n // Tolerate cost/usage events and other backend chatter — extractLlmCallEvent\n // in run-loop.ts handles cost accounting upstream from the adapter.\n break\n }\n }\n\n const out: UiAuditOutput = { lens: lens ?? 'other', findings, captures }\n if (notes) out.notes = notes\n return out\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"profiles.js","names":[],"sources":["../src/profiles/researcher.ts","../src/profiles/ui-auditor/lens-prompts.ts","../src/profiles/ui-auditor/output-adapter.ts"],"sourcesContent":["/**\n * Opinionated preset for source-grounded research\n * tasks. The agent is told to:\n * - bound its work to a single `knowledgeNamespace`\n * - emit `items[]` carrying provenance + confidence\n * - emit `citations[]` linking quotes back to source urls\n * - emit `proposedWrites[]` — never call materialize itself\n * - describe `gaps` it could not answer\n *\n * The profile is stateless and agent-agnostic. The caller supplies the exact execution profile;\n * this preset adds only the researcher prompt, tools, parser, and validator.\n *\n * Propose-don't-apply: the profile NEVER writes to the knowledge base.\n * It produces `proposedWrites: KnowledgeUpdate[]` in the output. The\n * caller (gtm-agent, journey-eval, user) decides whether to feed those\n * updates through `applyKnowledgeWriteBlocks` / a KbStore put.\n *\n * Namespace isolation: every `KnowledgeItem` + `KnowledgeUpdate` in the\n * output carries `namespace`. The validator hard-fails when any item\n * touches a namespace other than `task.knowledgeNamespace`.\n *\n * @experimental\n */\n\nimport { type AgentProfile, agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { ConfigError } from '../errors'\nimport { isRecord } from '../record-value'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type {\n AgentRunSpec,\n DefaultVerdict,\n Driver,\n OutputAdapter,\n Validator,\n} from '../runtime/types'\n\n/** Source families a researcher profile may prefer for a task. One owner: the delegation\n * vocabulary (`DelegateResearchArgs.sources`) re-exports this type rather than restating it.\n * @experimental */\nexport type ResearchSource = 'web' | 'corpus' | 'twitter' | 'github' | 'docs'\n\n/** Task contract for a source-grounded research agent. @experimental */\nexport interface ResearchTask {\n /** The research question to answer. */\n question: string\n /** Bound: e.g. \"audience for cpg-founder ICP\". */\n scope?: string\n /** Multi-tenant scope (customer-id, workspace-id). Validator enforces. */\n knowledgeNamespace: string\n sources?: ResearchSource[]\n recencyWindow?: { since?: Date; until?: Date }\n maxItems?: number\n /** Per-item minimum confidence in [0, 1]. Validator scores recall vs this. */\n minConfidence?: number\n}\n\n/**\n * Knowledge item emitted by the researcher.\n *\n * Profile-local type. When agent-knowledge promotes `KnowledgeClaim` →\n * top-level `KnowledgeItem` substrate-wide, these fields collapse 1:1.\n *\n * @experimental\n */\nexport interface KnowledgeItem {\n id: string\n /** Multi-tenant scope. MUST equal `task.knowledgeNamespace`. */\n namespace: string\n /** The factual claim, in the researcher's words. */\n claim: string\n /** Provenance — at least one entry required. */\n evidence: Array<{ source: string; quote?: string; url?: string; capturedAt: number }>\n /** Researcher's self-reported confidence in [0, 1]. */\n confidence: number\n /** Prior item ids this supersedes (chain). */\n supersedes?: string[]\n /** Set if the agent is retracting an earlier item. Unix ms. */\n retractedAt?: number\n authoredBy: { kind: 'human' | 'agent'; id: string }\n}\n\n/**\n * A proposed write to the knowledge base. The profile does NOT apply\n * these — the caller decides.\n *\n * @experimental\n */\nexport type KnowledgeUpdate =\n | { kind: 'insert'; namespace: string; item: KnowledgeItem }\n | { kind: 'supersede'; namespace: string; previousId: string; item: KnowledgeItem }\n | { kind: 'retract'; namespace: string; itemId: string; reason: string }\n\n/**\n * Researcher output. Required fields are typed; optional fields preserve\n * the agent's free-form intelligence (`notes`, `raw`). The validator\n * enforces the typed minimum.\n *\n * @experimental\n */\nexport interface ResearchOutput {\n items: KnowledgeItem[]\n citations: Array<{ url: string; quote: string; confidence: number }>\n proposedWrites: KnowledgeUpdate[]\n gaps?: string[]\n notes?: string\n /** Anything the agent emitted beyond the typed fields. */\n raw?: unknown\n}\n\n/** Options for the source-grounded researcher profile preset. @experimental */\nexport interface ResearcherProfileOptions {\n /** Caller-owned exact harness/provider/model identity. */\n profile: AgentProfile\n /** Custom system prompt replacement. Default = built-in researcher preset. */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `profile.name`. */\n name?: string\n /**\n * Default 0.7. Minimum (citations with quote) / items ratio for `valid=true`.\n * Below this floor, citation_density scores < 1 and the item set is gated.\n */\n citationDensityMin?: number\n}\n\nconst DEFAULT_CITATION_DENSITY_MIN = 0.7\n\n/** Build a source-grounded researcher profile with output parsing and validation. @experimental */\nexport function researcherProfile(options: ResearcherProfileOptions & { task?: ResearchTask }): {\n profile: AgentProfile\n taskToPrompt: (task: ResearchTask) => string\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n agentRunSpec: AgentRunSpec<ResearchTask>\n} {\n const base = agentProfileSchema.parse(options.profile) as AgentProfile\n assertExecutableAgentProfile(base, 'researcherProfile')\n const name = options.name ?? base.name\n const systemPrompt = options.systemPrompt ?? RESEARCHER_SYSTEM_PROMPT\n const citationDensityMin = options.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const profile: AgentProfile = {\n ...base,\n name,\n description: base.description ?? \"Source-grounded research agent. Propose-don't-apply.\",\n prompt: { ...base.prompt, systemPrompt },\n tools: { web_search: true, fs: true, shell: true, ...base.tools },\n metadata: { ...base.metadata, specialty: 'researcher' },\n }\n const output: OutputAdapter<ResearchOutput> = { parse: parseResearcherEvents }\n const validator: Validator<ResearchOutput> = options.task\n ? createResearcherValidator(options.task, { citationDensityMin })\n : createResearcherValidator(\n { question: '', knowledgeNamespace: '' },\n { citationDensityMin, namespaceCheck: false },\n )\n const agentRunSpec: AgentRunSpec<ResearchTask> = {\n name,\n profile,\n taskToPrompt: formatResearcherPrompt,\n }\n return { profile, taskToPrompt: formatResearcherPrompt, output, validator, agentRunSpec }\n}\n\n/** @experimental */\ninterface MultiHarnessResearcherFanoutOptions {\n /** Exact execution profiles, one per parallel researcher. */\n profiles: ReadonlyArray<AgentProfile>\n /** Default citation density floor for the shared validator. */\n citationDensityMin?: number\n /** Optional task — narrows the validator's namespace check. */\n task?: ResearchTask\n}\n\n/**\n * Build a fanout topology over multiple harnesses. The kernel round-robins\n * `agentRuns` across the N parallel iterations and the `FanoutVote` driver\n * picks the highest-scoring valid output.\n *\n * @experimental\n */\nexport function multiHarnessResearcherFanout(options: MultiHarnessResearcherFanoutOptions): {\n agentRuns: AgentRunSpec<ResearchTask>[]\n output: OutputAdapter<ResearchOutput>\n validator: Validator<ResearchOutput>\n driver: Driver<ResearchTask, ResearchOutput, 'done'>\n} {\n if (options.profiles.length === 0) {\n throw new ConfigError('multiHarnessResearcherFanout: at least one exact profile is required')\n }\n const agentRuns = options.profiles.map((profile) => {\n const { agentRunSpec } = researcherProfile({ profile })\n return agentRunSpec\n })\n const { output, validator } = researcherProfile({\n profile: options.profiles[0]!,\n citationDensityMin: options.citationDensityMin,\n task: options.task,\n })\n // Single fanout round across the N harnesses, then stop: the kernel\n // round-robins `agentRuns` over the N branches and selects the winner\n // (best valid score) across all iterations via `defaultSelectWinner`.\n const driver: Driver<ResearchTask, ResearchOutput, 'done'> = {\n name: 'researcher-fanout',\n async plan(task, history) {\n return history.length === 0 ? Array.from({ length: agentRuns.length }, () => task) : []\n },\n // 'done' is a terminal decision in the kernel; the loop finalizes after\n // the single fanout round and selects the winner via `defaultSelectWinner`.\n decide() {\n return 'done'\n },\n describePlan() {\n return { kind: 'fanout' }\n },\n }\n return { agentRuns, output, validator, driver }\n}\n\n/**\n * Build a validator that closes over a specific `ResearchTask`'s constraints.\n *\n * Checks in order:\n * 1. Items must be non-empty.\n * 2. Every item carries `evidence.length >= 1`.\n * 3. Every item + proposedWrite is scoped to `task.knowledgeNamespace`\n * (hard-fail on any namespace mismatch — defence in depth for the\n * multi-tenant invariant).\n * 4. Citation density (citations with quote / items) >= floor.\n *\n * Aggregate score:\n * 0.4 · citation_density\n * + 0.2 · source_diversity (distinct sources / max(items, 1))\n * + 0.2 · recency_match (mean fraction within `recencyWindow`)\n * + 0.2 · (1 − gaps/maxGaps), maxGaps = max(items, 1)\n *\n * @experimental\n */\nfunction createResearcherValidator(\n task: ResearchTask,\n config: { citationDensityMin?: number; namespaceCheck?: boolean } = {},\n): Validator<ResearchOutput> {\n const citationDensityMin = config.citationDensityMin ?? DEFAULT_CITATION_DENSITY_MIN\n const namespaceCheck = config.namespaceCheck ?? true\n return {\n async validate(output) {\n const notes: string[] = []\n const scores: Record<string, number> = {}\n let pass = true\n\n if (!Array.isArray(output.items) || output.items.length === 0) {\n pass = false\n notes.push('no items')\n scores.items = 0\n } else {\n scores.items = 1\n }\n\n const missingEvidence = (output.items ?? []).filter(\n (item) => !Array.isArray(item.evidence) || item.evidence.length === 0,\n )\n if (missingEvidence.length > 0) {\n pass = false\n notes.push(`${missingEvidence.length} item(s) without evidence`)\n scores.provenance = 0\n } else {\n scores.provenance = 1\n }\n\n if (namespaceCheck) {\n const foreignItems = (output.items ?? []).filter(\n (item) => item.namespace !== task.knowledgeNamespace,\n )\n const foreignWrites = (output.proposedWrites ?? []).filter(\n (write) => write.namespace !== task.knowledgeNamespace,\n )\n if (foreignItems.length > 0 || foreignWrites.length > 0) {\n pass = false\n notes.push(\n `namespace violation: ${foreignItems.length} item(s) + ${foreignWrites.length} write(s) ` +\n `outside ${task.knowledgeNamespace}`,\n )\n scores.namespace = 0\n } else {\n scores.namespace = 1\n }\n }\n\n const itemCount = Math.max(output.items?.length ?? 0, 1)\n const citationsWithQuote = (output.citations ?? []).filter(\n (citation) => typeof citation.quote === 'string' && citation.quote.length > 0,\n ).length\n const citationDensity = Math.min(1, citationsWithQuote / itemCount)\n if (citationDensity < citationDensityMin) {\n pass = false\n notes.push(\n `citation density ${citationDensity.toFixed(2)} below floor ${citationDensityMin.toFixed(2)}`,\n )\n }\n scores.citation_density = citationDensity\n\n const sourceSet = new Set<string>()\n for (const item of output.items ?? []) {\n for (const evidence of item.evidence ?? []) {\n if (evidence.source) sourceSet.add(evidence.source)\n }\n }\n scores.source_diversity = Math.min(1, sourceSet.size / itemCount)\n\n scores.recency_match = recencyMatchScore(output.items ?? [], task.recencyWindow)\n\n const maxGaps = itemCount\n const gapCount = output.gaps?.length ?? 0\n scores.gap_coverage = Math.max(0, 1 - gapCount / maxGaps)\n\n const score =\n 0.4 * scores.citation_density +\n 0.2 * scores.source_diversity +\n 0.2 * scores.recency_match +\n 0.2 * scores.gap_coverage\n\n const verdict: DefaultVerdict = {\n valid: pass,\n score: Number.isFinite(score) ? score : 0,\n scores,\n }\n if (notes.length > 0) verdict.notes = notes.join('; ')\n return verdict\n },\n }\n}\n\nfunction recencyMatchScore(items: KnowledgeItem[], window: ResearchTask['recencyWindow']): number {\n if (!window || (window.since === undefined && window.until === undefined)) return 1\n if (items.length === 0) return 0\n const sinceMs = window.since?.getTime() ?? Number.NEGATIVE_INFINITY\n const untilMs = window.until?.getTime() ?? Number.POSITIVE_INFINITY\n let hits = 0\n let total = 0\n for (const item of items) {\n for (const evidence of item.evidence ?? []) {\n if (typeof evidence.capturedAt !== 'number') continue\n total += 1\n if (evidence.capturedAt >= sinceMs && evidence.capturedAt <= untilMs) hits += 1\n }\n }\n return total === 0 ? 0 : hits / total\n}\n\n/** Built-in source-grounded research contract added to a caller-owned exact profile. */\nconst RESEARCHER_SYSTEM_PROMPT = [\n 'You are a research agent. Your job is to answer a research question with',\n 'source-grounded knowledge items that the caller will choose whether to',\n 'persist to a multi-tenant knowledge base.',\n '',\n 'Hard rules:',\n \" 1. Every item you emit MUST carry the task's knowledgeNamespace exactly.\",\n ' Never write to a different namespace.',\n ' 2. Every item MUST carry at least one evidence entry with a source.',\n ' A quote + url is strongly preferred; capturedAt is unix ms.',\n ' 3. You propose writes — you do NOT apply them. The caller decides.',\n ' 4. Self-report confidence honestly in [0, 1]. Do not inflate.',\n ' 5. List what you could not answer in `gaps`. Better to admit a gap',\n ' than fabricate.',\n '',\n 'When you finish, emit a single final structured message of the shape:',\n ' ```json',\n ' { \"items\": [{ \"id\": \"...\", \"namespace\": \"...\", \"claim\": \"...\",',\n ' \"evidence\": [{ \"source\": \"...\", \"quote\": \"...\",',\n ' \"url\": \"...\", \"capturedAt\": 0 }],',\n ' \"confidence\": 0.0,',\n ' \"authoredBy\": { \"kind\": \"agent\", \"id\": \"...\" } }],',\n ' \"citations\": [{ \"url\": \"...\", \"quote\": \"...\", \"confidence\": 0.0 }],',\n ' \"proposedWrites\": [{ \"kind\": \"insert\", \"namespace\": \"...\",',\n ' \"item\": { /* same shape as items[] */ } }],',\n ' \"gaps\": [\"...\"],',\n ' \"notes\": \"free-form commentary\" }',\n ' ```',\n].join('\\n')\n\nfunction formatResearcherPrompt(task: ResearchTask): string {\n const sources = task.sources?.length ? task.sources.join(', ') : '(no preference)'\n const window = formatRecencyWindow(task.recencyWindow)\n return [\n `Question: ${task.question}`,\n `Knowledge namespace (DO NOT cross): ${task.knowledgeNamespace}`,\n `Scope: ${task.scope ?? '(unspecified)'}`,\n `Preferred sources: ${sources}`,\n `Recency window: ${window}`,\n `Max items: ${task.maxItems ?? '(no cap)'}`,\n `Per-item minimum confidence: ${task.minConfidence ?? '(no floor)'}`,\n '',\n 'Produce knowledge items with provenance + citations + proposed writes.',\n 'List gaps for anything you could not answer. Emit the final JSON',\n 'result block exactly as instructed.',\n ].join('\\n')\n}\n\nfunction formatRecencyWindow(window: ResearchTask['recencyWindow']): string {\n if (!window) return '(none)'\n const since = window.since ? window.since.toISOString() : '-∞'\n const until = window.until ? window.until.toISOString() : 'now'\n return `${since} .. ${until}`\n}\n\n/**\n * Walk the event stream and return the last structured `research.result`\n * payload. Falls back to scanning text deltas for a fenced JSON block.\n */\nfunction parseResearcherEvents(events: SandboxEvent[]): ResearchOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'research.result') {\n const direct = coerceResearchOutput(data.result ?? data.output ?? data)\n // opencode reports the agent's terminal answer in `finalText` (not result/output).\n // Parse it too, and prefer it when `direct` is an all-empty shape — otherwise an\n // event carrying both `{items:[],citations:[],proposedWrites:[]}` and a rich\n // finalText would silently drop the real answer.\n const finalText = pickString(data.finalText)\n const fenced = finalText ? extractFencedJson(finalText) : undefined\n const fromFinalText = fenced ? coerceResearchOutput(fenced) : undefined\n if (direct && !isEmptyOutput(direct)) return direct\n if (fromFinalText) return fromFinalText\n if (direct) return direct\n }\n }\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n const text = pickString(data.text) ?? pickString(data.delta) ?? pickString(data.finalText)\n if (!text) continue\n const fenced = extractFencedJson(text)\n if (!fenced) continue\n const coerced = coerceResearchOutput(fenced)\n if (coerced) return coerced\n }\n return { items: [], citations: [], proposedWrites: [] }\n}\n\n/** A coerced output that carries no items, citations, or proposed writes. */\nfunction isEmptyOutput(o: ResearchOutput): boolean {\n return o.items.length === 0 && o.citations.length === 0 && o.proposedWrites.length === 0\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction extractFencedJson(text: string): unknown | undefined {\n const match = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)\n if (!match) return undefined\n const body = (match[1] ?? '').trim()\n if (!body) return undefined\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction coerceResearchOutput(value: unknown): ResearchOutput | undefined {\n if (!isRecord(value)) return undefined\n const items = coerceItems(value.items)\n const citations = coerceCitations(value.citations)\n const proposedWrites = coerceProposedWrites(value.proposedWrites)\n // Reject completely empty payloads — those signal \"no result block\",\n // not \"a valid empty result\".\n if (items === undefined && citations === undefined && proposedWrites === undefined) {\n return undefined\n }\n const output: ResearchOutput = {\n items: items ?? [],\n citations: citations ?? [],\n proposedWrites: proposedWrites ?? [],\n }\n if (Array.isArray(value.gaps)) {\n output.gaps = value.gaps.filter((entry): entry is string => typeof entry === 'string')\n }\n const notes = pickString(value.notes)\n if (notes) output.notes = notes\n // Preserve any extra fields the agent emitted that don't fit the typed\n // surface — callers can inspect `raw` without forcing them through the\n // typed coercion. We only include `raw` when the agent emitted fields\n // beyond the known set.\n const known = new Set(['items', 'citations', 'proposedWrites', 'gaps', 'notes'])\n const extras: Record<string, unknown> = {}\n let extrasCount = 0\n for (const [key, val] of Object.entries(value)) {\n if (known.has(key)) continue\n extras[key] = val\n extrasCount += 1\n }\n if (extrasCount > 0) output.raw = extras\n return output\n}\n\nfunction coerceItems(value: unknown): KnowledgeItem[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeItem[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const id = pickString(entry.id)\n const namespace = pickString(entry.namespace)\n const claim = pickString(entry.claim)\n const evidence = coerceEvidence(entry.evidence)\n const confidence = toFiniteNumber(entry.confidence)\n const authoredBy = coerceAuthoredBy(entry.authoredBy)\n if (!id || !namespace || !claim || !authoredBy) continue\n const item: KnowledgeItem = {\n id,\n namespace,\n claim,\n evidence,\n confidence: clamp01(confidence),\n authoredBy,\n }\n if (Array.isArray(entry.supersedes)) {\n item.supersedes = entry.supersedes.filter((s): s is string => typeof s === 'string')\n }\n const retractedAt = toFiniteNumber(entry.retractedAt)\n if (retractedAt > 0) item.retractedAt = retractedAt\n out.push(item)\n }\n return out\n}\n\nfunction coerceEvidence(value: unknown): KnowledgeItem['evidence'] {\n if (!Array.isArray(value)) return []\n const out: KnowledgeItem['evidence'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const source = pickString(entry.source)\n if (!source) continue\n const item: KnowledgeItem['evidence'][number] = {\n source,\n capturedAt: toFiniteNumber(entry.capturedAt),\n }\n const quote = pickString(entry.quote)\n if (quote) item.quote = quote\n const url = pickString(entry.url)\n if (url) item.url = url\n out.push(item)\n }\n return out\n}\n\nfunction coerceAuthoredBy(value: unknown): KnowledgeItem['authoredBy'] | undefined {\n if (!isRecord(value)) return undefined\n const kind = value.kind === 'human' || value.kind === 'agent' ? value.kind : undefined\n const id = pickString(value.id)\n if (!kind || !id) return undefined\n return { kind, id }\n}\n\nfunction coerceCitations(value: unknown): ResearchOutput['citations'] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: ResearchOutput['citations'] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const url = pickString(entry.url)\n const quote = pickString(entry.quote)\n if (!url || !quote) continue\n out.push({ url, quote, confidence: clamp01(toFiniteNumber(entry.confidence)) })\n }\n return out\n}\n\nfunction coerceProposedWrites(value: unknown): KnowledgeUpdate[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out: KnowledgeUpdate[] = []\n for (const entry of value) {\n if (!isRecord(entry)) continue\n const namespace = pickString(entry.namespace)\n if (!namespace) continue\n if (entry.kind === 'insert') {\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!item) continue\n out.push({ kind: 'insert', namespace, item })\n } else if (entry.kind === 'supersede') {\n const previousId = pickString(entry.previousId)\n const items = coerceItems([entry.item])\n const item = items?.[0]\n if (!previousId || !item) continue\n out.push({ kind: 'supersede', namespace, previousId, item })\n } else if (entry.kind === 'retract') {\n const itemId = pickString(entry.itemId)\n const reason = pickString(entry.reason)\n if (!itemId || !reason) continue\n out.push({ kind: 'retract', namespace, itemId, reason })\n }\n }\n return out\n}\n\nfunction toFiniteNumber(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n if (value < 0) return 0\n if (value > 1) return 1\n return value\n}\n","/**\n *\n * Per-lens guidance the auditor inlines into its system prompt for an\n * iteration. Each entry is a self-contained brief — the same content the\n * standalone ui-issue-finder skill ships, embedded as a string constant so\n * agent-runtime carries no runtime dep on that external workspace.\n *\n * Briefs are deliberately concrete: they enumerate the SIGNALS to look for\n * and the cross-lens distinctions to respect, so the judge files fewer\n * pile-on findings under generic labels.\n *\n * @experimental\n */\n\nimport type { UiLens } from './substrate'\n\n/** Cross-lens rules injected into every UI audit iteration: finding quality standards and scope limits. @experimental */\nexport const SHARED_AUDITOR_RULES = `\nYou are auditing a UI for a specific class of problems. Stay strictly in your assigned lens — do not file issues that belong to another lens (a separate iteration will catch those).\n\nA finding is only valid if a thoughtful product designer would agree the screenshot shows something that should change. Avoid:\n- Personal taste (\"I'd prefer brand blue\").\n- Hallucinated text or controls you cannot actually see in the screenshot.\n- Suggestions that depend on requirements you don't have access to.\n- Pile-on findings about the same root cause — file ONE finding and use \\`similarTo\\` to link the rest.\n\nRequired for every finding:\n- title: concrete, names the offending element AND what's wrong (NOT \"improve UX\").\n- severity: critical=blocks a core task or accessibility blocker; high=noticeable friction; med=visible polish issue; low=nitpick.\n- observation: 1–3 sentences describing exactly what you see that is wrong.\n- impact: who is affected and how (concrete).\n- suggestedFix: a specific change a developer could apply without asking you back.\n- screenshots: refer to the captures attached to this iteration by path.\n- selector: when you can pin the offending element with a CSS selector.\n\nMost findings are med or low. Reserve high/critical for genuine blockers.\n`.trim()\n\n/** Per-lens auditor briefs: concrete signals to look for and cross-lens distinctions to respect. @experimental */\nexport const LENS_BRIEFS: Record<UiLens, string> = {\n consistency: `\nLENS: consistency\nLook for inconsistencies in the design system — things that look like they came from different products glued together.\nSignals: multiple font families, inconsistent weights/sizes for the same role, two shades of \"primary\", arbitrary paddings/margins that don't snap to a scale (4/8/12/16/24), same control with different border-radius or shadow on different pages, mixed icon styles (filled vs outlined), inconsistent button heights/padding for the same variant, inconsistent capitalization (Title Case vs sentence case) for the same role.\nNOT this lens: layout misalignment (use \\`layout\\`), confusing user flow (use \\`ux-flow\\`), contrast/keyboard issues (use \\`accessibility\\`).\nTitle format: \\`Inconsistent <thing> between <A> and <B>\\`.\n`.trim(),\n hierarchy: `\nLENS: hierarchy\nLook for broken visual hierarchy — places where the eye does not land on what matters most.\nSignals: primary CTA same weight as secondary/tertiary controls, headings (H1/H2/H3) nearly the same size, important data buried (headline number smaller than its label), decoration outshining content, too many emphases competing, wrong scan order, missing or overly heavy section dividers.\nNOT this lens: same-role styled differently (\\`consistency\\`), grid/alignment (\\`layout\\`), contrast-failing text (\\`accessibility\\`).\nTitle format: \\`Weak hierarchy: <element> does not read as the <intended-role>\\`.\n`.trim(),\n layout: `\nLENS: layout\nLook for layout and organization problems — alignment, grouping, whitespace, structural choices that hurt scannability.\nSignals: misalignment within rows, inconsistent gutters in grids, orphan whitespace next to crammed regions, poor grouping (related fields separated, unrelated fields adjacent), no visual sections (long wall of content), container overflow (text/content punching out of card boundaries), cramped or oversized hit targets, sidebars/headers sized wrong relative to main content.\nNOT this lens: same-role styled differently (\\`consistency\\`), click-distance/friction (\\`ux-flow\\`), overflow specifically at small viewports (\\`responsive\\`).\nTitle format: \\`<Region> alignment/spacing problem\\` or \\`<Region> grouping unclear\\`.\n`.trim(),\n 'ux-flow': `\nLENS: ux-flow\nLook for interaction-flow friction — action sequences that are slower, more annoying, or more error-prone than necessary.\nSignals: sequential clicks far apart (e.g. Next top-right while user is bottom-left), destructive action adjacent to primary with same weight, confirmations that don't say what's being confirmed, primary CTA below the fold or hidden in a kebab menu, silent state changes (toggle gives no feedback), form ordering that fights real-world order, dead-end states after submit, lost inputs on back-navigation, hidden pre-selected options.\nNOT this lens: visual style only (\\`consistency\\`), component arrangement without a flow problem (\\`layout\\`), microcopy clarity (\\`content\\`).\nTitle format: \\`<Action A> → <Action B> friction: <root cause>\\`.\n`.trim(),\n duplication: `\nLENS: duplication\nLook for redundancy — the same control, link, or piece of content appearing more than once with no good reason.\nSignals: two ways to do the same action on the same screen with no difference, repeated nav (same links in sidebar AND top nav), drifted duplicates (two copies that have diverged), content repeated verbatim, icon + label saying the same thing twice in one row, per-row + bulk actions that overlap confusingly, multiple status indicators conveying the same status.\nNOT this lens: inconsistent styling of duplicates (\\`consistency\\`) — this lens is about the existence of duplicates.\nTitle format: \\`Duplicate <thing> in <location A> and <location B>\\`.\n`.trim(),\n accessibility: `\nLENS: accessibility\nLook for accessibility blockers and degradations. Be conservative — do not assume violations you cannot see.\nSignals: insufficient contrast on body text or controls, missing/invisible focus styles, tiny tap targets (<24px on mobile), color as sole signal (red border with no message), form labels missing or not associated (placeholders standing in for labels), broken heading order (H1 → H4), modals that don't trap focus, decorative elements that take focus, errors not announced, important text rendered inside images.\nNOT this lens: generic \"looks confusing\" (\\`hierarchy\\` or \\`content\\`), layout overflow at small viewports (\\`responsive\\`).\nTitle format: \\`Accessibility: <specific blocker> in <element>\\`.\n`.trim(),\n responsive: `\nLENS: responsive\nLook for layout breakage across viewport sizes — content that works at one width but degrades at another. This iteration's captures should include the same surface at >=2 viewports; compare across them.\nSignals: horizontal scroll where content should reflow, overlapping elements (header overlaps content, fixed footer covers inputs), desktop nav crammed into mobile without collapsing, table columns that don't truncate, tap targets too close at touch sizes, controls vanishing at certain widths, layout flips that break grouping order, modals exceeding viewport height (confirm button unreachable).\nNOT this lens: issues present at every viewport (\\`consistency\\` / \\`hierarchy\\` instead).\nTitle format: \\`<Element/Region> breaks at <viewport>\\`.\n`.trim(),\n states: `\nLENS: states\nLook for missing or broken UI states — the not-happy-paths that make a product feel finished or unfinished. The iteration's captures should depict at least one non-default state.\nSignals: empty lists with no guidance, skeletons that don't match final layout (CLS on settle), error states with no message or recovery action, disabled buttons with no explanation, toasts that disappear before being read, success states that don't confirm, missing hover/focus/active/disabled variants on primary controls, no long-content view, no-permission state broken.\nNOT this lens: generic polish on the happy path (other lenses), missing focus rings specifically (\\`accessibility\\`).\nTitle format: \\`Missing/broken <state> state on <surface>\\`.\n`.trim(),\n content: `\nLENS: content\nLook for microcopy and content problems — text that is unclear, inconsistent, condescending, jargon-heavy, or wrong.\nSignals: jargon/internal language leaking (\"Provisioning a Tenant\" instead of \"Setting up your account\"), inconsistent terminology (workspace vs team), verbose button labels, empty-state copy that's just \"No results\", error messages blaming the user, tone inconsistency, truncation without affordance, mixed date/number formats on one page, placeholder used as a label, \"Saved!\" toast appearing before save completes, typos and grammar errors.\nNOT this lens: visual treatment of text (\\`hierarchy\\` / \\`consistency\\`), missing labels for a11y (\\`accessibility\\`).\nTitle format: \\`Copy: \"<actual text>\" in <location>\\` or \\`Inconsistent term: \"<A>\" vs \"<B>\"\\`.\n`.trim(),\n interaction: `\nLENS: interaction\nLook for interaction quality problems — affordances, feedback, and micro-interactions.\nSignals: no affordance (clickable areas not looking clickable, non-clickable areas looking clickable), missing feedback (>100ms click with no progress), hover surprises (whole row highlights but only title clickable), cursor inconsistency, animations that block input, missing transitions where they're needed (accordion snaps open), drag-and-drop without indicators, scroll-jacking, click-through bugs (card click handler firing alongside button), hover-only revelations on touch.\nNOT this lens: position of controls (\\`layout\\` / \\`ux-flow\\`), missing focus styles (\\`accessibility\\`).\nTitle format: \\`<Action> on <element>: <missing/wrong> feedback\\`.\n`.trim(),\n 'performance-perceived': `\nLENS: performance-perceived\nLook for perceived-performance problems — visible jank a real user would notice, not benchmark numbers. This iteration's captures should include >=2 frames during load to show shift.\nSignals: layout shift (CLS) when late-arriving images/fonts/banners settle, FOUC (flash of unstyled content), font swap jumps, late-loading hero images that shift everything, skeletons that don't match final shape, spinners on instant local actions, loading state reappearing after content paints (refetch on focus), modal open animation longer than the operation it precedes.\nNOT this lens: slow API calls (file separately), stale data after navigation (\\`states\\`).\nTitle format: \\`Layout shift / late paint on <route>: <root cause>\\`.\n`.trim(),\n other: `\nLENS: other\nUse ONLY when a finding is clearly a UI quality issue but does not fit any other lens. Strongly prefer a specific lens — \\`other\\` should be rare. Title must still be concrete.\n`.trim(),\n}\n\n/**\n * Build a system prompt for a single auditor iteration.\n *\n * @experimental\n */\nexport function buildAuditorSystemPrompt(lens: UiLens): string {\n const brief = LENS_BRIEFS[lens]\n return `${SHARED_AUDITOR_RULES}\\n\\n${brief}`\n}\n","/**\n *\n * Sandbox-event stream → UiAuditOutput decoder. The custom auditor\n * `SandboxClient` emits events of the form:\n *\n * { type: 'audit.capture', data: UiAuditCapture }\n * { type: 'audit.finding', data: UiFinding }\n * { type: 'audit.notes', data: { notes: string } }\n * { type: 'audit.lens', data: { lens: UiLens } }\n * { type: 'done', data: { tokenUsage: { ... }, totalCostUsd?: number } }\n *\n * Other event types are tolerated and ignored. The adapter is pure: it\n * folds an already-collected event array into a UiAuditOutput.\n *\n * @experimental\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport { UI_LENSES, type UiFinding, type UiLens } from './substrate'\nimport type { UiAuditCapture, UiAuditOutput } from './task'\n\n// Build the lens-validation set from the canonical UI_LENSES tuple so adding\n// a lens to the substrate automatically extends the parser; otherwise a new\n// lens would silently fail isUiLens() and parseAuditorEvents would drop\n// every event using it.\nconst KNOWN_LENS_VALUES = new Set<UiLens>(UI_LENSES)\n\nfunction isUiLens(v: unknown): v is UiLens {\n return typeof v === 'string' && KNOWN_LENS_VALUES.has(v as UiLens)\n}\n\n/** Parse raw `SandboxEvent` emissions from an audit iteration into structured `UiAuditOutput`. @experimental */\nexport function parseAuditorEvents(events: SandboxEvent[]): UiAuditOutput {\n const findings: UiFinding[] = []\n const captures: UiAuditCapture[] = []\n let lens: UiLens | undefined\n let notes: string | undefined\n\n for (const evt of events) {\n if (!evt || typeof evt !== 'object') continue\n const type = String(evt.type ?? '')\n const data =\n evt.data && typeof evt.data === 'object' ? (evt.data as Record<string, unknown>) : undefined\n if (!data) continue\n\n switch (type) {\n case 'audit.lens': {\n const v = data.lens\n if (isUiLens(v)) lens = v\n break\n }\n case 'audit.capture': {\n const cap = data as unknown as Partial<UiAuditCapture>\n if (\n typeof cap.path === 'string' &&\n typeof cap.viewport === 'string' &&\n typeof cap.fullPage === 'boolean' &&\n typeof cap.route === 'string' &&\n typeof cap.url === 'string' &&\n typeof cap.capturedAt === 'string'\n ) {\n const out: UiAuditCapture = {\n path: cap.path,\n viewport: cap.viewport,\n fullPage: cap.fullPage,\n route: cap.route,\n url: cap.url,\n capturedAt: cap.capturedAt,\n }\n if (cap.elementSelector) out.elementSelector = cap.elementSelector\n if (cap.label) out.label = cap.label\n captures.push(out)\n }\n break\n }\n case 'audit.finding': {\n const f = data as unknown as Partial<UiFinding>\n // Hard requirement: all the actionable fields must be present and\n // non-empty for a finding to enter the output. The validator does the\n // softer scoring; the adapter only filters structural junk.\n if (\n typeof f.title === 'string' &&\n f.title.trim().length > 0 &&\n isUiLens(f.lens) &&\n typeof f.severity === 'string' &&\n ['low', 'med', 'high', 'critical'].includes(f.severity) &&\n typeof f.route === 'string' &&\n typeof f.observation === 'string' &&\n typeof f.impact === 'string' &&\n typeof f.suggestedFix === 'string' &&\n Array.isArray(f.screenshots)\n ) {\n findings.push(f as UiFinding)\n }\n break\n }\n case 'audit.notes': {\n const n = data.notes\n if (typeof n === 'string' && n.trim().length > 0) notes = n\n break\n }\n default:\n // Tolerate cost/usage events and other backend chatter — extractLlmCallEvent\n // in run-loop.ts handles cost accounting upstream from the adapter.\n break\n }\n }\n\n const out: UiAuditOutput = { lens: lens ?? 'other', findings, captures }\n if (notes) out.notes = notes\n return out\n}\n"],"mappings":"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"}