@tangle-network/agent-runtime 0.102.0 → 0.102.2

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 (77) 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.js +5 -4
  6. package/dist/{chunk-SPCD4IQQ.js → chunk-377GOJHJ.js} +2 -2
  7. package/dist/{chunk-LKKIM5QD.js → chunk-3DW5DEKQ.js} +3 -3
  8. package/dist/{chunk-4AMAFNUD.js → chunk-7FJJUC73.js} +311 -40
  9. package/dist/chunk-7FJJUC73.js.map +1 -0
  10. package/dist/{chunk-DA7YL6I4.js → chunk-CK76OZPM.js} +3 -3
  11. package/dist/{chunk-KSBUSEUA.js → chunk-EKUMRQNR.js} +2 -2
  12. package/dist/{chunk-23Z7N5IG.js → chunk-J6V6DWWS.js} +5 -5
  13. package/dist/{chunk-AIBIRAJ6.js → chunk-KSM6GFHP.js} +2 -2
  14. package/dist/chunk-L5DST3QC.js +351 -0
  15. package/dist/chunk-L5DST3QC.js.map +1 -0
  16. package/dist/{chunk-TGDHHHH4.js → chunk-LJLG734E.js} +12 -253
  17. package/dist/chunk-LJLG734E.js.map +1 -0
  18. package/dist/{chunk-MAONWP4R.js → chunk-QCXD7NHM.js} +611 -1419
  19. package/dist/chunk-QCXD7NHM.js.map +1 -0
  20. package/dist/chunk-ROILMKDL.js +1338 -0
  21. package/dist/chunk-ROILMKDL.js.map +1 -0
  22. package/dist/{chunk-N2CEE5Q3.js → chunk-SCOHHMKU.js} +3 -3
  23. package/dist/chunk-SQ3ZJH3Y.js +3082 -0
  24. package/dist/chunk-SQ3ZJH3Y.js.map +1 -0
  25. package/dist/chunk-UPWGXKXB.js +254 -0
  26. package/dist/chunk-UPWGXKXB.js.map +1 -0
  27. package/dist/{chunk-KVJQV342.js → chunk-ZUCUAFVF.js} +26 -1778
  28. package/dist/chunk-ZUCUAFVF.js.map +1 -0
  29. package/dist/{completion-gate-C80jiRfN.d.ts → completion-gate-C6dhVN-N.d.ts} +2 -2
  30. package/dist/{coordination-BFE3Den7.d.ts → coordination-D9l_YmwW.d.ts} +6 -6
  31. package/dist/environment-provider.d.ts +2 -2
  32. package/dist/{improve-CIml6hT3.d.ts → improve-B40dRu0X.d.ts} +40 -19
  33. package/dist/index.d.ts +329 -21
  34. package/dist/index.js +541 -137
  35. package/dist/index.js.map +1 -1
  36. package/dist/intelligence.d.ts +5 -5
  37. package/dist/intelligence.js +7 -5
  38. package/dist/intelligence.js.map +1 -1
  39. package/dist/knowledge.d.ts +8 -8
  40. package/dist/knowledge.js +9 -7
  41. package/dist/{local-harness-ZqCx51u7.d.ts → local-harness-CtK9dSny.d.ts} +14 -2
  42. package/dist/{loop-runner-bin-Cn1N2rRo.d.ts → loop-runner-bin-PnWslIw4.d.ts} +2 -2
  43. package/dist/loop-runner-bin.d.ts +6 -6
  44. package/dist/loop-runner-bin.js +6 -4
  45. package/dist/loops.d.ts +231 -460
  46. package/dist/loops.js +58 -37
  47. package/dist/mcp/bin.js +2 -2
  48. package/dist/mcp/index.d.ts +184 -12
  49. package/dist/mcp/index.js +31 -9
  50. package/dist/mcp/index.js.map +1 -1
  51. package/dist/mcp/memory-bin.d.ts +1 -0
  52. package/dist/mcp/memory-bin.js +22 -0
  53. package/dist/mcp/memory-bin.js.map +1 -0
  54. package/dist/profiles.d.ts +3 -3
  55. package/dist/structural-rollout-D7xik9XR.d.ts +446 -0
  56. package/dist/{substrate-DO2GHNg2.d.ts → substrate-Dyiqmd3o.d.ts} +1 -1
  57. package/dist/{supervise-BLPI50-w.d.ts → supervise-BQdNAXtK.d.ts} +4 -4
  58. package/dist/testing.js +10 -8
  59. package/dist/testing.js.map +1 -1
  60. package/dist/{types-B3vAW0Oq.d.ts → types-CLat4bT9.d.ts} +1 -1
  61. package/dist/{types-CmnA2iL3.d.ts → types-D870JlH0.d.ts} +2 -2
  62. package/dist/{worktree-fanout-DCA3G4bO.d.ts → worktree-fanout-DsIR4d6w.d.ts} +234 -234
  63. package/package.json +4 -3
  64. package/dist/chunk-4AMAFNUD.js.map +0 -1
  65. package/dist/chunk-IKGCKPDX.js +0 -1115
  66. package/dist/chunk-IKGCKPDX.js.map +0 -1
  67. package/dist/chunk-KVJQV342.js.map +0 -1
  68. package/dist/chunk-MAONWP4R.js.map +0 -1
  69. package/dist/chunk-TGDHHHH4.js.map +0 -1
  70. package/dist/{chunk-SPCD4IQQ.js.map → chunk-377GOJHJ.js.map} +0 -0
  71. package/dist/{chunk-LKKIM5QD.js.map → chunk-3DW5DEKQ.js.map} +0 -0
  72. package/dist/{chunk-DA7YL6I4.js.map → chunk-CK76OZPM.js.map} +0 -0
  73. package/dist/{chunk-KSBUSEUA.js.map → chunk-EKUMRQNR.js.map} +0 -0
  74. package/dist/{chunk-23Z7N5IG.js.map → chunk-J6V6DWWS.js.map} +0 -0
  75. package/dist/{chunk-AIBIRAJ6.js.map → chunk-KSM6GFHP.js.map} +0 -0
  76. package/dist/{chunk-N2CEE5Q3.js.map → chunk-SCOHHMKU.js.map} +0 -0
  77. package/dist/{sanitize-BTSsdBXw.d.ts → sanitize-DEbPNtyI.d.ts} +58 -58
