@tangle-network/agent-runtime 0.101.1 → 0.102.1

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 (78) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +5 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/analyst-loop.d.ts +1 -1
  5. package/dist/candidate-execution/index.d.ts +13 -2
  6. package/dist/candidate-execution/index.js +8 -3
  7. package/dist/chunk-377GOJHJ.js +578 -0
  8. package/dist/chunk-377GOJHJ.js.map +1 -0
  9. package/dist/{chunk-DI677IPX.js → chunk-3DW5DEKQ.js} +3 -3
  10. package/dist/{chunk-KVJQV342.js → chunk-6MR4IJRW.js} +25 -1777
  11. package/dist/chunk-6MR4IJRW.js.map +1 -0
  12. package/dist/{chunk-RJPQLUDA.js → chunk-7FJJUC73.js} +336 -43
  13. package/dist/chunk-7FJJUC73.js.map +1 -0
  14. package/dist/{chunk-TA4RBJLE.js → chunk-CI7WS6S2.js} +5 -5
  15. package/dist/{chunk-U4PRAATQ.js → chunk-CK76OZPM.js} +3 -3
  16. package/dist/{chunk-KSBUSEUA.js → chunk-KJ2Q4T7F.js} +2 -2
  17. package/dist/{chunk-MAONWP4R.js → chunk-KPHTCHQ4.js} +611 -1419
  18. package/dist/chunk-KPHTCHQ4.js.map +1 -0
  19. package/dist/{chunk-BXZ7GPL4.js → chunk-KSM6GFHP.js} +2 -2
  20. package/dist/chunk-L5DST3QC.js +351 -0
  21. package/dist/chunk-L5DST3QC.js.map +1 -0
  22. package/dist/{chunk-HGSHPVJ6.js → chunk-LJLG734E.js} +200 -441
  23. package/dist/chunk-LJLG734E.js.map +1 -0
  24. package/dist/chunk-ROILMKDL.js +1338 -0
  25. package/dist/chunk-ROILMKDL.js.map +1 -0
  26. package/dist/{chunk-N2CEE5Q3.js → chunk-RTB3TC73.js} +3 -3
  27. package/dist/chunk-SQ3ZJH3Y.js +3082 -0
  28. package/dist/chunk-SQ3ZJH3Y.js.map +1 -0
  29. package/dist/chunk-UPWGXKXB.js +254 -0
  30. package/dist/chunk-UPWGXKXB.js.map +1 -0
  31. package/dist/{completion-gate-C80jiRfN.d.ts → completion-gate-C6dhVN-N.d.ts} +2 -2
  32. package/dist/{coordination-BFE3Den7.d.ts → coordination-D9l_YmwW.d.ts} +6 -6
  33. package/dist/environment-provider.d.ts +2 -2
  34. package/dist/{improve-g75IE2Cx.d.ts → improve-B40dRu0X.d.ts} +47 -19
  35. package/dist/index.d.ts +331 -23
  36. package/dist/index.js +544 -136
  37. package/dist/index.js.map +1 -1
  38. package/dist/intelligence.d.ts +63 -62
  39. package/dist/intelligence.js +62 -471
  40. package/dist/intelligence.js.map +1 -1
  41. package/dist/knowledge.d.ts +8 -8
  42. package/dist/knowledge.js +9 -7
  43. package/dist/{local-harness-ZqCx51u7.d.ts → local-harness-CtK9dSny.d.ts} +14 -2
  44. package/dist/{loop-runner-bin-Cn1N2rRo.d.ts → loop-runner-bin-PnWslIw4.d.ts} +2 -2
  45. package/dist/loop-runner-bin.d.ts +6 -6
  46. package/dist/loop-runner-bin.js +6 -4
  47. package/dist/loops.d.ts +231 -460
  48. package/dist/loops.js +58 -37
  49. package/dist/mcp/bin.js +2 -2
  50. package/dist/mcp/index.d.ts +184 -12
  51. package/dist/mcp/index.js +31 -9
  52. package/dist/mcp/index.js.map +1 -1
  53. package/dist/mcp/memory-bin.d.ts +1 -0
  54. package/dist/mcp/memory-bin.js +22 -0
  55. package/dist/mcp/memory-bin.js.map +1 -0
  56. package/dist/profiles.d.ts +3 -3
  57. package/dist/structural-rollout-D7xik9XR.d.ts +446 -0
  58. package/dist/{substrate-DO2GHNg2.d.ts → substrate-Dyiqmd3o.d.ts} +1 -1
  59. package/dist/{supervise-BLPI50-w.d.ts → supervise-BQdNAXtK.d.ts} +4 -4
  60. package/dist/testing.js +255 -211
  61. package/dist/testing.js.map +1 -1
  62. package/dist/{types-B3vAW0Oq.d.ts → types-CLat4bT9.d.ts} +1 -1
  63. package/dist/{types-CmnA2iL3.d.ts → types-D870JlH0.d.ts} +2 -2
  64. package/dist/{worktree-fanout-DCA3G4bO.d.ts → worktree-fanout-DsIR4d6w.d.ts} +234 -234
  65. package/package.json +6 -5
  66. package/dist/chunk-HGSHPVJ6.js.map +0 -1
  67. package/dist/chunk-IKGCKPDX.js +0 -1115
  68. package/dist/chunk-IKGCKPDX.js.map +0 -1
  69. package/dist/chunk-KVJQV342.js.map +0 -1
  70. package/dist/chunk-MAONWP4R.js.map +0 -1
  71. package/dist/chunk-RJPQLUDA.js.map +0 -1
  72. package/dist/{chunk-DI677IPX.js.map → chunk-3DW5DEKQ.js.map} +0 -0
  73. package/dist/{chunk-TA4RBJLE.js.map → chunk-CI7WS6S2.js.map} +0 -0
  74. package/dist/{chunk-U4PRAATQ.js.map → chunk-CK76OZPM.js.map} +0 -0
  75. package/dist/{chunk-KSBUSEUA.js.map → chunk-KJ2Q4T7F.js.map} +0 -0
  76. package/dist/{chunk-BXZ7GPL4.js.map → chunk-KSM6GFHP.js.map} +0 -0
  77. package/dist/{chunk-N2CEE5Q3.js.map → chunk-RTB3TC73.js.map} +0 -0
  78. package/dist/{sanitize-BTSsdBXw.d.ts → sanitize-DEbPNtyI.d.ts} +58 -58
