@vaudience/aigentflow-flow-validator 0.19.0 → 0.20.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.
package/dist/index.js CHANGED
@@ -430,7 +430,7 @@ function validateBasicStructure(flow, issues) {
430
430
 
431
431
  // src/spec/aigentflow-spec.json
432
432
  var aigentflow_spec_default = {
433
- specVersion: "2.820.0",
433
+ specVersion: "2.821.0",
434
434
  inputSchemaVersion: 1,
435
435
  executorSchemes: [
436
436
  "a2a",
@@ -1255,6 +1255,34 @@ var aigentflow_spec_default = {
1255
1255
  }
1256
1256
  }
1257
1257
  },
1258
+ complianceResidency: {
1259
+ code: "compliance_residency_unenforced",
1260
+ euResidencyCodes: ["EU", "DE", "FR", "IE", "NL", "IT", "ES"],
1261
+ regionLaneProviders: [
1262
+ "bedrock",
1263
+ "google",
1264
+ "azure",
1265
+ "openai",
1266
+ "assemblyai",
1267
+ "speechmatics",
1268
+ "deepgram",
1269
+ "mistral"
1270
+ ],
1271
+ aiProtocol: "ai",
1272
+ protocolSeparator: "://",
1273
+ regionParam: "region",
1274
+ enforceRegionParam: "enforce_region",
1275
+ baseUrlParamSuffix: "_base_url",
1276
+ enforceRegionTrueStrings: ["true", "1", "yes"],
1277
+ stepFieldFormat: "steps.%s.executor",
1278
+ loopStepFieldFormat: "steps.%s.loop.steps.%s.executor",
1279
+ orchestratorField: "orchestrator.exons",
1280
+ siteStepFormat: "step %q",
1281
+ siteLoopStepFormat: "loop sub-step %q of step %q",
1282
+ siteOrchestrator: "the orchestrator",
1283
+ messageFormat: "%s calls provider %q, whose default endpoint commits to no jurisdiction, but sets neither region nor enforce_region, so nothing pins it to the declared residency %v. compliance.residency is a catalogue eligibility check, not endpoint evidence",
1284
+ suggestion: "Add `region: eu` and `enforce_region: true` to the call (an orchestrator: the same two keys on the orchestrator block). Prove it afterwards: the step record's diagnostics.region is stamped from the host actually dialled."
1285
+ },
1258
1286
  examples: {
1259
1287
  limits: {
1260
1288
  maxPerFlow: 50,
@@ -1850,6 +1878,25 @@ var CREDENTIAL_ENDPOINT_PAIRING = {
1850
1878
  familyKeySeparator: aigentflow_spec_default.credentialEndpointPairing.familyKeySeparator,
1851
1879
  families: aigentflow_spec_default.credentialEndpointPairing.families
1852
1880
  };
1881
+ var COMPLIANCE_RESIDENCY = {
1882
+ code: aigentflow_spec_default.complianceResidency.code,
1883
+ euResidencyCodes: aigentflow_spec_default.complianceResidency.euResidencyCodes,
1884
+ regionLaneProviders: aigentflow_spec_default.complianceResidency.regionLaneProviders,
1885
+ aiProtocol: aigentflow_spec_default.complianceResidency.aiProtocol,
1886
+ protocolSeparator: aigentflow_spec_default.complianceResidency.protocolSeparator,
1887
+ regionParam: aigentflow_spec_default.complianceResidency.regionParam,
1888
+ enforceRegionParam: aigentflow_spec_default.complianceResidency.enforceRegionParam,
1889
+ baseUrlParamSuffix: aigentflow_spec_default.complianceResidency.baseUrlParamSuffix,
1890
+ enforceRegionTrueStrings: aigentflow_spec_default.complianceResidency.enforceRegionTrueStrings,
1891
+ stepFieldFormat: aigentflow_spec_default.complianceResidency.stepFieldFormat,
1892
+ loopStepFieldFormat: aigentflow_spec_default.complianceResidency.loopStepFieldFormat,
1893
+ orchestratorField: aigentflow_spec_default.complianceResidency.orchestratorField,
1894
+ siteStepFormat: aigentflow_spec_default.complianceResidency.siteStepFormat,
1895
+ siteLoopStepFormat: aigentflow_spec_default.complianceResidency.siteLoopStepFormat,
1896
+ siteOrchestrator: aigentflow_spec_default.complianceResidency.siteOrchestrator,
1897
+ messageFormat: aigentflow_spec_default.complianceResidency.messageFormat,
1898
+ suggestion: aigentflow_spec_default.complianceResidency.suggestion
1899
+ };
1853
1900
  var EXAMPLES = {
1854
1901
  limits: aigentflow_spec_default.examples.limits,
1855
1902
  idPattern: new RegExp(aigentflow_spec_default.examples.idPattern),
@@ -5202,6 +5249,141 @@ function warnOrchestratorToolWithheld(flow, orch, report, issues) {
5202
5249
  }
5203
5250
  }
5204
5251
 
5252
+ // src/validators/complianceResidency.ts
5253
+ function own2(m, key) {
5254
+ if (!isRecord(m) || !Object.prototype.hasOwnProperty.call(m, key)) return void 0;
5255
+ return m[key];
5256
+ }
5257
+ function sprintf(format, ...args) {
5258
+ let i = 0;
5259
+ return format.replace(/%[sqv]/g, (verb) => {
5260
+ const arg = args[i++] ?? "";
5261
+ return verb === "%q" ? JSON.stringify(arg) : arg;
5262
+ });
5263
+ }
5264
+ function literalOrEmpty(s) {
5265
+ const t = goTrimSpace2(s);
5266
+ return t.includes(TEMPLATE_ACTION_OPEN) ? "" : t;
5267
+ }
5268
+ function euOnlyResidency(flow, issues) {
5269
+ const raw = own2(own2(flow, "compliance"), "residency");
5270
+ if (!isArray(raw)) return null;
5271
+ const codes = [];
5272
+ for (let i = 0; i < raw.length; i++) {
5273
+ if (raw[i] === null) continue;
5274
+ const code = issues.stringAt(raw[i], `compliance.residency[${i}]`);
5275
+ if (code === null) return null;
5276
+ codes.push(code);
5277
+ }
5278
+ if (codes.length === 0) return null;
5279
+ const eu = new Set(COMPLIANCE_RESIDENCY.euResidencyCodes);
5280
+ return codes.every((c) => eu.has(goTrimSpace2(c).toUpperCase())) ? codes : null;
5281
+ }
5282
+ function aiProvider(executor) {
5283
+ const prefix = COMPLIANCE_RESIDENCY.aiProtocol + COMPLIANCE_RESIDENCY.protocolSeparator;
5284
+ if (!executor.startsWith(prefix)) return "";
5285
+ const rest = executor.slice(prefix.length);
5286
+ const slash = rest.indexOf("/");
5287
+ const provider = slash > 0 ? rest.slice(0, slash) : "";
5288
+ return provider.includes(TEMPLATE_ACTION_OPEN) ? "" : provider;
5289
+ }
5290
+ function isRegionLane(provider) {
5291
+ const literal = literalOrEmpty(provider);
5292
+ return literal !== "" && COMPLIANCE_RESIDENCY.regionLaneProviders.includes(literal.toLowerCase());
5293
+ }
5294
+ function nonBlankString(m, key) {
5295
+ const v = own2(m, key);
5296
+ return typeof v === "string" && goTrimSpace2(v) !== "";
5297
+ }
5298
+ function queryEnforcesRegion(query) {
5299
+ const v = own2(query, COMPLIANCE_RESIDENCY.enforceRegionParam);
5300
+ if (typeof v === "boolean") return v;
5301
+ return typeof v === "string" && COMPLIANCE_RESIDENCY.enforceRegionTrueStrings.includes(v);
5302
+ }
5303
+ function flowDirectsEndpoint(flow, provider, issues) {
5304
+ const key = provider.toLowerCase();
5305
+ const inst = own2(own2(flow, "executor_config"), key);
5306
+ if (!isRecord(inst)) return false;
5307
+ const baseUrl = issues.stringOf(inst, "base_url", `executor_config.${key}`);
5308
+ return baseUrl !== null && goTrimSpace2(baseUrl) !== "";
5309
+ }
5310
+ function callPinsEndpoint(flow, provider, query, issues) {
5311
+ if (nonBlankString(query, COMPLIANCE_RESIDENCY.regionParam)) return true;
5312
+ if (queryEnforcesRegion(query)) return true;
5313
+ if (nonBlankString(query, provider.toLowerCase() + COMPLIANCE_RESIDENCY.baseUrlParamSuffix)) return true;
5314
+ return flowDirectsEndpoint(flow, provider, issues);
5315
+ }
5316
+ function validateResidencyEnforcement(flow, issues) {
5317
+ const residency = euOnlyResidency(flow, issues);
5318
+ if (residency === null) return;
5319
+ const warn = (site, field, stepId, provider) => {
5320
+ issues.warn({
5321
+ field,
5322
+ ...stepId === void 0 ? {} : { stepId },
5323
+ code: COMPLIANCE_RESIDENCY.code,
5324
+ message: sprintf(COMPLIANCE_RESIDENCY.messageFormat, site, provider, `[${residency.join(" ")}]`),
5325
+ suggestion: COMPLIANCE_RESIDENCY.suggestion
5326
+ });
5327
+ };
5328
+ const steps = flow.steps;
5329
+ if (isRecord(steps)) {
5330
+ for (const stepId of Object.keys(steps).sort()) {
5331
+ const step = steps[stepId];
5332
+ if (!isRecord(step)) continue;
5333
+ const calls = [
5334
+ {
5335
+ executor: issues.stringOf(step, "executor", `steps.${stepId}`) ?? "",
5336
+ query: own2(step, "query"),
5337
+ subId: null
5338
+ }
5339
+ ];
5340
+ for (const sub of loopSubStepsOfStep(stepId, step)) {
5341
+ calls.push({
5342
+ executor: issues.stringOf(sub.raw, "executor", sub.basePath) ?? "",
5343
+ query: own2(sub.raw, "query"),
5344
+ subId: issues.stringOf(sub.raw, "id", sub.basePath) ?? ""
5345
+ });
5346
+ }
5347
+ for (const call of calls) {
5348
+ const provider = aiProvider(call.executor);
5349
+ if (!isRegionLane(provider)) continue;
5350
+ if (callPinsEndpoint(flow, provider, call.query, issues)) continue;
5351
+ if (call.subId === null) {
5352
+ warn(
5353
+ sprintf(COMPLIANCE_RESIDENCY.siteStepFormat, stepId),
5354
+ sprintf(COMPLIANCE_RESIDENCY.stepFieldFormat, stepId),
5355
+ stepId,
5356
+ provider
5357
+ );
5358
+ } else {
5359
+ warn(
5360
+ sprintf(COMPLIANCE_RESIDENCY.siteLoopStepFormat, call.subId, stepId),
5361
+ sprintf(COMPLIANCE_RESIDENCY.loopStepFieldFormat, stepId, call.subId),
5362
+ stepId,
5363
+ provider
5364
+ );
5365
+ }
5366
+ }
5367
+ }
5368
+ }
5369
+ warnOrchestrator(flow, issues, warn);
5370
+ }
5371
+ function warnOrchestrator(flow, issues, warn) {
5372
+ const orch = flow.orchestrator;
5373
+ if (!isRecord(orch)) return;
5374
+ const source = issues.stringOf(orch, "exons", "orchestrator");
5375
+ if (source === null || source === "") return;
5376
+ const report = inspectExonsFrontmatter(source);
5377
+ if (report.parseError !== null || !report.specRead || !report.hasSpec) return;
5378
+ const provider = literalOrEmpty(report.provider);
5379
+ if (!isRegionLane(provider)) return;
5380
+ const region = issues.stringOf(orch, "region", "orchestrator");
5381
+ if (region !== null && goTrimSpace2(region) !== "") return;
5382
+ if (orch.enforce_region === true) return;
5383
+ if (flowDirectsEndpoint(flow, provider, issues)) return;
5384
+ warn(COMPLIANCE_RESIDENCY.siteOrchestrator, COMPLIANCE_RESIDENCY.orchestratorField, void 0, provider);
5385
+ }
5386
+
5205
5387
  // src/validators/examples.ts
5206
5388
  var KEY_EXAMPLES = "examples";
5207
5389
  var VISIBILITY_PUBLIC = "public";
@@ -5279,7 +5461,7 @@ function num(n) {
5279
5461
  function has(o, key) {
5280
5462
  return Object.prototype.hasOwnProperty.call(o, key) && o[key] !== null && o[key] !== void 0;
5281
5463
  }
5282
- function own2(o, key) {
5464
+ function own3(o, key) {
5283
5465
  return Object.prototype.hasOwnProperty.call(o, key) ? o[key] : void 0;
5284
5466
  }
5285
5467
  function setOwn(o, key, value) {
@@ -5331,7 +5513,7 @@ function mergePatch(target, patch, depth) {
5331
5513
  continue;
5332
5514
  }
5333
5515
  if (isRecord(pv)) {
5334
- const current = own2(target, k);
5516
+ const current = own3(target, k);
5335
5517
  const existing = isRecord(current) ? deepCopy(current, 0) : {};
5336
5518
  mergePatch(existing, pv, depth + 1);
5337
5519
  setOwn(target, k, existing);
@@ -5351,7 +5533,7 @@ function asFileRef(v) {
5351
5533
  if (keys.length === 0) return null;
5352
5534
  for (const k of keys) if (!FILE_REF_KEYS.has(k)) return null;
5353
5535
  const str = (k) => {
5354
- const x = own2(v, k);
5536
+ const x = own3(v, k);
5355
5537
  return typeof x === "string" ? x : "";
5356
5538
  };
5357
5539
  return {
@@ -5419,7 +5601,7 @@ var Walker = class _Walker {
5419
5601
  `the examples block is ${size} bytes; the limit is ${L.maxBlockBytes}. Move large inputs or target outputs to a file reference (https URL).`
5420
5602
  );
5421
5603
  }
5422
- const allHeld = examples.every((e) => isRecord(e) && own2(e, "hold_out") === true);
5604
+ const allHeld = examples.every((e) => isRecord(e) && own3(e, "hold_out") === true);
5423
5605
  if (allHeld) {
5424
5606
  this.warn(
5425
5607
  "examples_all_held_out",
@@ -5507,9 +5689,9 @@ var Walker = class _Walker {
5507
5689
  `example ${q(label)} notes are ${notesN} characters; the limit is ${L.maxNotesRunes}`
5508
5690
  );
5509
5691
  }
5510
- this.validateTags(path, label, own2(ex, "tags"));
5511
- this.validateWeight(`${path}.weight`, label, numberOf(own2(ex, "weight")));
5512
- const minScore = numberOf(own2(ex, "min_score"));
5692
+ this.validateTags(path, label, own3(ex, "tags"));
5693
+ this.validateWeight(`${path}.weight`, label, numberOf(own3(ex, "weight")));
5694
+ const minScore = numberOf(own3(ex, "min_score"));
5513
5695
  if (minScore !== void 0 && !scoreInRange(minScore)) {
5514
5696
  this.err(
5515
5697
  "example_min_score_range",
@@ -5525,7 +5707,7 @@ var Walker = class _Walker {
5525
5707
  `example ${q(label)} has side_effects ${q(sideEffects)}; use refuse or allow`
5526
5708
  );
5527
5709
  }
5528
- const holdOut = own2(ex, "hold_out") === true;
5710
+ const holdOut = own3(ex, "hold_out") === true;
5529
5711
  if (holdOut && this.isPublic()) {
5530
5712
  this.err(
5531
5713
  "example_holdout_in_public_flow",
@@ -5548,17 +5730,17 @@ var Walker = class _Walker {
5548
5730
  `example ${q(label)} has neither input nor input_ref; use input: {} for a flow that takes no input`
5549
5731
  );
5550
5732
  }
5551
- const rawInput = own2(ex, "input");
5733
+ const rawInput = own3(ex, "input");
5552
5734
  const baseInput = isRecord(rawInput) ? rawInput : null;
5553
5735
  if (baseInput !== null) {
5554
5736
  this.checkInput(`${path}.input`, label, baseInput, "example_input_invalid");
5555
5737
  }
5556
- const rawInputRef = own2(ex, "input_ref");
5738
+ const rawInputRef = own3(ex, "input_ref");
5557
5739
  if (isRecord(rawInputRef)) {
5558
5740
  this.validateFileRef(`${path}.input_ref`, this.fileRefOf(rawInputRef, `${path}.input_ref`));
5559
5741
  }
5560
5742
  let binaryOnly = false;
5561
- const expected = own2(ex, "expected");
5743
+ const expected = own3(ex, "expected");
5562
5744
  if (!has(ex, "expected")) {
5563
5745
  this.err(
5564
5746
  "example_expected_missing",
@@ -5577,7 +5759,7 @@ var Walker = class _Walker {
5577
5759
  "this example can be run but not scored"
5578
5760
  );
5579
5761
  }
5580
- this.validateCheckpoints(path, label, own2(ex, "checkpoints"));
5762
+ this.validateCheckpoints(path, label, own3(ex, "checkpoints"));
5581
5763
  this.validateVariants(i, path, label, ex, hasInput, baseInput);
5582
5764
  this.scanSecretLike(i, path, ex);
5583
5765
  }
@@ -5637,8 +5819,8 @@ var Walker = class _Walker {
5637
5819
  );
5638
5820
  return;
5639
5821
  }
5640
- const schema = own2(this.flow, "input_schema");
5641
- const query = own2(this.flow, "query");
5822
+ const schema = own3(this.flow, "input_schema");
5823
+ const query = own3(this.flow, "query");
5642
5824
  if (isRecord(schema)) {
5643
5825
  this.checkInputAgainstSchema(field, label, input, schema, code);
5644
5826
  } else if (isRecord(query) && Object.keys(query).length > 0) {
@@ -5706,29 +5888,29 @@ var Walker = class _Walker {
5706
5888
  }
5707
5889
  }
5708
5890
  schemaFields(schema) {
5709
- const raw = own2(schema, "fields");
5891
+ const raw = own3(schema, "fields");
5710
5892
  if (!Array.isArray(raw)) return [];
5711
5893
  const out = [];
5712
5894
  raw.forEach((f, i) => {
5713
5895
  if (!isRecord(f)) return;
5714
5896
  const base = `input_schema.fields[${i}]`;
5715
- const enumRaw = own2(f, "enum");
5897
+ const enumRaw = own3(f, "enum");
5716
5898
  const enumValues = [];
5717
5899
  if (Array.isArray(enumRaw)) {
5718
5900
  enumRaw.forEach((e, j) => {
5719
5901
  enumValues.push(e === null ? "" : this.issues.stringAt(e, `${base}.enum[${j}]`) ?? "");
5720
5902
  });
5721
5903
  }
5722
- const vw = own2(f, "visible_when");
5904
+ const vw = own3(f, "visible_when");
5723
5905
  out.push({
5724
5906
  name: this.s(f, "name", base),
5725
5907
  type: this.s(f, "type", base),
5726
- required: own2(f, "required") === true,
5908
+ required: own3(f, "required") === true,
5727
5909
  enumValues,
5728
5910
  visibleWhen: isRecord(vw) ? {
5729
5911
  field: this.s(vw, "field", `${base}.visible_when`),
5730
- equals: own2(vw, "equals"),
5731
- in: Array.isArray(own2(vw, "in")) ? own2(vw, "in") : []
5912
+ equals: own3(vw, "equals"),
5913
+ in: Array.isArray(own3(vw, "in")) ? own3(vw, "in") : []
5732
5914
  } : null
5733
5915
  });
5734
5916
  });
@@ -5739,7 +5921,7 @@ var Walker = class _Walker {
5739
5921
  const failures = [];
5740
5922
  for (const f of fields) {
5741
5923
  if (!isVisible(f, runInput)) continue;
5742
- const raw = own2(runInput, f.name);
5924
+ const raw = own3(runInput, f.name);
5743
5925
  if (raw === void 0 || raw === null) {
5744
5926
  if (f.required) {
5745
5927
  failures.push({
@@ -5850,7 +6032,7 @@ var Walker = class _Walker {
5850
6032
  /** The names `fields` / `exact` may use, and whether such a list is declared at all. */
5851
6033
  outputNamesFor(kind, stepId) {
5852
6034
  if (kind === "final") {
5853
- const out = own2(this.flow, "output");
6035
+ const out = own3(this.flow, "output");
5854
6036
  const names2 = [];
5855
6037
  if (Array.isArray(out)) {
5856
6038
  out.forEach((item, i) => {
@@ -5859,10 +6041,10 @@ var Walker = class _Walker {
5859
6041
  }
5860
6042
  return { names: names2, declared: names2.length > 0 };
5861
6043
  }
5862
- const steps = own2(this.flow, "steps");
5863
- const step = isRecord(steps) ? own2(steps, stepId) : void 0;
5864
- const schema = isRecord(step) ? own2(step, "output_schema") : void 0;
5865
- const fields = isRecord(schema) ? own2(schema, "fields") : void 0;
6044
+ const steps = own3(this.flow, "steps");
6045
+ const step = isRecord(steps) ? own3(steps, stepId) : void 0;
6046
+ const schema = isRecord(step) ? own3(step, "output_schema") : void 0;
6047
+ const fields = isRecord(schema) ? own3(schema, "fields") : void 0;
5866
6048
  if (!Array.isArray(fields) || fields.length === 0) return { names: [], declared: false };
5867
6049
  const names = [];
5868
6050
  fields.forEach((f, i) => {
@@ -5881,8 +6063,8 @@ var Walker = class _Walker {
5881
6063
  );
5882
6064
  }
5883
6065
  const noOutput = status === STATUS_FAILED || status === STATUS_PAUSED_FOR_HUMAN;
5884
- const fieldsRec = own2(e, "fields");
5885
- const exactRec = own2(e, "exact");
6066
+ const fieldsRec = own3(e, "fields");
6067
+ const exactRec = own3(e, "exact");
5886
6068
  const fieldKeys = isRecord(fieldsRec) ? sortedKeys(fieldsRec) : [];
5887
6069
  const exactKeys = isRecord(exactRec) ? sortedKeys(exactRec) : [];
5888
6070
  const hasFields = fieldKeys.length > 0;
@@ -5900,7 +6082,7 @@ var Walker = class _Walker {
5900
6082
  `a case that ends in ${status} has no output to match; remove fields and exact, or expect status completed`
5901
6083
  );
5902
6084
  }
5903
- const minScore = numberOf(own2(e, "min_score"));
6085
+ const minScore = numberOf(own3(e, "min_score"));
5904
6086
  if (minScore !== void 0 && !scoreInRange(minScore)) {
5905
6087
  this.err(
5906
6088
  "example_min_score_range",
@@ -5927,7 +6109,7 @@ var Walker = class _Walker {
5927
6109
  }
5928
6110
  }
5929
6111
  }
5930
- const reference = own2(e, "reference");
6112
+ const reference = own3(e, "reference");
5931
6113
  if (isRecord(reference)) this.validateReference(`${path}.reference`, reference);
5932
6114
  const { names, declared } = this.outputNamesFor(kind, stepId);
5933
6115
  const checkKey = (field, key) => {
@@ -5954,12 +6136,12 @@ var Walker = class _Walker {
5954
6136
  for (const key of fieldKeys) {
5955
6137
  const fpath = `${path}.fields.${key}`;
5956
6138
  checkKey(fpath, key);
5957
- const matcher = own2(fieldsRec, key);
6139
+ const matcher = own3(fieldsRec, key);
5958
6140
  if (isRecord(matcher)) this.validateFieldMatcher(fpath, matcher);
5959
6141
  }
5960
6142
  for (const key of exactKeys) checkKey(`${path}.exact.${key}`, key);
5961
- const mustNot = this.stringList(own2(e, "must_not"), `${path}.must_not`);
5962
- const mustNotContain = this.stringList(own2(e, "must_not_contain"), `${path}.must_not_contain`);
6143
+ const mustNot = this.stringList(own3(e, "must_not"), `${path}.must_not`);
6144
+ const mustNotContain = this.stringList(own3(e, "must_not_contain"), `${path}.must_not_contain`);
5963
6145
  const mustNotMsg = `must_not takes up to ${L.maxMustNot} statements of at most ${L.maxMustNotRunes} characters each, none empty`;
5964
6146
  if (mustNot.length > L.maxMustNot) {
5965
6147
  this.err("example_must_not_invalid", `${path}.must_not`, mustNotMsg);
@@ -5980,9 +6162,9 @@ var Walker = class _Walker {
5980
6162
  }
5981
6163
  });
5982
6164
  for (const key of fieldKeys) {
5983
- const matcher = own2(fieldsRec, key);
6165
+ const matcher = own3(fieldsRec, key);
5984
6166
  if (!isRecord(matcher)) continue;
5985
- const eq = own2(matcher, "equals");
6167
+ const eq = own3(matcher, "equals");
5986
6168
  if (typeof eq !== "string" || eq === "") continue;
5987
6169
  for (const banned of mustNotContain) {
5988
6170
  if (banned !== "" && equalFold(banned, eq)) {
@@ -6042,7 +6224,7 @@ var Walker = class _Walker {
6042
6224
  }
6043
6225
  return;
6044
6226
  }
6045
- const refRec = own2(r, "ref");
6227
+ const refRec = own3(r, "ref");
6046
6228
  if (!isRecord(refRec)) return;
6047
6229
  const ref = this.fileRefOf(refRec, `${path}.ref`);
6048
6230
  this.validateFileRef(`${path}.ref`, ref);
@@ -6055,22 +6237,22 @@ var Walker = class _Walker {
6055
6237
  }
6056
6238
  }
6057
6239
  expectationIsBinaryReferenceOnly(e, path) {
6058
- const reference = own2(e, "reference");
6059
- const refRec = isRecord(reference) ? own2(reference, "ref") : void 0;
6240
+ const reference = own3(e, "reference");
6241
+ const refRec = isRecord(reference) ? own3(reference, "ref") : void 0;
6060
6242
  if (!isRecord(refRec)) return false;
6061
6243
  const mediaType = this.s(refRec, "media_type", `${path}.reference.ref`);
6062
6244
  if (mediaType === "" || isTextualMediaType(mediaType)) return false;
6063
6245
  const status = this.s(e, "status", path);
6064
- const fields = own2(e, "fields");
6065
- const exact = own2(e, "exact");
6066
- return this.s(e, "rubric", path) === "" && !(isRecord(fields) && Object.keys(fields).length > 0) && !(isRecord(exact) && Object.keys(exact).length > 0) && this.stringList(own2(e, "must_not"), `${path}.must_not`).length === 0 && this.stringList(own2(e, "must_not_contain"), `${path}.must_not_contain`).length === 0 && (status === "" || status === STATUS_COMPLETED);
6246
+ const fields = own3(e, "fields");
6247
+ const exact = own3(e, "exact");
6248
+ return this.s(e, "rubric", path) === "" && !(isRecord(fields) && Object.keys(fields).length > 0) && !(isRecord(exact) && Object.keys(exact).length > 0) && this.stringList(own3(e, "must_not"), `${path}.must_not`).length === 0 && this.stringList(own3(e, "must_not_contain"), `${path}.must_not_contain`).length === 0 && (status === "" || status === STATUS_COMPLETED);
6067
6249
  }
6068
6250
  validateFieldMatcher(path, m) {
6069
6251
  const L = EXAMPLES.limits;
6070
6252
  const matches = this.s(m, "matches", path);
6071
- const oneOf = own2(m, "one_of");
6072
- const approx = numberOf(own2(m, "approx"));
6073
- const tolerance = numberOf(own2(m, "tolerance"));
6253
+ const oneOf = own3(m, "one_of");
6254
+ const approx = numberOf(own3(m, "approx"));
6255
+ const tolerance = numberOf(own3(m, "tolerance"));
6074
6256
  let operators = 0;
6075
6257
  if (has(m, "equals")) operators++;
6076
6258
  if (this.s(m, "contains", path) !== "") operators++;
@@ -6078,7 +6260,7 @@ var Walker = class _Walker {
6078
6260
  if (matches !== "") operators++;
6079
6261
  if (Array.isArray(oneOf) && oneOf.length > 0) operators++;
6080
6262
  if (approx !== void 0) operators++;
6081
- if (typeof own2(m, "present") === "boolean") operators++;
6263
+ if (typeof own3(m, "present") === "boolean") operators++;
6082
6264
  if (operators !== 1) {
6083
6265
  this.err(
6084
6266
  "example_field_matcher_invalid",
@@ -6105,12 +6287,12 @@ var Walker = class _Walker {
6105
6287
  // -- checkpoints ------------------------------------------------------
6106
6288
  validateCheckpoints(path, label, cps) {
6107
6289
  if (!isRecord(cps) || Object.keys(cps).length === 0) return;
6108
- const stepsRaw = own2(this.flow, "steps");
6290
+ const stepsRaw = own3(this.flow, "steps");
6109
6291
  const steps = isRecord(stepsRaw) ? stepsRaw : {};
6110
6292
  const stepIds = sortedKeys(steps);
6111
6293
  for (const id of sortedKeys(cps)) {
6112
6294
  const cpath = `${path}.checkpoints.${id}`;
6113
- const step = own2(steps, id);
6295
+ const step = own3(steps, id);
6114
6296
  if (!isRecord(step)) {
6115
6297
  this.err(
6116
6298
  "example_checkpoint_step_unknown",
@@ -6120,7 +6302,7 @@ var Walker = class _Walker {
6120
6302
  );
6121
6303
  continue;
6122
6304
  }
6123
- const next = own2(step, "next");
6305
+ const next = own3(step, "next");
6124
6306
  if (has(step, "for_each") || has(step, "loop") || isRecord(next) && has(next, "parallel")) {
6125
6307
  this.err(
6126
6308
  "example_checkpoint_step_composite",
@@ -6129,7 +6311,7 @@ var Walker = class _Walker {
6129
6311
  );
6130
6312
  continue;
6131
6313
  }
6132
- const cp = own2(cps, id);
6314
+ const cp = own3(cps, id);
6133
6315
  if (cp === null || cp === void 0) {
6134
6316
  this.validateExpectation(cpath, label, {}, "checkpoint", id);
6135
6317
  } else if (isRecord(cp)) {
@@ -6140,7 +6322,7 @@ var Walker = class _Walker {
6140
6322
  // -- variants ---------------------------------------------------------
6141
6323
  validateVariants(i, path, label, ex, hasInput, baseInput) {
6142
6324
  const L = EXAMPLES.limits;
6143
- const variants = own2(ex, "variants");
6325
+ const variants = own3(ex, "variants");
6144
6326
  if (!Array.isArray(variants) || variants.length === 0) return;
6145
6327
  if (variants.length > L.maxVariants) {
6146
6328
  this.err(
@@ -6203,8 +6385,8 @@ var Walker = class _Walker {
6203
6385
  `example ${q(both)} notes are ${provN} characters; the limit is ${L.maxProvenanceRunes}`
6204
6386
  );
6205
6387
  }
6206
- this.validateWeight(`${vpath}.weight`, both, numberOf(own2(v, "weight")));
6207
- const patch = own2(v, "input_patch");
6388
+ this.validateWeight(`${vpath}.weight`, both, numberOf(own3(v, "weight")));
6389
+ const patch = own3(v, "input_patch");
6208
6390
  const patchRec = isRecord(patch) ? patch : null;
6209
6391
  const hasPatch = patchRec !== null && Object.keys(patchRec).length > 0;
6210
6392
  const hasRef = has(v, "input_ref");
@@ -6221,7 +6403,7 @@ var Walker = class _Walker {
6221
6403
  `variant ${q(vlabel)} of example ${q(label)} changes neither the input nor the expectation`
6222
6404
  );
6223
6405
  }
6224
- const refRec = own2(v, "input_ref");
6406
+ const refRec = own3(v, "input_ref");
6225
6407
  if (isRecord(refRec)) {
6226
6408
  this.validateFileRef(`${vpath}.input_ref`, this.fileRefOf(refRec, `${vpath}.input_ref`));
6227
6409
  }
@@ -6236,7 +6418,7 @@ var Walker = class _Walker {
6236
6418
  this.checkVariantPatch(vpath, label, vlabel, baseInput, patchRec);
6237
6419
  }
6238
6420
  }
6239
- const expected = own2(v, "expected");
6421
+ const expected = own3(v, "expected");
6240
6422
  if (isRecord(expected)) {
6241
6423
  this.validateExpectation(`${vpath}.expected`, both, expected, "final", "");
6242
6424
  }
@@ -6247,11 +6429,11 @@ var Walker = class _Walker {
6247
6429
  * itself supplies. A null patch value deleting a secret is fine.
6248
6430
  */
6249
6431
  checkVariantPatch(vpath, label, vlabel, base, patch) {
6250
- const schema = own2(this.flow, "input_schema");
6432
+ const schema = own3(this.flow, "input_schema");
6251
6433
  if (isRecord(schema)) {
6252
6434
  for (const f of this.schemaFields(schema)) {
6253
6435
  if (f.type !== TYPE_SECRET) continue;
6254
- const val = own2(patch, f.name);
6436
+ const val = own3(patch, f.name);
6255
6437
  if (val !== void 0 && val !== null) {
6256
6438
  this.err(
6257
6439
  "example_secret_value",
@@ -6291,18 +6473,18 @@ var Walker = class _Walker {
6291
6473
  emit(`${path}.title`, this.s(ex, "title", path));
6292
6474
  emit(`${path}.guidance`, this.s(ex, "guidance", path));
6293
6475
  emit(`${path}.notes`, this.s(ex, "notes", path));
6294
- const input = own2(ex, "input");
6476
+ const input = own3(ex, "input");
6295
6477
  if (isRecord(input)) scanLeaves(`${path}.input`, input, 0, emit);
6296
- const expected = own2(ex, "expected");
6478
+ const expected = own3(ex, "expected");
6297
6479
  if (isRecord(expected)) this.scanExpectationLeaves(`${path}.expected`, expected, emit);
6298
- const cps = own2(ex, "checkpoints");
6480
+ const cps = own3(ex, "checkpoints");
6299
6481
  if (isRecord(cps)) {
6300
6482
  for (const id of sortedKeys(cps)) {
6301
- const cp = own2(cps, id);
6483
+ const cp = own3(cps, id);
6302
6484
  if (isRecord(cp)) this.scanExpectationLeaves(`${path}.checkpoints.${id}`, cp, emit);
6303
6485
  }
6304
6486
  }
6305
- const variants = own2(ex, "variants");
6487
+ const variants = own3(ex, "variants");
6306
6488
  if (Array.isArray(variants)) {
6307
6489
  variants.forEach((v, j) => {
6308
6490
  if (!isRecord(v)) return;
@@ -6310,34 +6492,34 @@ var Walker = class _Walker {
6310
6492
  emit(`${vpath}.title`, this.s(v, "title", vpath));
6311
6493
  emit(`${vpath}.guidance`, this.s(v, "guidance", vpath));
6312
6494
  emit(`${vpath}.provenance`, this.s(v, "provenance", vpath));
6313
- scanLeaves(`${vpath}.input_patch`, own2(v, "input_patch"), 0, emit);
6314
- const vexp = own2(v, "expected");
6495
+ scanLeaves(`${vpath}.input_patch`, own3(v, "input_patch"), 0, emit);
6496
+ const vexp = own3(v, "expected");
6315
6497
  if (isRecord(vexp)) this.scanExpectationLeaves(`${vpath}.expected`, vexp, emit);
6316
6498
  });
6317
6499
  }
6318
6500
  }
6319
6501
  scanExpectationLeaves(path, e, emit) {
6320
6502
  emit(`${path}.rubric`, this.s(e, "rubric", path));
6321
- const reference = own2(e, "reference");
6503
+ const reference = own3(e, "reference");
6322
6504
  if (isRecord(reference)) {
6323
6505
  emit(`${path}.reference.text`, this.s(reference, "text", `${path}.reference`));
6324
6506
  }
6325
- this.stringList(own2(e, "must_not"), `${path}.must_not`).forEach(
6507
+ this.stringList(own3(e, "must_not"), `${path}.must_not`).forEach(
6326
6508
  (s, j) => emit(`${path}.must_not[${j}]`, s)
6327
6509
  );
6328
- this.stringList(own2(e, "must_not_contain"), `${path}.must_not_contain`).forEach(
6510
+ this.stringList(own3(e, "must_not_contain"), `${path}.must_not_contain`).forEach(
6329
6511
  (s, j) => emit(`${path}.must_not_contain[${j}]`, s)
6330
6512
  );
6331
- const fields = own2(e, "fields");
6513
+ const fields = own3(e, "fields");
6332
6514
  if (isRecord(fields)) {
6333
6515
  for (const key of sortedKeys(fields)) {
6334
- const m = own2(fields, key);
6516
+ const m = own3(fields, key);
6335
6517
  if (!isRecord(m)) continue;
6336
6518
  const fpath = `${path}.fields.${key}`;
6337
- scanLeaves(`${fpath}.equals`, own2(m, "equals"), 0, emit);
6519
+ scanLeaves(`${fpath}.equals`, own3(m, "equals"), 0, emit);
6338
6520
  emit(`${fpath}.contains`, this.s(m, "contains", fpath));
6339
6521
  emit(`${fpath}.not_contains`, this.s(m, "not_contains", fpath));
6340
- const oneOf = own2(m, "one_of");
6522
+ const oneOf = own3(m, "one_of");
6341
6523
  if (Array.isArray(oneOf)) {
6342
6524
  oneOf.forEach(
6343
6525
  (one, j) => scanLeaves(`${fpath}.one_of[${j}]`, one, 0, emit)
@@ -6345,7 +6527,7 @@ var Walker = class _Walker {
6345
6527
  }
6346
6528
  }
6347
6529
  }
6348
- scanLeaves(`${path}.exact`, own2(e, "exact"), 0, emit);
6530
+ scanLeaves(`${path}.exact`, own3(e, "exact"), 0, emit);
6349
6531
  }
6350
6532
  };
6351
6533
  function scoreInRange(v) {
@@ -6461,7 +6643,7 @@ function inputValueFailures(f, raw) {
6461
6643
  case TYPE_FILE2: {
6462
6644
  if (typeof raw === "string") return raw === "" ? [mismatch(f, TYPE_FILE2)] : [];
6463
6645
  if (isRecord(raw)) {
6464
- const ref = own2(raw, FILE_REF_KEY);
6646
+ const ref = own3(raw, FILE_REF_KEY);
6465
6647
  return typeof ref === "string" && ref !== "" ? [] : [mismatch(f, TYPE_FILE2)];
6466
6648
  }
6467
6649
  return [mismatch(f, TYPE_FILE2)];
@@ -6544,6 +6726,7 @@ function validateParsed(flow, opts, sources) {
6544
6726
  validateCredentialEndpointPairing(f, issues);
6545
6727
  validateExamples(f, issues);
6546
6728
  validateOrchestratorExons(f, issues);
6729
+ validateResidencyEnforcement(f, issues);
6547
6730
  validateUnknownKeys(f, issues);
6548
6731
  const templateStats = validateTemplates(f, issues, opts);
6549
6732
  const totalSteps = f.steps && typeof f.steps === "object" && !Array.isArray(f.steps) ? Object.keys(f.steps).length : 0;