@@ -0,0 +1,254 @@
1
+ // src/candidate-execution/protected-redaction.ts
2
+ import { createHmac, randomBytes } from "crypto";
3
+ import {
4
+ DEFAULT_REDACTION_RULES,
5
+ REDACTION_VERSION,
6
+ redactString
7
+ } from "@tangle-network/agent-eval";
8
+ function createProtectedRecordRedactor(protectedValues) {
9
+ const identityKey = randomBytes(32);
10
+ const aggregate = {
11
+ version: REDACTION_VERSION,
12
+ redactionCount: 0,
13
+ byRule: {}
14
+ };
15
+ const mergeReport = (report) => {
16
+ aggregate.version = report.version;
17
+ aggregate.redactionCount += report.redactionCount;
18
+ for (const [rule, count] of Object.entries(report.byRule)) {
19
+ aggregate.byRule[rule] = (aggregate.byRule[rule] ?? 0) + count;
20
+ }
21
+ };
22
+ const redactScalar = (value, record) => {
23
+ const redacted = redactProtectedValue(value, protectedValues);
24
+ if (record) mergeReport(redacted.report);
25
+ return redacted.value;
26
+ };
27
+ const identifier = (value, record) => {
28
+ const redacted = redactScalar(value, record);
29
+ if (redacted === value) return value;
30
+ const digest = createHmac("sha256", identityKey).update(value).digest("hex");
31
+ return `${redacted}:hmac-sha256:${digest}`;
32
+ };
33
+ const transform = (value, record) => {
34
+ const transformed = transformProtectedRecord(
35
+ value,
36
+ void 0,
37
+ record,
38
+ redactScalar,
39
+ identifier
40
+ );
41
+ assertNoProtectedEvidence(transformed, protectedValues);
42
+ return transformed;
43
+ };
44
+ return Object.freeze({
45
+ record: (value) => transform(value, true),
46
+ query: (value) => transform(value, false),
47
+ identifier: (value) => identifier(value, false),
48
+ traceIdentity: (trace) => transform(trace, false),
49
+ report: () => ({
50
+ version: aggregate.version,
51
+ redactionCount: aggregate.redactionCount,
52
+ byRule: { ...aggregate.byRule }
53
+ })
54
+ });
55
+ }
56
+ function redactProtectedValue(value, protectedValues) {
57
+ const report = {
58
+ version: REDACTION_VERSION,
59
+ redactionCount: 0,
60
+ byRule: {}
61
+ };
62
+ const rules = protectedRedactionRules(protectedValues);
63
+ const redacted = redactNode(value, protectedValues, rules, report);
64
+ assertNoProtectedEvidence(redacted, protectedValues);
65
+ return { value: redacted, report };
66
+ }
67
+ function redactProtectedReason(reason, protectedValues) {
68
+ try {
69
+ return redactProtectedValue(reason, protectedValues).value;
70
+ } catch {
71
+ return "candidate execution failed with a protected error";
72
+ }
73
+ }
74
+ function assertNoProtectedEvidence(value, protectedValues) {
75
+ if (value instanceof Uint8Array) {
76
+ assertNoProtectedBytes(value, protectedValues);
77
+ return;
78
+ }
79
+ if (typeof value === "string") {
80
+ for (const protectedValue of protectedValueVariants(protectedValues)) {
81
+ if (value.includes(protectedValue)) {
82
+ throw new Error("protected value survived candidate evidence redaction");
83
+ }
84
+ }
85
+ if (decodedBase64ContainsProtectedValue(value, protectedValues)) {
86
+ throw new Error("base64 protected value survived candidate evidence redaction");
87
+ }
88
+ return;
89
+ }
90
+ if (Array.isArray(value)) {
91
+ for (const entry of value) assertNoProtectedEvidence(entry, protectedValues);
92
+ return;
93
+ }
94
+ if (value && typeof value === "object") {
95
+ for (const [key, entry] of Object.entries(value)) {
96
+ assertNoProtectedEvidence(key, protectedValues);
97
+ assertNoProtectedEvidence(entry, protectedValues);
98
+ }
99
+ }
100
+ }
101
+ function assertNoProtectedBytes(bytes, protectedValues) {
102
+ if (containsProtectedBytes(bytes, protectedValues)) {
103
+ throw new Error("protected value survived candidate evidence byte redaction");
104
+ }
105
+ }
106
+ function redactNode(value, protectedValues, rules, report) {
107
+ if (value instanceof Uint8Array) {
108
+ if (containsProtectedBytes(value, protectedValues)) {
109
+ recordRedaction(report, "candidate-access-binary", 1);
110
+ return Uint8Array.from(Buffer.from("[redacted:candidate-access-binary]", "utf8"));
111
+ }
112
+ return Uint8Array.from(value);
113
+ }
114
+ if (typeof value === "string") {
115
+ if (decodedBase64ContainsProtectedValue(value, protectedValues)) {
116
+ recordRedaction(report, "candidate-access-binary", 1);
117
+ return "[redacted:candidate-access-binary]";
118
+ }
119
+ const redacted = redactString(value, [...rules]);
120
+ for (const [rule, count] of Object.entries(redacted.report.byRule)) {
121
+ recordRedaction(report, rule, count);
122
+ }
123
+ return redacted.output;
124
+ }
125
+ if (Array.isArray(value)) {
126
+ return value.map((entry) => redactNode(entry, protectedValues, rules, report));
127
+ }
128
+ if (value && typeof value === "object") {
129
+ const entries = [];
130
+ const seenKeys = /* @__PURE__ */ new Set();
131
+ for (const [key, entry] of Object.entries(value)) {
132
+ const redactedKey = redactNode(key, protectedValues, rules, report);
133
+ if (typeof redactedKey !== "string" || seenKeys.has(redactedKey)) {
134
+ throw new Error("protected evidence redaction produced an ambiguous object key");
135
+ }
136
+ seenKeys.add(redactedKey);
137
+ entries.push([redactedKey, redactNode(entry, protectedValues, rules, report)]);
138
+ }
139
+ return Object.fromEntries(entries);
140
+ }
141
+ return value;
142
+ }
143
+ function transformProtectedRecord(value, fieldName, record, redactScalar, redactIdentifier) {
144
+ if (value instanceof Uint8Array) return redactScalar(value, record);
145
+ if (typeof value === "string") {
146
+ return fieldName && isIdentifierFieldName(fieldName) ? redactIdentifier(value, record) : redactScalar(value, record);
147
+ }
148
+ if (Array.isArray(value)) {
149
+ return value.map(
150
+ (entry) => transformProtectedRecord(entry, fieldName, record, redactScalar, redactIdentifier)
151
+ );
152
+ }
153
+ if (!value || typeof value !== "object") return value;
154
+ if (fieldName === "tags") {
155
+ return transformTagMap(value, record, redactScalar, redactIdentifier);
156
+ }
157
+ if (fieldName === "tag") {
158
+ return transformTagFilter(value, record, redactScalar, redactIdentifier);
159
+ }
160
+ const entries = [];
161
+ const seenKeys = /* @__PURE__ */ new Set();
162
+ for (const [key, entry] of Object.entries(value)) {
163
+ const redactedKey = redactScalar(key, record);
164
+ if (seenKeys.has(redactedKey)) {
165
+ throw new Error("protected evidence redaction produced an ambiguous object key");
166
+ }
167
+ seenKeys.add(redactedKey);
168
+ entries.push([
169
+ redactedKey,
170
+ transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)
171
+ ]);
172
+ }
173
+ return Object.fromEntries(entries);
174
+ }
175
+ function transformTagMap(value, record, redactScalar, redactIdentifier) {
176
+ const entries = [];
177
+ const seenKeys = /* @__PURE__ */ new Set();
178
+ for (const [key, entry] of Object.entries(value)) {
179
+ const redactedKey = redactIdentifier(key, record);
180
+ if (seenKeys.has(redactedKey)) {
181
+ throw new Error("protected evidence redaction produced an ambiguous trace tag");
182
+ }
183
+ seenKeys.add(redactedKey);
184
+ entries.push([
185
+ redactedKey,
186
+ typeof entry === "string" ? redactIdentifier(entry, record) : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)
187
+ ]);
188
+ }
189
+ return Object.fromEntries(entries);
190
+ }
191
+ function transformTagFilter(value, record, redactScalar, redactIdentifier) {
192
+ const output = {};
193
+ for (const [key, entry] of Object.entries(value)) {
194
+ const redactedKey = redactScalar(key, record);
195
+ output[redactedKey] = (key === "key" || key === "value") && typeof entry === "string" ? redactIdentifier(entry, record) : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier);
196
+ }
197
+ return output;
198
+ }
199
+ function isIdentifierFieldName(name) {
200
+ return /ids?$/i.test(name);
201
+ }
202
+ function protectedRedactionRules(protectedValues) {
203
+ const exactRules = protectedValueVariants(protectedValues).sort((left, right) => right.length - left.length || left.localeCompare(right)).map((value, index) => ({
204
+ id: `candidate-access-${index}`,
205
+ pattern: new RegExp(escapeRegularExpression(value), "g"),
206
+ replacement: "[redacted:candidate-access]"
207
+ }));
208
+ return [...exactRules, ...DEFAULT_REDACTION_RULES];
209
+ }
210
+ function recordRedaction(report, rule, count) {
211
+ if (count <= 0) return;
212
+ report.redactionCount += count;
213
+ report.byRule[rule] = (report.byRule[rule] ?? 0) + count;
214
+ }
215
+ function containsProtectedBytes(bytes, protectedValues) {
216
+ const source = Buffer.from(bytes);
217
+ return protectedValueVariants(protectedValues).some(
218
+ (value) => source.includes(Buffer.from(value, "utf8"))
219
+ );
220
+ }
221
+ function decodedBase64ContainsProtectedValue(value, protectedValues) {
222
+ if (value.length < 4 || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {
223
+ return false;
224
+ }
225
+ try {
226
+ return containsProtectedBytes(Buffer.from(value, "base64"), protectedValues);
227
+ } catch {
228
+ return false;
229
+ }
230
+ }
231
+ function protectedValueVariants(protectedValues) {
232
+ const variants = /* @__PURE__ */ new Set();
233
+ for (const value of normalizedProtectedValues(protectedValues)) {
234
+ variants.add(value);
235
+ variants.add(Buffer.from(value, "utf8").toString("base64"));
236
+ variants.add(Buffer.from(value, "utf8").toString("base64url"));
237
+ variants.add(encodeURIComponent(value));
238
+ }
239
+ return [...variants];
240
+ }
241
+ function normalizedProtectedValues(values) {
242
+ return [...new Set(values.filter((value) => value.length > 0))];
243
+ }
244
+ function escapeRegularExpression(value) {
245
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
246
+ }
247
+
248
+ export {
249
+ createProtectedRecordRedactor,
250
+ redactProtectedValue,
251
+ redactProtectedReason,
252
+ assertNoProtectedBytes
253
+ };
254
+ //# sourceMappingURL=chunk-UPWGXKXB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/candidate-execution/protected-redaction.ts"],"sourcesContent":["import { createHmac, randomBytes } from 'node:crypto'\n\nimport {\n DEFAULT_REDACTION_RULES,\n REDACTION_VERSION,\n type RedactionRule,\n redactString,\n} from '@tangle-network/agent-eval'\n\nexport interface ProtectedRedactionReport {\n version: string\n redactionCount: number\n byRule: Record<string, number>\n}\n\nexport interface ProtectedTraceIdentity {\n readonly runId: string\n readonly tags: Readonly<Record<string, string>>\n}\n\nexport interface ProtectedRecordRedactor {\n record<T>(value: T): T\n query<T>(value: T): T\n identifier(value: string): string\n traceIdentity(trace: ProtectedTraceIdentity): ProtectedTraceIdentity\n report(): ProtectedRedactionReport\n}\n\n/** Create one execution-local namespace for identifiers changed by redaction. */\nexport function createProtectedRecordRedactor(\n protectedValues: readonly string[],\n): ProtectedRecordRedactor {\n const identityKey = randomBytes(32)\n const aggregate: ProtectedRedactionReport = {\n version: REDACTION_VERSION,\n redactionCount: 0,\n byRule: {},\n }\n\n const mergeReport = (report: ProtectedRedactionReport): void => {\n aggregate.version = report.version\n aggregate.redactionCount += report.redactionCount\n for (const [rule, count] of Object.entries(report.byRule)) {\n aggregate.byRule[rule] = (aggregate.byRule[rule] ?? 0) + count\n }\n }\n\n const redactScalar = <T>(value: T, record: boolean): T => {\n const redacted = redactProtectedValue(value, protectedValues)\n if (record) mergeReport(redacted.report)\n return redacted.value\n }\n\n const identifier = (value: string, record: boolean): string => {\n const redacted = redactScalar(value, record)\n if (redacted === value) return value\n const digest = createHmac('sha256', identityKey).update(value).digest('hex')\n return `${redacted}:hmac-sha256:${digest}`\n }\n\n const transform = <T>(value: T, record: boolean): T => {\n const transformed = transformProtectedRecord(\n value,\n undefined,\n record,\n redactScalar,\n identifier,\n ) as T\n assertNoProtectedEvidence(transformed, protectedValues)\n return transformed\n }\n\n return Object.freeze({\n record: <T>(value: T): T => transform(value, true),\n query: <T>(value: T): T => transform(value, false),\n identifier: (value: string): string => identifier(value, false),\n traceIdentity: (trace: ProtectedTraceIdentity): ProtectedTraceIdentity =>\n transform(trace, false),\n report: (): ProtectedRedactionReport => ({\n version: aggregate.version,\n redactionCount: aggregate.redactionCount,\n byRule: { ...aggregate.byRule },\n }),\n })\n}\n\n/** Redact protected values at the first persistence boundary, including object keys and bytes. */\nexport function redactProtectedValue<T>(\n value: T,\n protectedValues: readonly string[],\n): { value: T; report: ProtectedRedactionReport } {\n const report: ProtectedRedactionReport = {\n version: REDACTION_VERSION,\n redactionCount: 0,\n byRule: {},\n }\n const rules = protectedRedactionRules(protectedValues)\n const redacted = redactNode(value, protectedValues, rules, report) as T\n assertNoProtectedEvidence(redacted, protectedValues)\n return { value: redacted, report }\n}\n\nexport function redactProtectedReason(reason: string, protectedValues: readonly string[]): string {\n try {\n return redactProtectedValue(reason, protectedValues).value\n } catch {\n return 'candidate execution failed with a protected error'\n }\n}\n\nexport function assertNoProtectedEvidence(\n value: unknown,\n protectedValues: readonly string[],\n): void {\n if (value instanceof Uint8Array) {\n assertNoProtectedBytes(value, protectedValues)\n return\n }\n if (typeof value === 'string') {\n for (const protectedValue of protectedValueVariants(protectedValues)) {\n if (value.includes(protectedValue)) {\n throw new Error('protected value survived candidate evidence redaction')\n }\n }\n if (decodedBase64ContainsProtectedValue(value, protectedValues)) {\n throw new Error('base64 protected value survived candidate evidence redaction')\n }\n return\n }\n if (Array.isArray(value)) {\n for (const entry of value) assertNoProtectedEvidence(entry, protectedValues)\n return\n }\n if (value && typeof value === 'object') {\n for (const [key, entry] of Object.entries(value)) {\n assertNoProtectedEvidence(key, protectedValues)\n assertNoProtectedEvidence(entry, protectedValues)\n }\n }\n}\n\nexport function assertNoProtectedBytes(\n bytes: Uint8Array,\n protectedValues: readonly string[],\n): void {\n if (containsProtectedBytes(bytes, protectedValues)) {\n throw new Error('protected value survived candidate evidence byte redaction')\n }\n}\n\nfunction redactNode(\n value: unknown,\n protectedValues: readonly string[],\n rules: readonly RedactionRule[],\n report: ProtectedRedactionReport,\n): unknown {\n if (value instanceof Uint8Array) {\n if (containsProtectedBytes(value, protectedValues)) {\n recordRedaction(report, 'candidate-access-binary', 1)\n return Uint8Array.from(Buffer.from('[redacted:candidate-access-binary]', 'utf8'))\n }\n return Uint8Array.from(value)\n }\n if (typeof value === 'string') {\n if (decodedBase64ContainsProtectedValue(value, protectedValues)) {\n recordRedaction(report, 'candidate-access-binary', 1)\n return '[redacted:candidate-access-binary]'\n }\n const redacted = redactString(value, [...rules])\n for (const [rule, count] of Object.entries(redacted.report.byRule)) {\n recordRedaction(report, rule, count)\n }\n return redacted.output\n }\n if (Array.isArray(value)) {\n return value.map((entry) => redactNode(entry, protectedValues, rules, report))\n }\n if (value && typeof value === 'object') {\n const entries: Array<[string, unknown]> = []\n const seenKeys = new Set<string>()\n for (const [key, entry] of Object.entries(value)) {\n const redactedKey = redactNode(key, protectedValues, rules, report)\n if (typeof redactedKey !== 'string' || seenKeys.has(redactedKey)) {\n throw new Error('protected evidence redaction produced an ambiguous object key')\n }\n seenKeys.add(redactedKey)\n entries.push([redactedKey, redactNode(entry, protectedValues, rules, report)])\n }\n return Object.fromEntries(entries)\n }\n return value\n}\n\nfunction transformProtectedRecord(\n value: unknown,\n fieldName: string | undefined,\n record: boolean,\n redactScalar: <T>(value: T, record: boolean) => T,\n redactIdentifier: (value: string, record: boolean) => string,\n): unknown {\n if (value instanceof Uint8Array) return redactScalar(value, record)\n if (typeof value === 'string') {\n return fieldName && isIdentifierFieldName(fieldName)\n ? redactIdentifier(value, record)\n : redactScalar(value, record)\n }\n if (Array.isArray(value)) {\n return value.map((entry) =>\n transformProtectedRecord(entry, fieldName, record, redactScalar, redactIdentifier),\n )\n }\n if (!value || typeof value !== 'object') return value\n\n if (fieldName === 'tags') {\n return transformTagMap(value, record, redactScalar, redactIdentifier)\n }\n if (fieldName === 'tag') {\n return transformTagFilter(value, record, redactScalar, redactIdentifier)\n }\n\n const entries: Array<[string, unknown]> = []\n const seenKeys = new Set<string>()\n for (const [key, entry] of Object.entries(value)) {\n const redactedKey = redactScalar(key, record)\n if (seenKeys.has(redactedKey)) {\n throw new Error('protected evidence redaction produced an ambiguous object key')\n }\n seenKeys.add(redactedKey)\n entries.push([\n redactedKey,\n transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier),\n ])\n }\n return Object.fromEntries(entries)\n}\n\nfunction transformTagMap(\n value: object,\n record: boolean,\n redactScalar: <T>(value: T, record: boolean) => T,\n redactIdentifier: (value: string, record: boolean) => string,\n): Record<string, unknown> {\n const entries: Array<[string, unknown]> = []\n const seenKeys = new Set<string>()\n for (const [key, entry] of Object.entries(value)) {\n const redactedKey = redactIdentifier(key, record)\n if (seenKeys.has(redactedKey)) {\n throw new Error('protected evidence redaction produced an ambiguous trace tag')\n }\n seenKeys.add(redactedKey)\n entries.push([\n redactedKey,\n typeof entry === 'string'\n ? redactIdentifier(entry, record)\n : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier),\n ])\n }\n return Object.fromEntries(entries)\n}\n\nfunction transformTagFilter(\n value: object,\n record: boolean,\n redactScalar: <T>(value: T, record: boolean) => T,\n redactIdentifier: (value: string, record: boolean) => string,\n): Record<string, unknown> {\n const output: Record<string, unknown> = {}\n for (const [key, entry] of Object.entries(value)) {\n const redactedKey = redactScalar(key, record)\n output[redactedKey] =\n (key === 'key' || key === 'value') && typeof entry === 'string'\n ? redactIdentifier(entry, record)\n : transformProtectedRecord(entry, key, record, redactScalar, redactIdentifier)\n }\n return output\n}\n\nfunction isIdentifierFieldName(name: string): boolean {\n return /ids?$/i.test(name)\n}\n\nfunction protectedRedactionRules(protectedValues: readonly string[]): RedactionRule[] {\n const exactRules = protectedValueVariants(protectedValues)\n .sort((left, right) => right.length - left.length || left.localeCompare(right))\n .map((value, index) => ({\n id: `candidate-access-${index}`,\n pattern: new RegExp(escapeRegularExpression(value), 'g'),\n replacement: '[redacted:candidate-access]',\n }))\n return [...exactRules, ...DEFAULT_REDACTION_RULES]\n}\n\nfunction recordRedaction(report: ProtectedRedactionReport, rule: string, count: number): void {\n if (count <= 0) return\n report.redactionCount += count\n report.byRule[rule] = (report.byRule[rule] ?? 0) + count\n}\n\nfunction containsProtectedBytes(bytes: Uint8Array, protectedValues: readonly string[]): boolean {\n const source = Buffer.from(bytes)\n return protectedValueVariants(protectedValues).some((value) =>\n source.includes(Buffer.from(value, 'utf8')),\n )\n}\n\nfunction decodedBase64ContainsProtectedValue(\n value: string,\n protectedValues: readonly string[],\n): boolean {\n if (value.length < 4 || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {\n return false\n }\n try {\n return containsProtectedBytes(Buffer.from(value, 'base64'), protectedValues)\n } catch {\n return false\n }\n}\n\nfunction protectedValueVariants(protectedValues: readonly string[]): string[] {\n const variants = new Set<string>()\n for (const value of normalizedProtectedValues(protectedValues)) {\n variants.add(value)\n variants.add(Buffer.from(value, 'utf8').toString('base64'))\n variants.add(Buffer.from(value, 'utf8').toString('base64url'))\n variants.add(encodeURIComponent(value))\n }\n return [...variants]\n}\n\nfunction normalizedProtectedValues(values: readonly string[]): string[] {\n return [...new Set(values.filter((value) => value.length > 0))]\n}\n\nfunction escapeRegularExpression(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n"],"mappings":"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","names":[]}