@@ -1,3 +1,9 @@
1
+ import {
2
+ assertNoProtectedBytes,
3
+ createProtectedRecordRedactor,
4
+ redactProtectedReason,
5
+ redactProtectedValue
6
+ } from "./chunk-UPWGXKXB.js";
1
7
  import {
2
8
  contentAddress
3
9
  } from "./chunk-IMSNJSXH.js";
@@ -2531,6 +2537,182 @@ function retryLineageDigest(prepared, resultTimeoutMs) {
2531
2537
  });
2532
2538
  }
2533
2539
 
2540
+ // src/candidate-execution/verify.ts
2541
+ import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
2542
+ var verifiedCandidateState = /* @__PURE__ */ new WeakMap();
2543
+ var AGENT_CANDIDATE_EXECUTION_SUPPORT = Object.freeze({
2544
+ outcomes: Object.freeze(["workspace", "output"]),
2545
+ code: Object.freeze(["disabled", "no-op", "git-patch"]),
2546
+ memory: Object.freeze(["disabled", "isolated"]),
2547
+ knowledge: true,
2548
+ profile: Object.freeze({
2549
+ mcpTransports: Object.freeze(["stdio"]),
2550
+ remoteMcp: false,
2551
+ tools: false,
2552
+ permissions: false,
2553
+ modes: false,
2554
+ confidential: false
2555
+ })
2556
+ });
2557
+ async function verifyAgentCandidateBundle(input, ports) {
2558
+ const parsed = agentCandidateBundleSchema.parse(input);
2559
+ const withoutDigest = omitTopLevelDigest(parsed);
2560
+ const actualDigest = canonicalCandidateDigest(withoutDigest);
2561
+ if (actualDigest !== parsed.digest) {
2562
+ throw new Error(`candidate bundle digest ${parsed.digest} does not match ${actualDigest}`);
2563
+ }
2564
+ const canonicalBytes = canonicalCandidateBytes(withoutDigest);
2565
+ verifyBytes(canonicalBytes, parsed.digest, canonicalBytes.byteLength, "candidate bundle");
2566
+ assertCandidateProfileExecutionSupport(parsed.profile);
2567
+ const artifactBytes = /* @__PURE__ */ new Map();
2568
+ const readArtifact = async (artifact) => {
2569
+ const key = artifactCacheKey(artifact);
2570
+ const existing = artifactBytes.get(key);
2571
+ if (existing) return Uint8Array.from(existing);
2572
+ const bytes = await readVerifiedArtifact(artifact, ports.artifacts);
2573
+ artifactBytes.set(key, Uint8Array.from(bytes));
2574
+ return bytes;
2575
+ };
2576
+ let patchBytes;
2577
+ if (parsed.code.kind === "git-patch") {
2578
+ patchBytes = await readArtifact(parsed.code.patch.artifact);
2579
+ }
2580
+ const materializedTree = await verifyCandidateCode(parsed.code, ports.repositories, patchBytes);
2581
+ const resourceBytes = /* @__PURE__ */ new Map();
2582
+ for (const resource of candidateResources(parsed)) {
2583
+ const bytes = resource.kind === "inline" ? Buffer.from(resource.content, "utf8") : await readCandidateGitHubResource(resource, ports.repositories);
2584
+ verifyBytes(
2585
+ bytes,
2586
+ resource.sha256,
2587
+ resource.byteLength,
2588
+ `candidate resource ${resource.name ?? (resource.kind === "github" ? resource.path : "<unnamed>")}`
2589
+ );
2590
+ resourceBytes.set(resourceKey(resource), Uint8Array.from(bytes));
2591
+ resourceBytes.set(resource.sha256, Uint8Array.from(bytes));
2592
+ }
2593
+ if (parsed.execution.workspace) {
2594
+ const workspace = await verifyWorkspaceSnapshotArtifacts(
2595
+ parsed.execution.workspace,
2596
+ ports.artifacts
2597
+ );
2598
+ artifactBytes.set(artifactCacheKey(parsed.execution.workspace.manifest), workspace.manifest);
2599
+ artifactBytes.set(artifactCacheKey(parsed.execution.workspace.archive), workspace.archive);
2600
+ }
2601
+ if (parsed.knowledge) {
2602
+ const knowledge = await verifyWorkspaceSnapshotArtifacts(
2603
+ parsed.knowledge.snapshot,
2604
+ ports.artifacts
2605
+ );
2606
+ artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.manifest), knowledge.manifest);
2607
+ artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.archive), knowledge.archive);
2608
+ if (parsed.knowledge.retrievalConfig) await readArtifact(parsed.knowledge.retrievalConfig);
2609
+ await readArtifact(parsed.knowledge.evaluation);
2610
+ }
2611
+ if (parsed.memory.mode === "isolated" && parsed.memory.seed)
2612
+ await readArtifact(parsed.memory.seed);
2613
+ deepFreezeCandidate(parsed);
2614
+ const verified = Object.freeze({
2615
+ bundle: parsed,
2616
+ ...materializedTree === void 0 ? {} : { materializedTree },
2617
+ [verifiedCandidateBrand]: true
2618
+ });
2619
+ verifiedCandidateState.set(verified, { ports, artifactBytes, resourceBytes });
2620
+ return verified;
2621
+ }
2622
+ function getVerifiedCandidateState(candidate) {
2623
+ const state = verifiedCandidateState.get(candidate);
2624
+ if (!state || candidate[verifiedCandidateBrand] !== true) {
2625
+ throw new Error("candidate must come from verifyAgentCandidateBundle");
2626
+ }
2627
+ return state;
2628
+ }
2629
+ async function verifiedArtifactBytes(candidate, artifact) {
2630
+ const state = getVerifiedCandidateState(candidate);
2631
+ const key = artifactCacheKey(artifact);
2632
+ const existing = state.artifactBytes.get(key);
2633
+ if (existing) return Uint8Array.from(existing);
2634
+ const bytes = await readVerifiedArtifact(artifact, state.ports.artifacts);
2635
+ state.artifactBytes.set(key, Uint8Array.from(bytes));
2636
+ return bytes;
2637
+ }
2638
+ function verifiedResourceTextByDigest(candidate) {
2639
+ const output = /* @__PURE__ */ new Map();
2640
+ for (const resource of candidateResources(candidate.bundle)) {
2641
+ const bytes = getVerifiedCandidateState(candidate).resourceBytes.get(resource.sha256);
2642
+ if (!bytes) throw new Error(`candidate resource digest was not verified: ${resource.sha256}`);
2643
+ output.set(resource.sha256, new TextDecoder("utf-8", { fatal: true }).decode(bytes));
2644
+ }
2645
+ return output;
2646
+ }
2647
+ function candidateResources(bundle) {
2648
+ const resources = bundle.profile.resources;
2649
+ if (!resources) return [];
2650
+ const output = [];
2651
+ for (const mount of resources.files ?? []) output.push(mount.resource);
2652
+ output.push(...resources.tools ?? []);
2653
+ output.push(...resources.skills ?? []);
2654
+ output.push(...resources.agents ?? []);
2655
+ output.push(...resources.commands ?? []);
2656
+ if (typeof resources.instructions === "object") output.push(resources.instructions);
2657
+ return output;
2658
+ }
2659
+ function resourceKey(resource) {
2660
+ return canonicalCandidateDigest(resource);
2661
+ }
2662
+
2663
+ // src/candidate-execution/knowledge.ts
2664
+ import { mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
2665
+ import { tmpdir as tmpdir2 } from "os";
2666
+ import { join as join2, posix } from "path";
2667
+ import { hashKnowledgeBase } from "@tangle-network/agent-knowledge";
2668
+ var CANDIDATE_KNOWLEDGE_ROOT_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_ROOT";
2669
+ var CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG";
2670
+ function candidateKnowledgeExecutionPaths(taskRoot, hasRetrievalConfig) {
2671
+ if (!posix.isAbsolute(taskRoot) || posix.normalize(taskRoot) !== taskRoot) {
2672
+ throw new Error("candidate knowledge requires a normalized absolute task root");
2673
+ }
2674
+ const parent = posix.join(taskRoot, ".tangle");
2675
+ return {
2676
+ root: posix.join(parent, "knowledge"),
2677
+ ...hasRetrievalConfig ? { retrievalConfig: posix.join(parent, "knowledge-retrieval-config.json") } : {}
2678
+ };
2679
+ }
2680
+ async function prepareAgentCandidateKnowledge(candidate, ports, arm) {
2681
+ const knowledge = candidate.bundle.knowledge;
2682
+ if (!knowledge) return void 0;
2683
+ const archive = await verifiedArtifactBytes(candidate, knowledge.snapshot.archive);
2684
+ const retrievalConfig = knowledge.retrievalConfig ? await verifiedArtifactBytes(candidate, knowledge.retrievalConfig) : void 0;
2685
+ const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-knowledge-"));
2686
+ try {
2687
+ await ports.workspaces.materialize({
2688
+ role: "knowledge",
2689
+ snapshot: knowledge.snapshot,
2690
+ archive,
2691
+ destination: root
2692
+ });
2693
+ const expectedHash = arm === "baseline" ? knowledge.candidate.baseHash : knowledge.candidate.candidateHash;
2694
+ const actualHash = `sha256:${await hashKnowledgeBase(root)}`;
2695
+ if (actualHash !== expectedHash) {
2696
+ throw new Error(
2697
+ `materialized ${arm} knowledge does not match its measured content: expected ${expectedHash}, got ${actualHash}`
2698
+ );
2699
+ }
2700
+ const files = await readMaterializedWorkspaceFiles(root, knowledge.snapshot.material);
2701
+ return Object.freeze({
2702
+ candidate: knowledge.candidate,
2703
+ snapshot: knowledge.snapshot,
2704
+ files: Object.freeze(
2705
+ files.map(
2706
+ (file) => Object.freeze({ path: file.path, mode: file.mode, bytes: Uint8Array.from(file.bytes) })
2707
+ )
2708
+ ),
2709
+ ...retrievalConfig ? { retrievalConfig: Uint8Array.from(retrievalConfig) } : {}
2710
+ });
2711
+ } finally {
2712
+ await rm2(root, { recursive: true, force: true });
2713
+ }
2714
+ }
2715
+
2534
2716
  // src/candidate-execution/output-artifacts.ts
2535
2717
  import {
2536
2718
  agentCandidateArtifactRefSchema as agentCandidateArtifactRefSchema3
@@ -2663,7 +2845,7 @@ function requireRecord(value, label) {
2663
2845
  }
2664
2846
 
2665
2847
  // src/candidate-execution/finalize.ts
2666
- import { isLlmSpan as isLlmSpan2, REDACTION_VERSION as REDACTION_VERSION2 } from "@tangle-network/agent-eval";
2848
+ import { isLlmSpan as isLlmSpan2, REDACTION_VERSION } from "@tangle-network/agent-eval";
2667
2849
  import {
2668
2850
  agentCandidateRunReceiptSchema,
2669
2851
  agentCandidateWorkspaceSnapshotEvidenceSchema
@@ -2891,253 +3073,6 @@ function safeAdd(left, right, label) {
2891
3073
  return total;
2892
3074
  }
2893
3075
 
2894
- // src/candidate-execution/protected-redaction.ts
2895
- import { createHmac, randomBytes as randomBytes2 } from "crypto";
2896
- import {
2897
- DEFAULT_REDACTION_RULES,
2898
- REDACTION_VERSION,
2899
- redactString
2900
- } from "@tangle-network/agent-eval";
2901
- function createProtectedRecordRedactor(protectedValues) {
2902
- const identityKey = randomBytes2(32);
2903
- const aggregate = {
2904
- version: REDACTION_VERSION,
2905
- redactionCount: 0,
2906
- byRule: {}
2907
- };
2908
- const mergeReport = (report) => {
2909
- aggregate.version = report.version;
2910
- aggregate.redactionCount += report.redactionCount;
2911
- for (const [rule, count] of Object.entries(report.byRule)) {
2912
- aggregate.byRule[rule] = (aggregate.byRule[rule] ?? 0) + count;
2913
- }
2914
- };
2915
- const redactScalar = (value, record) => {
2916
- const redacted = redactProtectedValue(value, protectedValues);
2917
- if (record) mergeReport(redacted.report);
2918
- return redacted.value;
2919
- };
2920
- const identifier = (value, record) => {
2921
- const redacted = redactScalar(value, record);
2922
- if (redacted === value) return value;
2923
- const digest = createHmac("sha256", identityKey).update(value).digest("hex");
2924
- return `${redacted}:hmac-sha256:${digest}`;
2925
- };
2926
- const transform = (value, record) => {
2927
- const transformed = transformProtectedRecord(
2928
- value,
2929
- void 0,
2930
- record,
2931
- redactScalar,
2932
- identifier
2933
- );
2934
- assertNoProtectedEvidence(transformed, protectedValues);
2935
- return transformed;
2936
- };
2937
- return Object.freeze({
2938
- record: (value) => transform(value, true),
2939
- query: (value) => transform(value, false),
2940
- identifier: (value) => identifier(value, false),
2941
- traceIdentity: (trace) => transform(trace, false),
2942
- report: () => ({
2943
- version: aggregate.version,
2944
- redactionCount: aggregate.redactionCount,
2945
- byRule: { ...aggregate.byRule }
2946
- })
2947
- });
2948
- }
2949
- function redactProtectedValue(value, protectedValues) {
2950
- const report = {
2951
- version: REDACTION_VERSION,
2952
- redactionCount: 0,
2953
- byRule: {}
2954
- };
2955
- const rules = protectedRedactionRules(protectedValues);
2956
- const redacted = redactNode(value, protectedValues, rules, report);
2957
- assertNoProtectedEvidence(redacted, protectedValues);
2958
- return { value: redacted, report };
2959
- }
2960
- function redactProtectedReason(reason, protectedValues) {
2961
- try {
2962
- return redactProtectedValue(reason, protectedValues).value;
2963
- } catch {
2964
- return "candidate execution failed with a protected error";
2965
- }
2966
- }
2967
- function assertNoProtectedEvidence(value, protectedValues) {
2968
- if (value instanceof Uint8Array) {
2969
- assertNoProtectedBytes(value, protectedValues);
2970
- return;
2971
- }
2972
- if (typeof value === "string") {
2973
- for (const protectedValue of protectedValueVariants(protectedValues)) {
2974
- if (value.includes(protectedValue)) {
2975
- throw new Error("protected value survived candidate evidence redaction");
2976
- }
2977
- }
2978
- if (decodedBase64ContainsProtectedValue(value, protectedValues)) {
2979
- throw new Error("base64 protected value survived candidate evidence redaction");
2980
- }
2981
- return;
2982
- }
2983
- if (Array.isArray(value)) {
2984
- for (const entry of value) assertNoProtectedEvidence(entry, protectedValues);
2985
- return;
2986
- }
2987
- if (value && typeof value === "object") {
2988
- for (const [key, entry] of Object.entries(value)) {
2989
- assertNoProtectedEvidence(key, protectedValues);
2990
- assertNoProtectedEvidence(entry, protectedValues);
2991
- }
2992
- }
2993
- }
2994
- function assertNoProtectedBytes(bytes, protectedValues) {
2995
- if (containsProtectedBytes(bytes, protectedValues)) {
2996
- throw new Error("protected value survived candidate evidence byte redaction");
2997
- }
2998
- }
2999
- function redactNode(value, protectedValues, rules, report) {
3000
- if (value instanceof Uint8Array) {
3001
- if (containsProtectedBytes(value, protectedValues)) {
3002
- recordRedaction(report, "candidate-access-binary", 1);
3003
- return Uint8Array.from(Buffer.from("[redacted:candidate-access-binary]", "utf8"));
3004
- }
3005
- return Uint8Array.from(value);
3006
- }
3007
- if (typeof value === "string") {
3008
- if (decodedBase64ContainsProtectedValue(value, protectedValues)) {
3009
- recordRedaction(report, "candidate-access-binary", 1);
3010
- return "[redacted:candidate-access-binary]";
3011
- }
3012
- const redacted = redactString(value, [...rules]);
3013
- for (const [rule, count] of Object.entries(redacted.report.byRule)) {
3014
- recordRedaction(report, rule, count);
3015
- }
3016
- return redacted.output;
3017
- }
3018
- if (Array.isArray(value)) {
3019
- return value.map((entry) => redactNode(entry, protectedValues, rules, report));
3020
- }
3021
- if (value && typeof value === "object") {
3022
- const entries = [];
3023
- const seenKeys = /* @__PURE__ */ new Set();
3024
- for (const [key, entry] of Object.entries(value)) {
3025
- const redactedKey = redactNode(key, protectedValues, rules, report);
3026
- if (typeof redactedKey !== "string" || seenKeys.has(redactedKey)) {
3027
- throw new Error("protected evidence redaction produced an ambiguous object key");
3028
- }
3029
- seenKeys.add(redactedKey);
3030
- entries.push([redactedKey, redactNode(entry, protectedValues, rules, report)]);
3031
- }
3032
- return Object.fromEntries(entries);
3033
- }
3034
- return value;
3035
- }
3036
- function transformProtectedRecord(value, fieldName, record, redactScalar, redactIdentifier) {
3037
- if (value instanceof Uint8Array) return redactScalar(value, record);
3038
- if (typeof value === "string") {
3039
- return fieldName && isIdentifierFieldName(fieldName) ? redactIdentifier(value, record) : redactScalar(value, record);
3040
- }
3041
- if (Array.isArray(value)) {
3042
- return value.map(
3043
- (entry) => transformProtectedRecord(entry, fieldName, record, redactScalar, redactIdentifier)
3044
- );
3045
- }
3046
- if (!value || typeof value !== "object") return value;
3047
- if (fieldName === "tags") {
3048
- return transformTagMap(value, record, redactScalar, redactIdentifier);
3049
- }
3050
- if (fieldName === "tag") {
3051
- return transformTagFilter(value, record, redactScalar, redactIdentifier);
3052
- }
3053
- const entries = [];
3054
- const seenKeys = /* @__PURE__ */ new Set();
3055
- for (const [key, entry] of Object.entries(value)) {
3056
- const redactedKey = redactScalar(key, record);
3057
- if (seenKeys.has(redactedKey)) {
3058
- throw new Error("protected evidence redaction produced an ambiguous object key");
3059
- }
3060
- seenKeys.add(redactedKey);
3061
- entries.push([
3062
- redactedKey,
3063
- transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)
3064
- ]);
3065
- }
3066
- return Object.fromEntries(entries);
3067
- }
3068
- function transformTagMap(value, record, redactScalar, redactIdentifier) {
3069
- const entries = [];
3070
- const seenKeys = /* @__PURE__ */ new Set();
3071
- for (const [key, entry] of Object.entries(value)) {
3072
- const redactedKey = redactIdentifier(key, record);
3073
- if (seenKeys.has(redactedKey)) {
3074
- throw new Error("protected evidence redaction produced an ambiguous trace tag");
3075
- }
3076
- seenKeys.add(redactedKey);
3077
- entries.push([
3078
- redactedKey,
3079
- typeof entry === "string" ? redactIdentifier(entry, record) : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)
3080
- ]);
3081
- }
3082
- return Object.fromEntries(entries);
3083
- }
3084
- function transformTagFilter(value, record, redactScalar, redactIdentifier) {
3085
- const output = {};
3086
- for (const [key, entry] of Object.entries(value)) {
3087
- const redactedKey = redactScalar(key, record);
3088
- output[redactedKey] = (key === "key" || key === "value") && typeof entry === "string" ? redactIdentifier(entry, record) : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier);
3089
- }
3090
- return output;
3091
- }
3092
- function isIdentifierFieldName(name) {
3093
- return /ids?$/i.test(name);
3094
- }
3095
- function protectedRedactionRules(protectedValues) {
3096
- const exactRules = protectedValueVariants(protectedValues).sort((left, right) => right.length - left.length || left.localeCompare(right)).map((value, index) => ({
3097
- id: `candidate-access-${index}`,
3098
- pattern: new RegExp(escapeRegularExpression(value), "g"),
3099
- replacement: "[redacted:candidate-access]"
3100
- }));
3101
- return [...exactRules, ...DEFAULT_REDACTION_RULES];
3102
- }
3103
- function recordRedaction(report, rule, count) {
3104
- if (count <= 0) return;
3105
- report.redactionCount += count;
3106
- report.byRule[rule] = (report.byRule[rule] ?? 0) + count;
3107
- }
3108
- function containsProtectedBytes(bytes, protectedValues) {
3109
- const source = Buffer.from(bytes);
3110
- return protectedValueVariants(protectedValues).some(
3111
- (value) => source.includes(Buffer.from(value, "utf8"))
3112
- );
3113
- }
3114
- function decodedBase64ContainsProtectedValue(value, protectedValues) {
3115
- if (value.length < 4 || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {
3116
- return false;
3117
- }
3118
- try {
3119
- return containsProtectedBytes(Buffer.from(value, "base64"), protectedValues);
3120
- } catch {
3121
- return false;
3122
- }
3123
- }
3124
- function protectedValueVariants(protectedValues) {
3125
- const variants = /* @__PURE__ */ new Set();
3126
- for (const value of normalizedProtectedValues(protectedValues)) {
3127
- variants.add(value);
3128
- variants.add(Buffer.from(value, "utf8").toString("base64"));
3129
- variants.add(Buffer.from(value, "utf8").toString("base64url"));
3130
- variants.add(encodeURIComponent(value));
3131
- }
3132
- return [...variants];
3133
- }
3134
- function normalizedProtectedValues(values) {
3135
- return [...new Set(values.filter((value) => value.length > 0))];
3136
- }
3137
- function escapeRegularExpression(value) {
3138
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3139
- }
3140
-
3141
3076
  // src/candidate-execution/finalize.ts
3142
3077
  async function finalizeAgentCandidateRun(state, capture, traceStore, traceIdentity, settlement, evidence, protectedValues, writeRedactionReport, signal) {
3143
3078
  let termination;
@@ -3185,7 +3120,7 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, traceIdenti
3185
3120
  );
3186
3121
  const redacted = redactProtectedValue(
3187
3122
  {
3188
- run: { ...run, redactionVersion: REDACTION_VERSION2 },
3123
+ run: { ...run, redactionVersion: REDACTION_VERSION },
3189
3124
  spans: orderedSpans,
3190
3125
  events: orderedEvents,
3191
3126
  budget: orderedBudget,
@@ -3201,7 +3136,7 @@ async function finalizeAgentCandidateRun(state, capture, traceStore, traceIdenti
3201
3136
  ...redacted.value,
3202
3137
  evaluatorLimits: { resultTimeoutMs: state.resultTimeoutMs },
3203
3138
  redaction: {
3204
- version: REDACTION_VERSION2,
3139
+ version: REDACTION_VERSION,
3205
3140
  redactionCount: (writeRedactionReport?.redactionCount ?? 0) + redacted.report.redactionCount,
3206
3141
  byRule: combinedByRule
3207
3142
  }
@@ -3348,9 +3283,9 @@ function compareStrings(a, b) {
3348
3283
  }
3349
3284
 
3350
3285
  // src/candidate-execution/outcome-evidence.ts
3351
- import { mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
3352
- import { tmpdir as tmpdir2 } from "os";
3353
- import { join as join2 } from "path";
3286
+ import { mkdtemp as mkdtemp3, rm as rm3 } from "fs/promises";
3287
+ import { tmpdir as tmpdir3 } from "os";
3288
+ import { join as join3 } from "path";
3354
3289
  import {
3355
3290
  agentCandidateBenchmarkResultEvidenceSchema,
3356
3291
  agentCandidateModelSettlementEvidenceSchema,
@@ -3846,7 +3781,7 @@ async function persistCandidateBenchmarkResult(state, termination, outcome, grad
3846
3781
  );
3847
3782
  }
3848
3783
  async function verifyTaskOutcomeArchive(state, snapshot, archive, protectedValues) {
3849
- const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-task-archive-"));
3784
+ const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-task-archive-"));
3850
3785
  try {
3851
3786
  await state.ports.workspaces.materialize({
3852
3787
  role: "task",
@@ -3857,7 +3792,7 @@ async function verifyTaskOutcomeArchive(state, snapshot, archive, protectedValue
3857
3792
  const files = await readMaterializedWorkspaceFiles(root, snapshot.material);
3858
3793
  for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
3859
3794
  } finally {
3860
- await rm2(root, { recursive: true, force: true });
3795
+ await rm3(root, { recursive: true, force: true });
3861
3796
  }
3862
3797
  }
3863
3798
  async function verifyMemoryCapture(state, capture, protectedValues, signal) {
@@ -3878,7 +3813,7 @@ async function verifyMemoryCapture(state, capture, protectedValues, signal) {
3878
3813
  manifest: embeddedCandidateArtifact(manifestBytes),
3879
3814
  archive: embeddedCandidateArtifact(memory.archive)
3880
3815
  });
3881
- const root = await mkdtemp2(join2(tmpdir2(), "agent-candidate-memory-after-"));
3816
+ const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-memory-after-"));
3882
3817
  try {
3883
3818
  await state.ports.workspaces.materialize({
3884
3819
  role: "memory",
@@ -3890,7 +3825,7 @@ async function verifyMemoryCapture(state, capture, protectedValues, signal) {
3890
3825
  for (const file of files) assertNoProtectedBytes(file.bytes, protectedValues);
3891
3826
  signal?.throwIfAborted();
3892
3827
  } finally {
3893
- await rm2(root, { recursive: true, force: true });
3828
+ await rm3(root, { recursive: true, force: true });
3894
3829
  }
3895
3830
  }
3896
3831
  function normalizeEvaluation(evaluation, termination) {
@@ -4794,184 +4729,8 @@ var CandidateExecutionDeadlineError = class extends Error {
4794
4729
  }
4795
4730
  };
4796
4731
 
4797
- // src/candidate-execution/verify.ts
4798
- import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
4799
- var verifiedCandidateState = /* @__PURE__ */ new WeakMap();
4800
- var AGENT_CANDIDATE_EXECUTION_SUPPORT = Object.freeze({
4801
- outcomes: Object.freeze(["workspace", "output"]),
4802
- code: Object.freeze(["disabled", "no-op", "git-patch"]),
4803
- memory: Object.freeze(["disabled", "isolated"]),
4804
- knowledge: true,
4805
- profile: Object.freeze({
4806
- mcpTransports: Object.freeze(["stdio"]),
4807
- remoteMcp: false,
4808
- tools: false,
4809
- permissions: false,
4810
- modes: false,
4811
- confidential: false
4812
- })
4813
- });
4814
- async function verifyAgentCandidateBundle(input, ports) {
4815
- const parsed = agentCandidateBundleSchema.parse(input);
4816
- const withoutDigest = omitTopLevelDigest(parsed);
4817
- const actualDigest = canonicalCandidateDigest(withoutDigest);
4818
- if (actualDigest !== parsed.digest) {
4819
- throw new Error(`candidate bundle digest ${parsed.digest} does not match ${actualDigest}`);
4820
- }
4821
- const canonicalBytes = canonicalCandidateBytes(withoutDigest);
4822
- verifyBytes(canonicalBytes, parsed.digest, canonicalBytes.byteLength, "candidate bundle");
4823
- assertCandidateProfileExecutionSupport(parsed.profile);
4824
- const artifactBytes = /* @__PURE__ */ new Map();
4825
- const readArtifact = async (artifact) => {
4826
- const key = artifactCacheKey(artifact);
4827
- const existing = artifactBytes.get(key);
4828
- if (existing) return Uint8Array.from(existing);
4829
- const bytes = await readVerifiedArtifact(artifact, ports.artifacts);
4830
- artifactBytes.set(key, Uint8Array.from(bytes));
4831
- return bytes;
4832
- };
4833
- let patchBytes;
4834
- if (parsed.code.kind === "git-patch") {
4835
- patchBytes = await readArtifact(parsed.code.patch.artifact);
4836
- }
4837
- const materializedTree = await verifyCandidateCode(parsed.code, ports.repositories, patchBytes);
4838
- const resourceBytes = /* @__PURE__ */ new Map();
4839
- for (const resource of candidateResources(parsed)) {
4840
- const bytes = resource.kind === "inline" ? Buffer.from(resource.content, "utf8") : await readCandidateGitHubResource(resource, ports.repositories);
4841
- verifyBytes(
4842
- bytes,
4843
- resource.sha256,
4844
- resource.byteLength,
4845
- `candidate resource ${resource.name ?? (resource.kind === "github" ? resource.path : "<unnamed>")}`
4846
- );
4847
- resourceBytes.set(resourceKey(resource), Uint8Array.from(bytes));
4848
- resourceBytes.set(resource.sha256, Uint8Array.from(bytes));
4849
- }
4850
- if (parsed.execution.workspace) {
4851
- const workspace = await verifyWorkspaceSnapshotArtifacts(
4852
- parsed.execution.workspace,
4853
- ports.artifacts
4854
- );
4855
- artifactBytes.set(artifactCacheKey(parsed.execution.workspace.manifest), workspace.manifest);
4856
- artifactBytes.set(artifactCacheKey(parsed.execution.workspace.archive), workspace.archive);
4857
- }
4858
- if (parsed.knowledge) {
4859
- const knowledge = await verifyWorkspaceSnapshotArtifacts(
4860
- parsed.knowledge.snapshot,
4861
- ports.artifacts
4862
- );
4863
- artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.manifest), knowledge.manifest);
4864
- artifactBytes.set(artifactCacheKey(parsed.knowledge.snapshot.archive), knowledge.archive);
4865
- if (parsed.knowledge.retrievalConfig) await readArtifact(parsed.knowledge.retrievalConfig);
4866
- await readArtifact(parsed.knowledge.evaluation);
4867
- }
4868
- if (parsed.memory.mode === "isolated" && parsed.memory.seed)
4869
- await readArtifact(parsed.memory.seed);
4870
- deepFreezeCandidate(parsed);
4871
- const verified = Object.freeze({
4872
- bundle: parsed,
4873
- ...materializedTree === void 0 ? {} : { materializedTree },
4874
- [verifiedCandidateBrand]: true
4875
- });
4876
- verifiedCandidateState.set(verified, { ports, artifactBytes, resourceBytes });
4877
- return verified;
4878
- }
4879
- function getVerifiedCandidateState(candidate) {
4880
- const state = verifiedCandidateState.get(candidate);
4881
- if (!state || candidate[verifiedCandidateBrand] !== true) {
4882
- throw new Error("candidate must come from verifyAgentCandidateBundle");
4883
- }
4884
- return state;
4885
- }
4886
- async function verifiedArtifactBytes(candidate, artifact) {
4887
- const state = getVerifiedCandidateState(candidate);
4888
- const key = artifactCacheKey(artifact);
4889
- const existing = state.artifactBytes.get(key);
4890
- if (existing) return Uint8Array.from(existing);
4891
- const bytes = await readVerifiedArtifact(artifact, state.ports.artifacts);
4892
- state.artifactBytes.set(key, Uint8Array.from(bytes));
4893
- return bytes;
4894
- }
4895
- function verifiedResourceTextByDigest(candidate) {
4896
- const output = /* @__PURE__ */ new Map();
4897
- for (const resource of candidateResources(candidate.bundle)) {
4898
- const bytes = getVerifiedCandidateState(candidate).resourceBytes.get(resource.sha256);
4899
- if (!bytes) throw new Error(`candidate resource digest was not verified: ${resource.sha256}`);
4900
- output.set(resource.sha256, new TextDecoder("utf-8", { fatal: true }).decode(bytes));
4901
- }
4902
- return output;
4903
- }
4904
- function candidateResources(bundle) {
4905
- const resources = bundle.profile.resources;
4906
- if (!resources) return [];
4907
- const output = [];
4908
- for (const mount of resources.files ?? []) output.push(mount.resource);
4909
- output.push(...resources.tools ?? []);
4910
- output.push(...resources.skills ?? []);
4911
- output.push(...resources.agents ?? []);
4912
- output.push(...resources.commands ?? []);
4913
- if (typeof resources.instructions === "object") output.push(resources.instructions);
4914
- return output;
4915
- }
4916
- function resourceKey(resource) {
4917
- return canonicalCandidateDigest(resource);
4918
- }
4919
-
4920
- // src/candidate-execution/knowledge.ts
4921
- import { mkdtemp as mkdtemp3, rm as rm3 } from "fs/promises";
4922
- import { tmpdir as tmpdir3 } from "os";
4923
- import { join as join3, posix } from "path";
4924
- import { hashKnowledgeBase } from "@tangle-network/agent-knowledge";
4925
- var CANDIDATE_KNOWLEDGE_ROOT_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_ROOT";
4926
- var CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV = "TANGLE_CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG";
4927
- function candidateKnowledgeExecutionPaths(taskRoot, hasRetrievalConfig) {
4928
- if (!posix.isAbsolute(taskRoot) || posix.normalize(taskRoot) !== taskRoot) {
4929
- throw new Error("candidate knowledge requires a normalized absolute task root");
4930
- }
4931
- const parent = posix.join(taskRoot, ".tangle");
4932
- return {
4933
- root: posix.join(parent, "knowledge"),
4934
- ...hasRetrievalConfig ? { retrievalConfig: posix.join(parent, "knowledge-retrieval-config.json") } : {}
4935
- };
4936
- }
4937
- async function prepareAgentCandidateKnowledge(candidate, ports, arm) {
4938
- const knowledge = candidate.bundle.knowledge;
4939
- if (!knowledge) return void 0;
4940
- const archive = await verifiedArtifactBytes(candidate, knowledge.snapshot.archive);
4941
- const retrievalConfig = knowledge.retrievalConfig ? await verifiedArtifactBytes(candidate, knowledge.retrievalConfig) : void 0;
4942
- const root = await mkdtemp3(join3(tmpdir3(), "agent-candidate-knowledge-"));
4943
- try {
4944
- await ports.workspaces.materialize({
4945
- role: "knowledge",
4946
- snapshot: knowledge.snapshot,
4947
- archive,
4948
- destination: root
4949
- });
4950
- const expectedHash = arm === "baseline" ? knowledge.candidate.baseHash : knowledge.candidate.candidateHash;
4951
- const actualHash = `sha256:${await hashKnowledgeBase(root)}`;
4952
- if (actualHash !== expectedHash) {
4953
- throw new Error(
4954
- `materialized ${arm} knowledge does not match its measured content: expected ${expectedHash}, got ${actualHash}`
4955
- );
4956
- }
4957
- const files = await readMaterializedWorkspaceFiles(root, knowledge.snapshot.material);
4958
- return Object.freeze({
4959
- candidate: knowledge.candidate,
4960
- snapshot: knowledge.snapshot,
4961
- files: Object.freeze(
4962
- files.map(
4963
- (file) => Object.freeze({ path: file.path, mode: file.mode, bytes: Uint8Array.from(file.bytes) })
4964
- )
4965
- ),
4966
- ...retrievalConfig ? { retrievalConfig: Uint8Array.from(retrievalConfig) } : {}
4967
- });
4968
- } finally {
4969
- await rm3(root, { recursive: true, force: true });
4970
- }
4971
- }
4972
-
4973
4732
  // src/candidate-execution/prepare.ts
4974
- import { randomBytes as randomBytes3 } from "crypto";
4733
+ import { randomBytes as randomBytes2 } from "crypto";
4975
4734
  import { lstat as lstat2, readdir as readdir2 } from "fs/promises";
4976
4735
  import { isAbsolute, posix as posix2, relative as relative2, resolve as resolveHostPath } from "path";
4977
4736
  import {
@@ -5097,7 +4856,7 @@ async function prepareAgentCandidateExecution(candidate, task, ports, options =
5097
4856
  const profileActivation = profileApplication.profileActivation;
5098
4857
  const container = await resolveContainer(candidate, task, ports);
5099
4858
  const resolvedModel = await resolveModel(candidate, task, ports);
5100
- const preparationId = `candidate-preparation.${randomBytes3(32).toString("base64url")}`;
4859
+ const preparationId = `candidate-preparation.${randomBytes2(32).toString("base64url")}`;
5101
4860
  const reservationExpiresAtMs = Date.now() + Math.max(MIN_RESERVATION_TTL_MS, reservationWindowMs);
5102
4861
  const modelReservation = await withinCandidateCleanupDeadline(
5103
4862
  () => ports.models.reserveGrant({
@@ -5802,17 +5561,17 @@ export {
5802
5561
  candidateClaimFileInternals,
5803
5562
  sealAgentCandidateModelSettlement,
5804
5563
  usdToNanos,
5805
- sealAgentCandidateExecutorStopAcknowledgement,
5806
- persistCandidateOutputArtifact,
5807
- persistCandidateModelSettlementEvidence,
5808
- RecoveryAgentCandidateTraceStore,
5809
- executePreparedAgentCandidate,
5810
5564
  AGENT_CANDIDATE_EXECUTION_SUPPORT,
5811
5565
  verifyAgentCandidateBundle,
5812
5566
  verifiedResourceTextByDigest,
5813
5567
  CANDIDATE_KNOWLEDGE_ROOT_ENV,
5814
5568
  CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV,
5815
5569
  candidateKnowledgeExecutionPaths,
5570
+ sealAgentCandidateExecutorStopAcknowledgement,
5571
+ persistCandidateOutputArtifact,
5572
+ persistCandidateModelSettlementEvidence,
5573
+ RecoveryAgentCandidateTraceStore,
5574
+ executePreparedAgentCandidate,
5816
5575
  prepareAgentCandidateExecution
5817
5576
  };
5818
- //# sourceMappingURL=chunk-HGSHPVJ6.js.map
5577
+ //# sourceMappingURL=chunk-LJLG734E.js.map