@felspar/sdk 0.3.0 → 0.4.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.
@@ -51,26 +51,26 @@ function append(token, state, bytes = utf8Bytes(token)) {
51
51
  state.parts.push(state.buffer);
52
52
  state.buffer = "";
53
53
  }
54
- function quoted(value) {
55
- if (value.length > canonicalJsonLimits.maxBytes) {
54
+ function quoted(value2) {
55
+ if (value2.length > canonicalJsonLimits.maxBytes) {
56
56
  throw new RangeError("Canonical JSON string exceeds the byte limit");
57
57
  }
58
- if (/[\uD800-\uDFFF]/u.test(value)) {
58
+ if (/[\uD800-\uDFFF]/u.test(value2)) {
59
59
  throw new TypeError("Canonical JSON requires valid Unicode strings");
60
60
  }
61
- return JSON.stringify(value);
61
+ return JSON.stringify(value2);
62
62
  }
63
- function appendQuoted(value, state) {
64
- let entry2 = state.strings.get(value);
65
- if (!entry2) {
66
- const token = quoted(value);
67
- entry2 = { token, bytes: utf8Bytes(token) };
68
- if (state.strings.size < 256 && state.stringBytes + entry2.bytes <= 65536) {
69
- state.strings.set(value, entry2);
70
- state.stringBytes += entry2.bytes;
63
+ function appendQuoted(value2, state) {
64
+ let entry3 = state.strings.get(value2);
65
+ if (!entry3) {
66
+ const token = quoted(value2);
67
+ entry3 = { token, bytes: utf8Bytes(token) };
68
+ if (state.strings.size < 256 && state.stringBytes + entry3.bytes <= 65536) {
69
+ state.strings.set(value2, entry3);
70
+ state.stringBytes += entry3.bytes;
71
71
  }
72
72
  }
73
- append(entry2.token, state, entry2.bytes);
73
+ append(entry3.token, state, entry3.bytes);
74
74
  }
75
75
  function dataValue(input, key3) {
76
76
  const descriptor = Object.getOwnPropertyDescriptor(input, key3);
@@ -131,13 +131,13 @@ function writeObject(input, state, depth) {
131
131
  }
132
132
  append("}", state);
133
133
  }
134
- function writeSealed(entry2, state, depth) {
135
- state.nodes += entry2.nodes - 1;
136
- if (depth + entry2.height > canonicalJsonLimits.maxDepth || state.nodes > canonicalJsonLimits.maxNodes) {
134
+ function writeSealed(entry3, state, depth) {
135
+ state.nodes += entry3.nodes - 1;
136
+ if (depth + entry3.height > canonicalJsonLimits.maxDepth || state.nodes > canonicalJsonLimits.maxNodes) {
137
137
  throw new RangeError("Canonical JSON exceeds the depth or node limit");
138
138
  }
139
- state.height = Math.max(state.height, depth + entry2.height);
140
- append(entry2.json, state, entry2.bytes);
139
+ state.height = Math.max(state.height, depth + entry3.height);
140
+ append(entry3.json, state, entry3.bytes);
141
141
  }
142
142
  function writeContainer(input, state, depth) {
143
143
  const sealed = sealedEntries.get(input);
@@ -266,12 +266,12 @@ function sealValue(input, depth, state) {
266
266
  throw new RangeError("Canonical JSON exceeds the depth, node or byte limit");
267
267
  }
268
268
  Object.freeze(input);
269
- const entry2 = { json, bytes, nodes, height };
269
+ const entry3 = { json, bytes, nodes, height };
270
270
  sealedContainers.add(input);
271
271
  if (bytes >= sealedEntryMinimumBytes) {
272
- sealedEntries.set(input, entry2);
272
+ sealedEntries.set(input, entry3);
273
273
  }
274
- return entry2;
274
+ return entry3;
275
275
  }
276
276
  function sealCanonicalJson(input) {
277
277
  sealValue(input, 0, { ancestors: /* @__PURE__ */ new Set() });
@@ -292,13 +292,13 @@ var contentPartsLimits = Object.freeze({
292
292
  maxLogicalDepth: canonicalJsonLimits.maxDepth
293
293
  });
294
294
  var encoder = new TextEncoder();
295
- function utf8(text7) {
296
- if (text7.length >= 64) {
297
- return encoder.encode(text7).byteLength;
295
+ function utf8(text8) {
296
+ if (text8.length >= 64) {
297
+ return encoder.encode(text8).byteLength;
298
298
  }
299
299
  let bytes = 0;
300
- for (let index = 0; index < text7.length; index += 1) {
301
- const code = text7.codePointAt(index) ?? 0;
300
+ for (let index = 0; index < text8.length; index += 1) {
301
+ const code = text8.codePointAt(index) ?? 0;
302
302
  if (code < 128) {
303
303
  bytes += 1;
304
304
  } else if (code < 2048) {
@@ -312,12 +312,12 @@ function utf8(text7) {
312
312
  }
313
313
  return bytes;
314
314
  }
315
- async function sha256(text7) {
316
- const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(text7)));
315
+ async function sha256(text8) {
316
+ const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(text8)));
317
317
  return `sha256:${Array.from(hash, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
318
318
  }
319
- function reference(digest28) {
320
- return { [draftContentPartReferenceKey]: digest28 };
319
+ function reference(digest29) {
320
+ return { [draftContentPartReferenceKey]: digest29 };
321
321
  }
322
322
  var referenceBytes = utf8(canonicalizeJson(reference(`sha256:${"0".repeat(64)}`)));
323
323
  var logicalLimit = "Content parts exceed the logical byte, node or depth limit";
@@ -326,12 +326,12 @@ function admit(logical, depth) {
326
326
  throw new RangeError(logicalLimit);
327
327
  }
328
328
  }
329
- function scalar(value) {
330
- if (value === void 0 || typeof value === "function" || typeof value === "symbol") {
329
+ function scalar(value2) {
330
+ if (value2 === void 0 || typeof value2 === "function" || typeof value2 === "symbol") {
331
331
  throw new TypeError("Content parts require JSON values");
332
332
  }
333
- const bytes = utf8(JSON.stringify(value));
334
- return { value, tokenBytes: bytes, logical: { bytes, nodes: 1, height: 0 } };
333
+ const bytes = utf8(JSON.stringify(value2));
334
+ return { value: value2, tokenBytes: bytes, logical: { bytes, nodes: 1, height: 0 } };
335
335
  }
336
336
  function combine(keys, children) {
337
337
  let tokenBytes = 2 + Math.max(children.length - 1, 0);
@@ -350,8 +350,8 @@ function combine(keys, children) {
350
350
  }
351
351
  var hydratedValues = /* @__PURE__ */ new WeakSet();
352
352
  var knownSplits = /* @__PURE__ */ new WeakMap();
353
- function isImmutable(value) {
354
- return hydratedValues.has(value) || isCanonicalJsonSealed(value);
353
+ function isImmutable(value2) {
354
+ return hydratedValues.has(value2) || isCanonicalJsonSealed(value2);
355
355
  }
356
356
  function entriesOf(input) {
357
357
  const isArray = Array.isArray(input);
@@ -397,7 +397,7 @@ function measure(input, state, depth) {
397
397
  throw new RangeError(logicalLimit);
398
398
  }
399
399
  const entries2 = entriesOf(input);
400
- const children = entries2.map(([, value]) => measure(value, state, depth + 1));
400
+ const children = entries2.map(([, value2]) => measure(value2, state, depth + 1));
401
401
  const keys = Array.isArray(input) ? null : entries2.map(([key3]) => key3);
402
402
  const { tokenBytes: tokenBytes2, logical } = combine(keys, children);
403
403
  const isPart = tokenBytes2 >= contentPartsLimits.minPartBytes;
@@ -419,19 +419,19 @@ function storedForm(input, state) {
419
419
  if (known) {
420
420
  return known.value;
421
421
  }
422
- const digest28 = state.digests.get(input);
423
- if (digest28 !== void 0) {
424
- return reference(digest28);
422
+ const digest29 = state.digests.get(input);
423
+ if (digest29 !== void 0) {
424
+ return reference(digest29);
425
425
  }
426
426
  const node = state.measured.get(input);
427
427
  if (!node) {
428
428
  throw new Error("Content parts lost a measured container");
429
429
  }
430
- return rebuild(input, node.entries, node.entries.map(([, value]) => storedForm(value, state)));
430
+ return rebuild(input, node.entries, node.entries.map(([, value2]) => storedForm(value2, state)));
431
431
  }
432
- function remember(node, value, tokenBytes) {
432
+ function remember(node, value2, tokenBytes) {
433
433
  if (isImmutable(node.input)) {
434
- knownSplits.set(node.input, { value, tokenBytes, logical: node.logical });
434
+ knownSplits.set(node.input, { value: value2, tokenBytes, logical: node.logical });
435
435
  }
436
436
  }
437
437
  function isCanonicalDocumentSized(logical) {
@@ -446,7 +446,7 @@ function freezeMeasured(state) {
446
446
  hydratedValues.add(node.input);
447
447
  }
448
448
  }
449
- async function splitRoot(value, isCollecting, isFreezing = false) {
449
+ async function splitRoot(value2, isCollecting, isFreezing = false) {
450
450
  const state = {
451
451
  isCollecting,
452
452
  measured: /* @__PURE__ */ new Map(),
@@ -454,26 +454,26 @@ async function splitRoot(value, isCollecting, isFreezing = false) {
454
454
  digests: /* @__PURE__ */ new Map(),
455
455
  parts: /* @__PURE__ */ new Map()
456
456
  };
457
- const root = measure(value, state, 0);
457
+ const root = measure(value2, state, 0);
458
458
  if (isFreezing) {
459
459
  freezeMeasured(state);
460
460
  }
461
461
  for (const node of state.order) {
462
462
  const token = canonicalizeJson(storedForm(node.input, state));
463
- const digest29 = await sha256(token);
464
- state.digests.set(node.input, digest29);
465
- state.parts.set(digest29, token);
466
- remember(node, reference(digest29), referenceBytes);
467
- }
468
- const stored = storedForm(value, state);
469
- if (value !== null && typeof value === "object") {
470
- const node = state.measured.get(value);
463
+ const digest30 = await sha256(token);
464
+ state.digests.set(node.input, digest30);
465
+ state.parts.set(digest30, token);
466
+ remember(node, reference(digest30), referenceBytes);
467
+ }
468
+ const stored = storedForm(value2, state);
469
+ if (value2 !== null && typeof value2 === "object") {
470
+ const node = state.measured.get(value2);
471
471
  if (node && !node.isPart) {
472
472
  remember(node, stored, node.tokenBytes);
473
473
  }
474
474
  }
475
- const digest28 = await sha256(canonicalizeJson(stored));
476
- return { state, root: { ...root, value: stored }, digest: digest28 };
475
+ const digest29 = await sha256(canonicalizeJson(stored));
476
+ return { state, root: { ...root, value: stored }, digest: digest29 };
477
477
  }
478
478
  function byDigest(left, right) {
479
479
  return left < right ? -1 : 1;
@@ -483,20 +483,20 @@ function admitStored(parts, bytes) {
483
483
  throw new RangeError("Content parts exceed the stored part or byte limit");
484
484
  }
485
485
  }
486
- async function packContentParts(value) {
487
- const { state, root, digest: digest28 } = await splitRoot(value, true);
486
+ async function packContentParts(value2) {
487
+ const { state, root, digest: digest29 } = await splitRoot(value2, true);
488
488
  const parts = [];
489
489
  for (const part of state.parts.keys()) {
490
490
  parts.push(part);
491
491
  }
492
492
  parts.sort(byDigest);
493
493
  const head = canonicalizeJson({ schema: draftContentPartsFormat, root: root.value, parts });
494
- const text7 = [head, ...parts.map((part) => state.parts.get(part) ?? "")].join("\n");
495
- const storedBytes = utf8(text7);
494
+ const text8 = [head, ...parts.map((part) => state.parts.get(part) ?? "")].join("\n");
495
+ const storedBytes = utf8(text8);
496
496
  admitStored(parts.length, storedBytes);
497
497
  return {
498
- digest: digest28,
499
- text: text7,
498
+ digest: digest29,
499
+ text: text8,
500
500
  parts: parts.length,
501
501
  storedBytes,
502
502
  logicalBytes: root.logical.bytes,
@@ -524,12 +524,12 @@ import { z as z5 } from "zod";
524
524
 
525
525
  // ../schemas/src/draft-calendar-date.ts
526
526
  import { z as z2 } from "zod";
527
- var CalendarDateSchema = z2.string().regex(/^(?!0000)\d{4}-\d{2}-\d{2}$/u).refine((value) => {
528
- const instant2 = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
529
- return Number.isFinite(instant2.getTime()) && instant2.toISOString().slice(0, 10) === value;
527
+ var CalendarDateSchema = z2.string().regex(/^(?!0000)\d{4}-\d{2}-\d{2}$/u).refine((value2) => {
528
+ const instant2 = /* @__PURE__ */ new Date(`${value2}T00:00:00.000Z`);
529
+ return Number.isFinite(instant2.getTime()) && instant2.toISOString().slice(0, 10) === value2;
530
530
  }, "Expected a real Gregorian calendar date in years 0001\u20139999");
531
- function calendarDay(value) {
532
- return Date.parse(`${value}T00:00:00.000Z`) / 864e5;
531
+ function calendarDay(value2) {
532
+ return Date.parse(`${value2}T00:00:00.000Z`) / 864e5;
533
533
  }
534
534
 
535
535
  // ../schemas/src/draft-evidence-scope.ts
@@ -537,8 +537,8 @@ import { z as z3 } from "zod";
537
537
  var identifier = z3.string().min(1).max(256).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/@-]*$/u);
538
538
  var draftSourceIdLimit = 2048;
539
539
  var draftSourceIdPattern = /^[a-zA-Z0-9](?:[a-zA-Z0-9\-._~:/?#[\]@!$&'()*+,;=]|%[0-9a-fA-F]{2})*$/u;
540
- function isDraftSourceId(value) {
541
- return value.length <= draftSourceIdLimit && draftSourceIdPattern.test(value);
540
+ function isDraftSourceId(value2) {
541
+ return value2.length <= draftSourceIdLimit && draftSourceIdPattern.test(value2);
542
542
  }
543
543
  var sourceId = z3.string().min(1).max(draftSourceIdLimit).regex(draftSourceIdPattern);
544
544
  var reference2 = z3.strictObject({
@@ -630,8 +630,8 @@ var businessCalendar = z5.strictObject({
630
630
  });
631
631
  }
632
632
  if (calendar.holidays.some((day) => {
633
- const value = calendarDay(day);
634
- return value < calendarDay(calendar.validFrom) || value > calendarDay(calendar.validThrough);
633
+ const value2 = calendarDay(day);
634
+ return value2 < calendarDay(calendar.validFrom) || value2 > calendarDay(calendar.validThrough);
635
635
  })) {
636
636
  context3.addIssue({ code: "custom", message: "Holiday outside declared calendar coverage" });
637
637
  }
@@ -691,20 +691,20 @@ function unique(values, context3, path3) {
691
691
  function checkAuthority(authority, context3) {
692
692
  unique(authority.definition.allowedValues, context3, ["definition", "allowedValues"]);
693
693
  unique(authority.allowedOutcomes, context3, ["allowedOutcomes"]);
694
- unique(authority.rules.map((entry2) => entry2.id), context3, ["rules"]);
694
+ unique(authority.rules.map((entry3) => entry3.id), context3, ["rules"]);
695
695
  const values = new Set(authority.definition.allowedValues);
696
696
  const outcomes = new Set(authority.allowedOutcomes);
697
- for (const [index, entry2] of authority.rules.entries()) {
697
+ for (const [index, entry3] of authority.rules.entries()) {
698
698
  const at = ["rules", index];
699
- requireBinding(entry2.when.key === authority.definition.key, context3, {
699
+ requireBinding(entry3.when.key === authority.definition.key, context3, {
700
700
  path: [...at, "when", "key"],
701
701
  message: unknownDefinition
702
702
  });
703
- requireBinding(values.has(entry2.when.equals), context3, {
703
+ requireBinding(values.has(entry3.when.equals), context3, {
704
704
  path: [...at, "when", "equals"],
705
705
  message: "Unknown definition value"
706
706
  });
707
- requireBinding(outcomes.has(entry2.outcome), context3, {
707
+ requireBinding(outcomes.has(entry3.outcome), context3, {
708
708
  path: [...at, "outcome"],
709
709
  message: "Unknown outcome"
710
710
  });
@@ -769,15 +769,15 @@ var admission = z8.strictObject({
769
769
  trustDomain: identifier5,
770
770
  status: z8.enum(["approved", "revoked"])
771
771
  });
772
- function draftEvidenceReferenceKey(value) {
773
- return JSON.stringify([draftPassageKey(value), value.contentDigest]);
772
+ function draftEvidenceReferenceKey(value2) {
773
+ return JSON.stringify([draftPassageKey(value2), value2.contentDigest]);
774
774
  }
775
- function draftAdmissionKey(value) {
775
+ function draftAdmissionKey(value2) {
776
776
  return JSON.stringify([
777
- draftEvidenceReferenceKey(value.reference),
778
- value.purpose,
779
- value.sensitivity,
780
- value.trustDomain
777
+ draftEvidenceReferenceKey(value2.reference),
778
+ value2.purpose,
779
+ value2.sensitivity,
780
+ value2.trustDomain
781
781
  ]);
782
782
  }
783
783
  function requireCoverage({ expected: expected2, actual, path: path3 }, context3) {
@@ -909,9 +909,9 @@ import { z as z12 } from "zod";
909
909
 
910
910
  // ../schemas/src/draft-decision-date.ts
911
911
  import { z as z11 } from "zod";
912
- function isTimeZone(value) {
912
+ function isTimeZone(value2) {
913
913
  try {
914
- const format = new Intl.DateTimeFormat("en-US", { timeZone: value });
914
+ const format = new Intl.DateTimeFormat("en-US", { timeZone: value2 });
915
915
  const options = format.resolvedOptions();
916
916
  return options.timeZone.length > 0;
917
917
  } catch {
@@ -992,22 +992,22 @@ function interval(clause, definition3) {
992
992
  if (!bounds) {
993
993
  return null;
994
994
  }
995
- const { minimum, maximum, operator, value } = bounds;
995
+ const { minimum, maximum, operator, value: value2 } = bounds;
996
996
  return {
997
- low: operator === "lt" || operator === "lte" ? minimum : Math.max(minimum, value),
998
- high: operator === "gt" || operator === "gte" ? maximum : Math.min(maximum, value),
999
- lowClosed: operator !== "gt" || minimum > value,
1000
- highClosed: operator !== "lt" || maximum < value
997
+ low: operator === "lt" || operator === "lte" ? minimum : Math.max(minimum, value2),
998
+ high: operator === "gt" || operator === "gte" ? maximum : Math.min(maximum, value2),
999
+ lowClosed: operator !== "gt" || minimum > value2,
1000
+ highClosed: operator !== "lt" || maximum < value2
1001
1001
  };
1002
1002
  }
1003
- function nextNumber(value) {
1004
- if (value === 0) {
1003
+ function nextNumber(value2) {
1004
+ if (value2 === 0) {
1005
1005
  return Number.MIN_VALUE;
1006
1006
  }
1007
1007
  const view = new DataView(new ArrayBuffer(8));
1008
- view.setFloat64(0, value);
1008
+ view.setFloat64(0, value2);
1009
1009
  const bits = view.getBigUint64(0);
1010
- view.setBigUint64(0, value > 0 ? bits + 1n : bits - 1n);
1010
+ view.setBigUint64(0, value2 > 0 ? bits + 1n : bits - 1n);
1011
1011
  return view.getFloat64(0);
1012
1012
  }
1013
1013
  function isNonempty(range2, isInteger) {
@@ -1046,7 +1046,7 @@ function isConditionSupported(clause, definition3, definitions) {
1046
1046
  return clause.key !== clause.compareFact.key && areCompatibleFacts(definition3, definitions?.get(clause.compareFact.key));
1047
1047
  }
1048
1048
  if ("allowedValues" in definition3) {
1049
- return "oneOf" in clause ? clause.oneOf.every((value) => definition3.allowedValues.includes(value)) : "equals" in clause && typeof clause.equals === "string" && definition3.allowedValues.includes(clause.equals);
1049
+ return "oneOf" in clause ? clause.oneOf.every((value2) => definition3.allowedValues.includes(value2)) : "equals" in clause && typeof clause.equals === "string" && definition3.allowedValues.includes(clause.equals);
1050
1050
  }
1051
1051
  if (definition3.valueRule.type === "boolean") {
1052
1052
  return "equals" in clause && typeof clause.equals === "boolean";
@@ -1066,7 +1066,7 @@ function relativeConditionsOverlap(left, right) {
1066
1066
  const { operator: b, ...rightOffset } = right.relativeDate;
1067
1067
  if (JSON.stringify(leftOffset) === JSON.stringify(rightOffset)) {
1068
1068
  const signs = { eq: [0], lt: [-1], lte: [-1, 0], gt: [1], gte: [0, 1] };
1069
- return signs[a].some((value) => signs[b].includes(value));
1069
+ return signs[a].some((value2) => signs[b].includes(value2));
1070
1070
  }
1071
1071
  }
1072
1072
  return null;
@@ -1127,12 +1127,12 @@ function areConditionsOverlapping(left, right, definition3) {
1127
1127
  }
1128
1128
  if ("compareFact" in left && "compareFact" in right && left.compareFact.key === right.compareFact.key) {
1129
1129
  const signs = { eq: [0], lt: [-1], lte: [-1, 0], gt: [1], gte: [0, 1] };
1130
- return signs[left.compareFact.operator].some((value) => signs[right.compareFact.operator].includes(value));
1130
+ return signs[left.compareFact.operator].some((value2) => signs[right.compareFact.operator].includes(value2));
1131
1131
  }
1132
1132
  const leftValues = optionsOf(left);
1133
1133
  const rightValues = optionsOf(right);
1134
1134
  if (leftValues && rightValues) {
1135
- return leftValues.some((value) => rightValues.includes(value));
1135
+ return leftValues.some((value2) => rightValues.includes(value2));
1136
1136
  }
1137
1137
  const a = interval(left, definition3);
1138
1138
  const b = interval(right, definition3);
@@ -1273,6 +1273,21 @@ function clauseIdentity(clause) {
1273
1273
  function isSameClause(left, right) {
1274
1274
  return clauseIdentity(left) === clauseIdentity(right);
1275
1275
  }
1276
+ function choiceValues(clause) {
1277
+ if ("equals" in clause) {
1278
+ return [clause.equals];
1279
+ }
1280
+ return "oneOf" in clause ? clause.oneOf : [];
1281
+ }
1282
+ function isGuardImplied(guard, clause) {
1283
+ if (isSameClause(guard, clause)) {
1284
+ return true;
1285
+ }
1286
+ const allowed = choiceValues(guard);
1287
+ const values = choiceValues(clause);
1288
+ const isSameKey = clause.key === guard.key;
1289
+ return isSameKey && values.length > 0 && values.every((value2) => allowed.includes(value2));
1290
+ }
1276
1291
  function isPolicyValid(proposal, context3) {
1277
1292
  const clauses2 = [
1278
1293
  ...proposal.rules.flatMap((rule3) => rule3.when),
@@ -1330,11 +1345,11 @@ function inspectRuleGuards(proposal, context3) {
1330
1345
  for (const [index, rule3] of proposal.rules.entries()) {
1331
1346
  for (const clause of rule3.when) {
1332
1347
  const gates = isRelational ? conditionKeys(clause).flatMap((key3) => activationGuards(key3, requirements3)) : requirements3.get(clause.key)?.requiredWhen ?? [];
1333
- if (gates.some((gate) => rule3.when.every((candidate2) => !isSameClause(gate, candidate2)))) {
1348
+ if (gates.some((gate) => rule3.when.every((candidate2) => !isGuardImplied(gate, candidate2)))) {
1334
1349
  context3.addIssue({
1335
1350
  code: "custom",
1336
1351
  path: ["rules", index],
1337
- message: "Conditional rule must include every exact activation predicate"
1352
+ message: "Conditional rule must include every activation predicate, or an answer condition on its key within its answers"
1338
1353
  });
1339
1354
  }
1340
1355
  }
@@ -1438,7 +1453,7 @@ import { z as z14 } from "zod";
1438
1453
 
1439
1454
  // ../schemas/src/draft-scoring-references.ts
1440
1455
  function hasClause(clauses2, expected2) {
1441
- return clauses2.some((clause) => JSON.stringify(clause) === JSON.stringify(expected2));
1456
+ return clauses2.some((clause) => isGuardImplied(expected2, clause));
1442
1457
  }
1443
1458
  function mayOverlap(left, right, definitions) {
1444
1459
  for (const clause of left) {
@@ -1461,7 +1476,7 @@ function clauseIssues(clause, scope2) {
1461
1476
  }
1462
1477
  for (const key3 of conditionKeys(clause)) {
1463
1478
  if (activationGuards(key3, byKey).some((guard) => !hasClause(active, guard))) {
1464
- issues.push("Scoring applicability must include every exact requirement activation guard");
1479
+ issues.push("Scoring applicability must include every requirement activation guard, or an answer condition on its key within its answers");
1465
1480
  }
1466
1481
  }
1467
1482
  return issues;
@@ -1469,8 +1484,8 @@ function clauseIssues(clause, scope2) {
1469
1484
  function inspectScoringReferences(scoring, requirements3, context3) {
1470
1485
  const definitions = new Map(requirements3.map((row2) => [row2.definition.key, row2.definition]));
1471
1486
  const byKey = new Map(requirements3.map((row2) => [row2.definition.key, row2]));
1472
- for (const [index, criterion2] of scoring.criteria.entries()) {
1473
- const active = criterion2.activeWhen ?? [];
1487
+ for (const [index, criterion3] of scoring.criteria.entries()) {
1488
+ const active = criterion3.activeWhen ?? [];
1474
1489
  const fail = (message) => {
1475
1490
  context3.addIssue({ code: "custom", path: ["criteria", index], message });
1476
1491
  };
@@ -1479,15 +1494,15 @@ function inspectScoringReferences(scoring, requirements3, context3) {
1479
1494
  fail("Scoring applicability requires unconditional requirements");
1480
1495
  }
1481
1496
  }
1482
- const all = [...active, ...criterion2.cases.flatMap((item) => item.when)];
1497
+ const all = [...active, ...criterion3.cases.flatMap((item) => item.when)];
1483
1498
  for (const clause of all) {
1484
1499
  const messages = clauseIssues(clause, { active, definitions, byKey });
1485
1500
  for (const message of messages) {
1486
1501
  fail(message);
1487
1502
  }
1488
1503
  }
1489
- for (const [caseIndex, item] of criterion2.cases.entries()) {
1490
- if (criterion2.cases.slice(caseIndex + 1).some((other) => mayOverlap(item.when, other.when, definitions))) {
1504
+ for (const [caseIndex, item] of criterion3.cases.entries()) {
1505
+ if (criterion3.cases.slice(caseIndex + 1).some((other) => mayOverlap(item.when, other.when, definitions))) {
1491
1506
  fail("Scoring contribution cases must be provably disjoint");
1492
1507
  }
1493
1508
  }
@@ -1519,7 +1534,7 @@ function inspectScoredPolicy(proposal, context3) {
1519
1534
  }
1520
1535
  inspectScoringReferences(scoring, proposal.requirements, context3);
1521
1536
  const ids3 = new Set(rules2.map((rule3) => rule3.id));
1522
- if (gates.some((id12) => !ids3.has(id12))) {
1537
+ if (gates.some((id14) => !ids3.has(id14))) {
1523
1538
  fail("Unknown mandatory gate rule");
1524
1539
  }
1525
1540
  if (rules2.every((rule3) => gates.includes(rule3.id))) {
@@ -1532,7 +1547,7 @@ function inspectScoredPolicy(proposal, context3) {
1532
1547
  if (isGate ? hasRange || rule3.when.length === 0 : !hasRange) {
1533
1548
  fail("Mandatory gates require fact predicates only; other rules require score ranges");
1534
1549
  }
1535
- if (rule3.overrides.some((id12) => gates.includes(id12) !== isGate)) {
1550
+ if (rule3.overrides.some((id14) => gates.includes(id14) !== isGate)) {
1536
1551
  fail("Explicit overrides cannot cross mandatory-gate and score-band classes");
1537
1552
  }
1538
1553
  const range2 = rule3.scoreRange;
@@ -1554,6 +1569,7 @@ function areScoredRulesDisjoint(proposal, left, right) {
1554
1569
 
1555
1570
  // ../schemas/src/draft-required-decision.ts
1556
1571
  var typedResolutionPolicy = "strict-required-types/direct-overrides/v2";
1572
+ var valueAgreementOutcomeRegions = "outcome-regions";
1557
1573
  var identifier8 = DraftEvidenceScopeSchema.shape.entityId;
1558
1574
  var duplicateIdentity = "Duplicate identity";
1559
1575
  var uniqueIds = z15.array(identifier8).max(64).refine(hasUniqueValues, duplicateIdentity);
@@ -1596,7 +1612,8 @@ var shape = z15.strictObject({
1596
1612
  }),
1597
1613
  scope: z15.strictObject({
1598
1614
  entityId: identifier8,
1599
- evaluationTime: DraftObservationChecksSchema.shape.evaluationTime
1615
+ evaluationTime: DraftObservationChecksSchema.shape.evaluationTime,
1616
+ valueAgreement: z15.literal(valueAgreementOutcomeRegions).optional()
1600
1617
  }),
1601
1618
  evidence: z15.array(DraftEvidenceValidationSchema).max(64)
1602
1619
  });
@@ -1616,23 +1633,44 @@ function draftRulePriority(ranked) {
1616
1633
  function hasDraftRulePrecedence(winner, other) {
1617
1634
  return winner.overrides.includes(other.id) || draftRulePriority(winner) > draftRulePriority(other);
1618
1635
  }
1636
+ function overlappingRulePairs(proposal) {
1637
+ const { rules: rules2, requirements: requirements3 } = proposal;
1638
+ const definitions = new Map(requirements3.map((item) => [item.definition.key, item.definition]));
1639
+ const pairs = [];
1640
+ for (const [index, item] of rules2.entries()) {
1641
+ const later = rules2.slice(index + 1);
1642
+ for (const [offset, other] of later.entries()) {
1643
+ if (item.outcome !== other.outcome && !areScoredRulesDisjoint(proposal, item, other) && hasOverlap(item, other, definitions)) {
1644
+ pairs.push([index, index + offset + 1]);
1645
+ }
1646
+ }
1647
+ }
1648
+ return pairs;
1649
+ }
1650
+ function contradictoryRulePairs(proposal) {
1651
+ const { rules: rules2 } = proposal;
1652
+ return overlappingRulePairs(proposal).filter(([left, right]) => {
1653
+ const [item, other] = [rules2[left], rules2[right]];
1654
+ return item !== void 0 && other !== void 0 && !hasDraftRulePrecedence(item, other) && !hasDraftRulePrecedence(other, item);
1655
+ });
1656
+ }
1619
1657
  function hasCycle(rules2) {
1620
1658
  const graph = new Map(rules2.map((item) => [item.id, item.overrides]));
1621
1659
  const visiting = /* @__PURE__ */ new Set();
1622
1660
  const visited = /* @__PURE__ */ new Set();
1623
- const hasPathCycle = (id12) => {
1624
- if (visiting.has(id12)) {
1661
+ const hasPathCycle = (id14) => {
1662
+ if (visiting.has(id14)) {
1625
1663
  return true;
1626
1664
  }
1627
- if (visited.has(id12)) {
1665
+ if (visited.has(id14)) {
1628
1666
  return false;
1629
1667
  }
1630
- visiting.add(id12);
1631
- if ((graph.get(id12) ?? []).some(hasPathCycle)) {
1668
+ visiting.add(id14);
1669
+ if ((graph.get(id14) ?? []).some(hasPathCycle)) {
1632
1670
  return true;
1633
1671
  }
1634
- visiting.delete(id12);
1635
- visited.add(id12);
1672
+ visiting.delete(id14);
1673
+ visited.add(id14);
1636
1674
  return false;
1637
1675
  };
1638
1676
  return rules2.some((item) => hasPathCycle(item.id));
@@ -1641,7 +1679,7 @@ function inspectRules(proposal, context3) {
1641
1679
  const { rules: rules2, requirements: requirements3, allowedOutcomes } = proposal;
1642
1680
  const definitions = new Map(requirements3.map((item) => [item.definition.key, item.definition]));
1643
1681
  const ids3 = new Set(rules2.map((item) => item.id));
1644
- const byId = new Map(rules2.map((entry2) => [entry2.id, entry2]));
1682
+ const byId = new Map(rules2.map((entry3) => [entry3.id, entry3]));
1645
1683
  for (const [index, item] of rules2.entries()) {
1646
1684
  const fail = (message) => {
1647
1685
  context3.addIssue({
@@ -1661,22 +1699,22 @@ function inspectRules(proposal, context3) {
1661
1699
  fail("Undeclared condition key or value");
1662
1700
  }
1663
1701
  }
1664
- if (item.overrides.some((id12) => id12 === item.id || !ids3.has(id12))) {
1702
+ if (item.overrides.some((id14) => id14 === item.id || !ids3.has(id14))) {
1665
1703
  fail("Unknown or self override");
1666
1704
  }
1667
- if (item.overrides.some((id12) => {
1668
- const target = byId.get(id12);
1669
- return target !== void 0 && draftRulePriority(target) > draftRulePriority(item);
1705
+ if (item.overrides.some((id14) => {
1706
+ const target2 = byId.get(id14);
1707
+ return target2 !== void 0 && draftRulePriority(target2) > draftRulePriority(item);
1670
1708
  })) {
1671
1709
  fail("Override points to a higher priority tier");
1672
1710
  }
1673
- const laterRules = rules2.slice(index + 1);
1674
- for (const other of laterRules) {
1675
- const isContradictory = item.outcome !== other.outcome && !areScoredRulesDisjoint(proposal, item, other) && hasOverlap(item, other, definitions);
1676
- if (isContradictory && !hasDraftRulePrecedence(item, other) && !hasDraftRulePrecedence(other, item)) {
1677
- fail("Overlapping contradictory rules require a direct override");
1678
- }
1679
- }
1711
+ }
1712
+ for (const [index] of contradictoryRulePairs(proposal)) {
1713
+ context3.addIssue({
1714
+ code: "custom",
1715
+ path: ["rules", index],
1716
+ message: "Overlapping contradictory rules require a direct override"
1717
+ });
1680
1718
  }
1681
1719
  if (hasCycle(rules2)) {
1682
1720
  context3.addIssue({ code: "custom", path: ["rules"], message: "Override cycle" });
@@ -1802,26 +1840,26 @@ function unique2(values, context3, path3) {
1802
1840
  }
1803
1841
  function checkObservations(candidate2, context3) {
1804
1842
  const { authority, observations } = candidate2;
1805
- unique2(observations.map((entry2) => entry2.id), context3, ["observations"]);
1806
- for (const [index, entry2] of observations.entries()) {
1843
+ unique2(observations.map((entry3) => entry3.id), context3, ["observations"]);
1844
+ for (const [index, entry3] of observations.entries()) {
1807
1845
  const at = ["observations", index];
1808
- requireBinding2(entry2.key === authority.definition.key, context3, {
1846
+ requireBinding2(entry3.key === authority.definition.key, context3, {
1809
1847
  path: [...at, "key"],
1810
1848
  message: unknownDefinition2
1811
1849
  });
1812
- requireBinding2(authority.definition.allowedValues.includes(entry2.value), context3, {
1850
+ requireBinding2(authority.definition.allowedValues.includes(entry3.value), context3, {
1813
1851
  path: [...at, "value"],
1814
1852
  message: "Unknown definition value"
1815
1853
  });
1816
- requireBinding2(entry2.definitionDigest === authority.definition.contentDigest, context3, {
1854
+ requireBinding2(entry3.definitionDigest === authority.definition.contentDigest, context3, {
1817
1855
  path: [...at, "definitionDigest"],
1818
1856
  message: "Definition fingerprint mismatch"
1819
1857
  });
1820
- requireBinding2(entry2.evidence.entityId === candidate2.entityId, context3, {
1858
+ requireBinding2(entry3.evidence.entityId === candidate2.entityId, context3, {
1821
1859
  path: [...at, "evidence", "entityId"],
1822
1860
  message: "Evidence belongs to a different entity"
1823
1861
  });
1824
- requireBinding2(Date.parse(entry2.observedAt) <= Date.parse(candidate2.evaluatedAt), context3, {
1862
+ requireBinding2(Date.parse(entry3.observedAt) <= Date.parse(candidate2.evaluatedAt), context3, {
1825
1863
  path: [...at, "observedAt"],
1826
1864
  message: "Observation is later than evaluation"
1827
1865
  });
@@ -1837,9 +1875,9 @@ function checkExpected(candidate2, context3) {
1837
1875
  return;
1838
1876
  }
1839
1877
  unique2(result.observationIds, context3, ["expected", "observationIds"]);
1840
- const observationIds = new Set(candidate2.observations.map((entry2) => entry2.id));
1841
- for (const [index, id12] of result.observationIds.entries()) {
1842
- requireBinding2(observationIds.has(id12), context3, {
1878
+ const observationIds = new Set(candidate2.observations.map((entry3) => entry3.id));
1879
+ for (const [index, id14] of result.observationIds.entries()) {
1880
+ requireBinding2(observationIds.has(id14), context3, {
1843
1881
  path: ["expected", "observationIds", index],
1844
1882
  message: "Unknown observation"
1845
1883
  });
@@ -1851,7 +1889,7 @@ function checkExpected(candidate2, context3) {
1851
1889
  path: ["expected", "outcome"],
1852
1890
  message: "Unknown outcome"
1853
1891
  });
1854
- requireBinding2(candidate2.authority.rules.some((entry2) => entry2.id === result.ruleId), context3, { path: ["expected", "ruleId"], message: "Unknown rule" });
1892
+ requireBinding2(candidate2.authority.rules.some((entry3) => entry3.id === result.ruleId), context3, { path: ["expected", "ruleId"], message: "Unknown rule" });
1855
1893
  }
1856
1894
  var DraftDecisionCaseSchema = shape2.superRefine((candidate2, context3) => {
1857
1895
  checkObservations(candidate2, context3);
@@ -1979,10 +2017,10 @@ var expectation = z19.strictObject({
1979
2017
  status: z19.enum(["ready", "blocked", "review_required", "stale", "conflict", "gap"]),
1980
2018
  outcome: identifier11.nullable(),
1981
2019
  selectedRuleIds: z19.array(identifier11).max(256).refine(hasUniqueValues, "Duplicate rule identity")
1982
- }).superRefine((value, context3) => {
1983
- const hasOutcome = value.outcome !== null;
1984
- const hasRules = value.selectedRuleIds.length > 0;
1985
- const isReady = value.status === "ready";
2020
+ }).superRefine((value2, context3) => {
2021
+ const hasOutcome = value2.outcome !== null;
2022
+ const hasRules = value2.selectedRuleIds.length > 0;
2023
+ const isReady = value2.status === "ready";
1986
2024
  if (isReady ? !hasOutcome || !hasRules : hasOutcome || hasRules) {
1987
2025
  context3.addIssue({
1988
2026
  code: "custom",
@@ -1999,9 +2037,22 @@ var DraftEvidenceFixtureSchema = z19.strictObject({
1999
2037
  ...fixtureIdentity,
2000
2038
  evidence: DraftRequiredDecisionSchema.shape.evidence
2001
2039
  });
2040
+ var fixtureFact = z19.strictObject({
2041
+ key: identifier11,
2042
+ value: DraftEvidenceValueSchema,
2043
+ held: z19.enum(["stale", "review"]).optional(),
2044
+ conflictsWith: DraftEvidenceValueSchema.optional()
2045
+ }).superRefine((fact, context3) => {
2046
+ if (fact.held !== void 0 && fact.conflictsWith !== void 0) {
2047
+ context3.addIssue({ code: "custom", message: "A fact is stale, flagged or conflicting" });
2048
+ }
2049
+ if (fact.conflictsWith === fact.value) {
2050
+ context3.addIssue({ code: "custom", message: "Conflicting values must differ" });
2051
+ }
2052
+ });
2002
2053
  var DraftFactFixtureSchema = z19.strictObject({
2003
2054
  ...fixtureIdentity,
2004
- facts: z19.array(z19.strictObject({ key: identifier11, value: DraftEvidenceValueSchema })).max(64).refine((facts) => hasUniqueValues(facts.map((fact) => fact.key)), "Duplicate fact key")
2055
+ facts: z19.array(fixtureFact).max(64).refine((facts) => hasUniqueValues(facts.map((fact) => fact.key)), "Duplicate fact key")
2005
2056
  });
2006
2057
  var DraftAnyCompilationFixtureSchema = z19.union([
2007
2058
  DraftEvidenceFixtureSchema,
@@ -2131,42 +2182,42 @@ var bundleNodeLimit = 65536;
2131
2182
  function boundedDraftInput(limits2) {
2132
2183
  return z21.unknown().transform((input, context3) => {
2133
2184
  let nodes = 0;
2134
- let text7 = 0;
2185
+ let text8 = 0;
2135
2186
  const budgetError = new Error("Draft input budget exceeded or non-data input");
2136
- function copy(value, depth) {
2187
+ function copy(value2, depth) {
2137
2188
  nodes += 1;
2138
2189
  if (nodes > limits2.nodes || depth > maxDepth) {
2139
2190
  throw budgetError;
2140
2191
  }
2141
- if (typeof value === "string") {
2142
- text7 += value.length;
2143
- if (value.length > limits2.stringLength || text7 > limits2.totalText) {
2192
+ if (typeof value2 === "string") {
2193
+ text8 += value2.length;
2194
+ if (value2.length > limits2.stringLength || text8 > limits2.totalText) {
2144
2195
  throw budgetError;
2145
2196
  }
2146
- return value;
2197
+ return value2;
2147
2198
  }
2148
- if (value === null || typeof value !== "object") {
2149
- return value;
2199
+ if (value2 === null || typeof value2 !== "object") {
2200
+ return value2;
2150
2201
  }
2151
- const isArray = Array.isArray(value);
2152
- const prototype = Object.getPrototypeOf(value);
2202
+ const isArray = Array.isArray(value2);
2203
+ const prototype = Object.getPrototypeOf(value2);
2153
2204
  if (prototype !== null && prototype !== (isArray ? Array.prototype : Object.prototype)) {
2154
2205
  throw budgetError;
2155
2206
  }
2156
- if (isArray && value.length > limits2.arrayLength) {
2207
+ if (isArray && value2.length > limits2.arrayLength) {
2157
2208
  throw budgetError;
2158
2209
  }
2159
- const output = isArray ? Array.from({ length: value.length }) : {};
2210
+ const output = isArray ? Array.from({ length: value2.length }) : {};
2160
2211
  let properties = 0;
2161
- for (const key3 in value) {
2162
- if (!Object.hasOwn(value, key3)) {
2212
+ for (const key3 in value2) {
2213
+ if (!Object.hasOwn(value2, key3)) {
2163
2214
  continue;
2164
2215
  }
2165
2216
  properties += 1;
2166
2217
  if (properties > (isArray ? limits2.arrayLength : 32)) {
2167
2218
  throw budgetError;
2168
2219
  }
2169
- const descriptor = Object.getOwnPropertyDescriptor(value, key3);
2220
+ const descriptor = Object.getOwnPropertyDescriptor(value2, key3);
2170
2221
  if (!descriptor || !("value" in descriptor)) {
2171
2222
  throw budgetError;
2172
2223
  }
@@ -2191,8 +2242,8 @@ function boundedDraftInput(limits2) {
2191
2242
  }
2192
2243
  });
2193
2244
  }
2194
- var isUnicodeText = (value) => !/[\uD800-\uDFFF]/u.test(value);
2195
- var isSplitCharacter = (text7, offset) => offset > 0 && offset < text7.length && /[\uDC00-\uDFFF]/u.test(text7.charAt(offset));
2245
+ var isUnicodeText = (value2) => !/[\uD800-\uDFFF]/u.test(value2);
2246
+ var isSplitCharacter = (text8, offset) => offset > 0 && offset < text8.length && /[\uDC00-\uDFFF]/u.test(text8.charAt(offset));
2196
2247
  var sourceText = DraftSourceReferenceSchema.omit({ contentDigest: true }).extend({
2197
2248
  text: z21.string().min(1).max(1048576).refine(isUnicodeText, "Lone Unicode surrogate"),
2198
2249
  offsetUnit: z21.literal("utf16_code_units"),
@@ -2556,22 +2607,22 @@ var DraftPrimitiveMappingSchema = z26.strictObject({
2556
2607
  caseId: id,
2557
2608
  rows: z26.array(row).min(requiredAuthorityPrimitives.length).max(authorityPrimitives.length)
2558
2609
  }).superRefine((mapping, context3) => {
2559
- if (!coversAuthorityPrimitives(mapping.rows.map((entry2) => entry2.primitive))) {
2610
+ if (!coversAuthorityPrimitives(mapping.rows.map((entry3) => entry3.primitive))) {
2560
2611
  context3.addIssue({ code: "custom", path: ["rows"], message: "Every category is explicit" });
2561
2612
  }
2562
2613
  const seen = /* @__PURE__ */ new Set();
2563
- for (const [index, entry2] of mapping.rows.entries()) {
2614
+ for (const [index, entry3] of mapping.rows.entries()) {
2564
2615
  const path3 = ["rows", index];
2565
- if (seen.has(entry2.primitive)) {
2616
+ if (seen.has(entry3.primitive)) {
2566
2617
  context3.addIssue({ code: "custom", path: path3, message: "Duplicate primitive" });
2567
2618
  }
2568
- seen.add(entry2.primitive);
2569
- if (entry2.status !== "mapped") {
2619
+ seen.add(entry3.primitive);
2620
+ if (entry3.status !== "mapped") {
2570
2621
  continue;
2571
2622
  }
2572
2623
  const references = /* @__PURE__ */ new Set();
2573
- for (const [at, ref] of entry2.references.entries()) {
2574
- if (!kinds[entry2.primitive].includes(ref.kind)) {
2624
+ for (const [at, ref] of entry3.references.entries()) {
2625
+ if (!kinds[entry3.primitive].includes(ref.kind)) {
2575
2626
  context3.addIssue({
2576
2627
  code: "custom",
2577
2628
  path: [...path3, "references", at],
@@ -2591,7 +2642,7 @@ var DraftPrimitiveMappingSchema = z26.strictObject({
2591
2642
  }
2592
2643
  });
2593
2644
  function readObservation(input, ref) {
2594
- const index = input.observations.findIndex((entry2) => entry2.id === ref.observationId);
2645
+ const index = input.observations.findIndex((entry3) => entry3.id === ref.observationId);
2595
2646
  const observation2 = input.observations[index];
2596
2647
  if (!observation2) {
2597
2648
  return void 0;
@@ -2627,7 +2678,7 @@ function readReference(input, ref) {
2627
2678
  return { path: "expected", value: input.expected };
2628
2679
  }
2629
2680
  case "rule": {
2630
- const index = authority.rules.findIndex((entry2) => entry2.id === ref.ruleId);
2681
+ const index = authority.rules.findIndex((entry3) => entry3.id === ref.ruleId);
2631
2682
  const rule3 = authority.rules[index];
2632
2683
  return rule3 ? {
2633
2684
  path: `authority.rules.${index}`,
@@ -2656,18 +2707,18 @@ var DraftMappedCaseSchema = z26.strictObject({
2656
2707
  message: "Mapping belongs to a different case"
2657
2708
  });
2658
2709
  }
2659
- for (const [index, entry2] of mapping.rows.entries()) {
2660
- if (entry2.status !== "mapped") {
2710
+ for (const [index, entry3] of mapping.rows.entries()) {
2711
+ if (entry3.status !== "mapped") {
2661
2712
  continue;
2662
2713
  }
2663
- if (entry2.primitive === "gaps" && input.expected.state === "ready") {
2714
+ if (entry3.primitive === "gaps" && input.expected.state === "ready") {
2664
2715
  context3.addIssue({
2665
2716
  code: "custom",
2666
2717
  path: ["mapping", "rows", index],
2667
2718
  message: "Ready expectation cannot demonstrate an unresolved gap or conflict"
2668
2719
  });
2669
2720
  }
2670
- for (const [at, ref] of entry2.references.entries()) {
2721
+ for (const [at, ref] of entry3.references.entries()) {
2671
2722
  if (!readReference(input, ref)) {
2672
2723
  context3.addIssue({
2673
2724
  code: "custom",
@@ -2834,6 +2885,8 @@ var PackDraftBoundSchema = z29.union([
2834
2885
  z29.number(),
2835
2886
  CalendarDateSchema,
2836
2887
  z29.strictObject({ question: draftIdentifier, days: dayOffset }),
2888
+ z29.strictObject({ question: draftIdentifier, businessDays: dayOffset }),
2889
+ z29.strictObject({ question: draftIdentifier }),
2837
2890
  z29.strictObject({ decisionDate: dayOffset })
2838
2891
  ]);
2839
2892
  var PackDraftComparisonSchema = z29.strictObject({
@@ -2843,10 +2896,10 @@ var PackDraftComparisonSchema = z29.strictObject({
2843
2896
  gte: PackDraftBoundSchema.optional(),
2844
2897
  eq: PackDraftBoundSchema.optional(),
2845
2898
  quote: draftQuote
2846
- }).superRefine((value, context3) => {
2847
- const lower = Number(value.gt !== void 0) + Number(value.gte !== void 0);
2848
- const upper = Number(value.lt !== void 0) + Number(value.lte !== void 0);
2849
- const hasEquality = value.eq !== void 0;
2899
+ }).superRefine((value2, context3) => {
2900
+ const lower = Number(value2.gt !== void 0) + Number(value2.gte !== void 0);
2901
+ const upper = Number(value2.lt !== void 0) + Number(value2.lte !== void 0);
2902
+ const hasEquality = value2.eq !== void 0;
2850
2903
  if (lower + upper + Number(hasEquality) === 0) {
2851
2904
  context3.addIssue({ code: "custom", message: "Give a bound: lt, lte, gt, gte or eq" });
2852
2905
  } else if (lower > 1 || upper > 1) {
@@ -2861,6 +2914,9 @@ var PackDraftConditionSchema = z29.union([
2861
2914
  PackDraftComparisonSchema
2862
2915
  ]);
2863
2916
  var PackDraftConditionsSchema = z29.record(draftIdentifier, PackDraftConditionSchema);
2917
+ function isComparison(condition) {
2918
+ return typeof condition === "object" && !Array.isArray(condition);
2919
+ }
2864
2920
  var questionTypes = ["number", "date"];
2865
2921
  var typedQuestionFields = {
2866
2922
  type: z29.enum(questionTypes).optional(),
@@ -2870,6 +2926,66 @@ var typedQuestionFields = {
2870
2926
  minimum: z29.number().optional(),
2871
2927
  maximum: z29.number().optional()
2872
2928
  };
2929
+ function unitKindOf(unit) {
2930
+ if (unit === "percent") {
2931
+ return "percent";
2932
+ }
2933
+ return isKnownCurrency(unit) ? "currency" : "count";
2934
+ }
2935
+ function fieldIssue(question3, field) {
2936
+ return { path: [field], message: `A ${question3.type ?? "choice"} question has no ${field}` };
2937
+ }
2938
+ function fieldIssues(question3, allowed) {
2939
+ const fields = ["answers", "unit", "unitWords", "integer", "minimum", "maximum"];
2940
+ const present = fields.filter((field) => question3[field] !== void 0);
2941
+ return present.filter((field) => !allowed.includes(field)).map((field) => fieldIssue(question3, field));
2942
+ }
2943
+ function numberIssues(question3) {
2944
+ const issues = [];
2945
+ const { unit } = question3;
2946
+ if (unit === void 0) {
2947
+ return [
2948
+ {
2949
+ path: ["unit"],
2950
+ message: 'Give the unit: a currency code such as "USD", "percent", or a count noun'
2951
+ }
2952
+ ];
2953
+ }
2954
+ const kind = unitKindOf(unit);
2955
+ if (kind === "count" && !/^[a-z][a-z0-9_-]*$/u.test(unit)) {
2956
+ issues.push({
2957
+ path: ["unit"],
2958
+ message: 'Use a currency code such as "USD", "percent", or a lowercase count noun'
2959
+ });
2960
+ }
2961
+ if (kind === "count" && question3.unitWords === void 0) {
2962
+ issues.push({
2963
+ path: ["unitWords"],
2964
+ message: 'A count needs the words that name its unit next to its number, such as "claims"'
2965
+ });
2966
+ }
2967
+ if (kind !== "count" && question3.unitWords !== void 0) {
2968
+ issues.push({ path: ["unitWords"], message: "Only a count has unit words" });
2969
+ }
2970
+ const { minimum, maximum } = question3;
2971
+ if (minimum !== void 0 && maximum !== void 0 && minimum > maximum) {
2972
+ issues.push({ path: ["maximum"], message: "maximum is below minimum" });
2973
+ }
2974
+ return issues;
2975
+ }
2976
+ function questionIssues(question3) {
2977
+ if (question3.type === "number") {
2978
+ return [
2979
+ ...fieldIssues(question3, ["unit", "unitWords", "integer", "minimum", "maximum"]),
2980
+ ...numberIssues(question3)
2981
+ ];
2982
+ }
2983
+ if (question3.type === "date") {
2984
+ return fieldIssues(question3, []);
2985
+ }
2986
+ const missing = question3.answers === void 0 ? [{ path: ["answers"], message: "A choice question needs answers" }] : [];
2987
+ return [...fieldIssues(question3, ["answers"]), ...missing];
2988
+ }
2873
2989
  var declaredDateOrders = [
2874
2990
  "month-first",
2875
2991
  "day-first"
@@ -2879,7 +2995,51 @@ var packConventionFields = {
2879
2995
  dateOrder: z29.enum(declaredDateOrders).optional(),
2880
2996
  timeZone: z29.string().min(1).max(64).regex(/^[A-Za-z][A-Za-z0-9_+/-]*$/u, "Use an IANA time zone name, such as Europe/Paris").refine(isTimeZone, "Unknown IANA time zone").optional()
2881
2997
  };
2882
- var caseFactSchema = z29.union([draftValue, z29.number()]);
2998
+ var plainFact = z29.union([draftValue, z29.number()]);
2999
+ var heldFactSchema = z29.union([
3000
+ z29.strictObject({ missing: z29.literal(true) }),
3001
+ z29.strictObject({ stale: plainFact }),
3002
+ z29.strictObject({ review: plainFact }),
3003
+ z29.strictObject({ conflict: z29.tuple([plainFact, plainFact]) }).refine((fact) => fact.conflict[0] !== fact.conflict[1], "Conflicting readings must differ")
3004
+ ]);
3005
+ var caseFactSchema = z29.union([plainFact, heldFactSchema]);
3006
+ var heldStates = ["missing", "stale", "conflict", "review"];
3007
+ var weekdayNames = [
3008
+ "sunday",
3009
+ "monday",
3010
+ "tuesday",
3011
+ "wednesday",
3012
+ "thursday",
3013
+ "friday",
3014
+ "saturday"
3015
+ ];
3016
+ var calendarYear = z29.number().int().min(1900).max(2200);
3017
+ var PackDraftBusinessDaysSchema = z29.strictObject({
3018
+ workingDays: z29.array(z29.enum(weekdayNames)).min(1).max(7).refine(hasUniqueValues, "Duplicate working day"),
3019
+ quote: draftQuote,
3020
+ years: z29.strictObject({ from: calendarYear, through: calendarYear }),
3021
+ holidays: z29.array(z29.strictObject({ date: CalendarDateSchema, quote: draftQuote })).max(400).refine((rows) => hasUniqueValues(rows.map((row2) => row2.date)), "Duplicate holiday").optional()
3022
+ }).superRefine((calendar, context3) => {
3023
+ const { from, through } = calendar.years;
3024
+ if (through < from || through - from > 99) {
3025
+ context3.addIssue({
3026
+ code: "custom",
3027
+ path: ["years"],
3028
+ message: "years.through must be on or after years.from, within 100 years"
3029
+ });
3030
+ }
3031
+ const holidays = calendar.holidays ?? [];
3032
+ for (const [index, holiday] of holidays.entries()) {
3033
+ const year = Number(holiday.date.slice(0, 4));
3034
+ if (year < from || year > through) {
3035
+ context3.addIssue({
3036
+ code: "custom",
3037
+ path: ["holidays", index, "date"],
3038
+ message: "This holiday is outside the calendar's years"
3039
+ });
3040
+ }
3041
+ }
3042
+ });
2883
3043
  var caseDecisionDate = CalendarDateSchema.optional();
2884
3044
 
2885
3045
  // ../schemas/src/draft-pack-subjects.ts
@@ -3002,7 +3162,7 @@ var group = z31.strictObject({
3002
3162
  min: z31.number().int().min(0).max(64),
3003
3163
  max: z31.number().int().min(0).max(64),
3004
3164
  candidates: z31.array(candidate).max(64)
3005
- }).refine((value) => value.min <= value.max, "Group minimum exceeds maximum");
3165
+ }).refine((value2) => value2.min <= value2.max, "Group minimum exceeds maximum");
3006
3166
  function areSubjectsValid(subjects, isIsolated) {
3007
3167
  const types = new Set(subjects.types.map((row2) => row2.id));
3008
3168
  const job = subjects.types.find((row2) => row2.id === subjects.job);
@@ -3023,13 +3183,13 @@ function areSubjectsValid(subjects, isIsolated) {
3023
3183
  function areEscalationsValid(escalations, context3) {
3024
3184
  const { isIsolated, outcomes } = context3;
3025
3185
  const ids3 = new Set(escalations.routes.map((row2) => row2.id));
3026
- const named = [escalations.unresolved, escalations.attemptLimit].filter((id12) => id12 !== null);
3186
+ const named = [escalations.unresolved, escalations.attemptLimit].filter((id14) => id14 !== null);
3027
3187
  return [
3028
3188
  ids3.size === escalations.routes.length,
3029
3189
  escalations.routes.every((row2) => isIsolated(row2.entryId, "routing_jobs")),
3030
3190
  hasUniqueValues(escalations.outcomes.map((row2) => row2.outcome)),
3031
3191
  escalations.outcomes.every((row2) => ids3.has(row2.escalation) && outcomes.has(row2.outcome)),
3032
- named.every((id12) => ids3.has(id12))
3192
+ named.every((id14) => ids3.has(id14))
3033
3193
  ].every(Boolean);
3034
3194
  }
3035
3195
  function isGuideValid(guide, isIsolated) {
@@ -3045,10 +3205,10 @@ function subjectPlanIssues(plan) {
3045
3205
  const issues = [];
3046
3206
  const candidates = plan.groups.flatMap((item) => item.candidates);
3047
3207
  const isIsolated = (entryId, primitive) => {
3048
- const entry2 = plan.entries.find((row2) => row2.id === entryId);
3208
+ const entry3 = plan.entries.find((row2) => row2.id === entryId);
3049
3209
  return [
3050
- entry2?.primitive === primitive,
3051
- entry2?.dependencies.length === 0,
3210
+ entry3?.primitive === primitive,
3211
+ entry3?.dependencies.length === 0,
3052
3212
  !plan.requiredIds.includes(entryId),
3053
3213
  candidates.every((row2) => row2.entryId !== entryId),
3054
3214
  plan.entries.every((row2) => !row2.dependencies.includes(entryId))
@@ -3087,7 +3247,7 @@ var DraftContextSelectionPlanSchema = z31.strictObject({
3087
3247
  attempts: z31.strictObject({
3088
3248
  max: z31.number().int().min(1).max(10),
3089
3249
  withProgress: z31.number().int().min(1).max(10)
3090
- }).refine((value) => value.withProgress >= value.max, "withProgress below max").optional(),
3250
+ }).refine((value2) => value2.withProgress >= value2.max, "withProgress below max").optional(),
3091
3251
  entries: base2.entries,
3092
3252
  requiredIds: base2.requiredIds,
3093
3253
  budget: base2.budget,
@@ -3119,19 +3279,19 @@ var DraftContextSelectionPlanSchema = z31.strictObject({
3119
3279
  if (candidateIds.length > 64 || !hasUniqueIds(candidateIds) || !hasUniqueIds(plan.groups.map((item) => item.id)) || !hasUniqueIds(plan.entries.map((item) => item.id))) {
3120
3280
  context3.addIssue({ code: "custom", message: "Duplicate identities or too many candidates" });
3121
3281
  }
3122
- if (plan.requiredIds.some((id12) => candidateIds.includes(id12))) {
3282
+ if (plan.requiredIds.some((id14) => candidateIds.includes(id14))) {
3123
3283
  context3.addIssue({ code: "custom", message: "Global required root cannot be a candidate" });
3124
3284
  }
3125
3285
  const guidanceId = plan.unresolvedGuidanceEntryId;
3126
3286
  if (guidanceId === void 0) {
3127
3287
  return;
3128
3288
  }
3129
- const entry2 = plan.entries.find((row2) => row2.id === guidanceId);
3289
+ const entry3 = plan.entries.find((row2) => row2.id === guidanceId);
3130
3290
  if ([
3131
- !entry2,
3132
- entry2?.primitive !== "gaps",
3133
- entry2?.dependencies.length,
3134
- entry2?.conflictsWith.length,
3291
+ !entry3,
3292
+ entry3?.primitive !== "gaps",
3293
+ entry3?.dependencies.length,
3294
+ entry3?.conflictsWith.length,
3135
3295
  plan.requiredIds.includes(guidanceId),
3136
3296
  candidateIds.includes(guidanceId),
3137
3297
  plan.entries.some((row2) => row2.dependencies.includes(guidanceId))
@@ -3654,7 +3814,7 @@ var DraftApplicationTargetSchema = DraftApplicationScopeSchema.extend({
3654
3814
  action,
3655
3815
  resourceId: identifier18,
3656
3816
  jobId: identifier18.nullable()
3657
- }).refine((target) => target.action === "execute_job" === (target.jobId !== null), "Only job execution carries a job ID");
3817
+ }).refine((target2) => target2.action === "execute_job" === (target2.jobId !== null), "Only job execution carries a job ID");
3658
3818
  var DraftApplicationActorSchema = z43.strictObject({
3659
3819
  principalId: identifier18,
3660
3820
  organizationId: identifier18,
@@ -3710,7 +3870,7 @@ var DraftApplicationReleaseSchema = z43.strictObject({
3710
3870
  });
3711
3871
 
3712
3872
  // ../schemas/src/draft-hosted-application.ts
3713
- import { z as z50 } from "zod";
3873
+ import { z as z57 } from "zod";
3714
3874
 
3715
3875
  // ../schemas/src/draft-source-instant.ts
3716
3876
  var localPattern = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?([^.\d].*)$/u;
@@ -3750,11 +3910,11 @@ function utcOf(local, offset) {
3750
3910
  const utc = date.toISOString();
3751
3911
  return utcYear.test(utc) ? utc.slice(0, 19) : null;
3752
3912
  }
3753
- function normalizedSourceInstant(value) {
3754
- if (value.length > sourceInstantMaxLength) {
3913
+ function normalizedSourceInstant(value2) {
3914
+ if (value2.length > sourceInstantMaxLength) {
3755
3915
  return null;
3756
3916
  }
3757
- const match = localPattern.exec(value);
3917
+ const match = localPattern.exec(value2);
3758
3918
  if (match === null) {
3759
3919
  return null;
3760
3920
  }
@@ -3823,7 +3983,7 @@ var DraftOutputContractSchema = z44.strictObject({
3823
3983
  }
3824
3984
  const encoder2 = new TextEncoder();
3825
3985
  for (const section of contract.sections) {
3826
- if (section.check === "exact" && section.alternatives.some((value) => encoder2.encode(value).byteLength > section.maxBytes)) {
3986
+ if (section.check === "exact" && section.alternatives.some((value2) => encoder2.encode(value2).byteLength > section.maxBytes)) {
3827
3987
  context3.addIssue({ code: "custom", message: "Exact alternative exceeds section budget" });
3828
3988
  }
3829
3989
  }
@@ -3970,8 +4130,10 @@ var ArtifactSemanticRequestSchema = z46.strictObject({
3970
4130
  calibration: recipe.calibration,
3971
4131
  requestDigest: digest20
3972
4132
  });
4133
+ var artifactInjectionScreen = z46.literal("paragraph-injection/v1");
3973
4134
  var ArtifactSemanticResponseSchema = z46.strictObject({
3974
4135
  schema: z46.literal("felspar.artifact-question-response.draft/v1"),
4136
+ screen: artifactInjectionScreen.optional(),
3975
4137
  preparationDigest: digest20,
3976
4138
  evaluator: recipe.evaluator,
3977
4139
  calibrationDigest: digest20,
@@ -3992,6 +4154,7 @@ var ArtifactSemanticJudgmentSchema = z46.strictObject({
3992
4154
  });
3993
4155
  var ArtifactSemanticRecordSchema = z46.strictObject({
3994
4156
  state: z46.enum(["ready", "skipped", "over_budget", "not_evaluated"]),
4157
+ screen: artifactInjectionScreen.optional(),
3995
4158
  preparationDigest: digest20,
3996
4159
  evaluator: ArtifactSemanticRecipeSchema.shape.evaluator,
3997
4160
  calibrationDigest: digest20,
@@ -4014,13 +4177,13 @@ var ArtifactSemanticRecordSchema = z46.strictObject({
4014
4177
  });
4015
4178
  var caseNotStated = "not_stated";
4016
4179
  var abstain = "cannot_determine";
4017
- function isMatchOf(question2, check) {
4018
- if (check?.kind !== "case_answer" || question2.aggregation !== "match") {
4019
- return check?.kind === "semantic_question" && question2.aggregation !== "match";
4180
+ function isMatchOf(question3, check) {
4181
+ if (check?.kind !== "case_answer" || question3.aggregation !== "match") {
4182
+ return check?.kind === "semantic_question" && question3.aggregation !== "match";
4020
4183
  }
4021
- const offered = new Set(question2.options.map((option2) => option2.value));
4184
+ const offered = new Set(question3.options.map((option2) => option2.value));
4022
4185
  const expected2 = [...(check.answers ?? []).map((row2) => row2.value), caseNotStated, abstain];
4023
- return offered.size === question2.options.length && offered.size === expected2.length && expected2.every((value) => offered.has(value));
4186
+ return offered.size === question3.options.length && offered.size === expected2.length && expected2.every((value2) => offered.has(value2));
4024
4187
  }
4025
4188
  function isAsking(check) {
4026
4189
  const isAsker = check.kind === "semantic_question" || check.kind === "case_answer";
@@ -4030,22 +4193,22 @@ function inspectSemantic(manifest2, issue) {
4030
4193
  const askers = manifest2.checks.filter(isAsking);
4031
4194
  const asked = askers.map((check) => check.questionId ?? "");
4032
4195
  const questions = manifest2.semantic?.questions ?? [];
4033
- for (const question2 of questions) {
4034
- const asker = askers.find((check) => check.questionId === question2.id);
4035
- if (!isMatchOf(question2, asker)) {
4196
+ for (const question3 of questions) {
4197
+ const asker = askers.find((check) => check.questionId === question3.id);
4198
+ if (!isMatchOf(question3, asker)) {
4036
4199
  issue("A semantic question's aggregation differs from the check that asks it");
4037
4200
  }
4038
4201
  }
4039
4202
  const distinctAsked = new Set(asked);
4040
- if (distinctAsked.size !== asked.length || asked.length !== questions.length || questions.some((question2) => !distinctAsked.has(question2.id))) {
4203
+ if (distinctAsked.size !== asked.length || asked.length !== questions.length || questions.some((question3) => !distinctAsked.has(question3.id))) {
4041
4204
  issue("Every released semantic question is asked by exactly one check");
4042
4205
  }
4043
- for (const question2 of questions) {
4044
- if (question2.aggregation === "match") {
4206
+ for (const question3 of questions) {
4207
+ if (question3.aggregation === "match") {
4045
4208
  continue;
4046
4209
  }
4047
- const effects = new Set(question2.options.map((option2) => option2.effect));
4048
- const needed = question2.aggregation === "prohibit" ? "violated" : "satisfied";
4210
+ const effects = new Set(question3.options.map((option2) => option2.effect));
4211
+ const needed = question3.aggregation === "prohibit" ? "violated" : "satisfied";
4049
4212
  if (!effects.has(needed)) {
4050
4213
  issue("A semantic question needs an option that can decide its aggregation");
4051
4214
  }
@@ -4065,8 +4228,8 @@ var artifactLintLimits = {
4065
4228
  maxLiteralUnits: 512,
4066
4229
  maxOccurrencesPerCheck: 16
4067
4230
  };
4068
- function isWellFormedText(value) {
4069
- return !/\p{Cs}/u.test(value);
4231
+ function isWellFormedText(value2) {
4232
+ return !/\p{Cs}/u.test(value2);
4070
4233
  }
4071
4234
  var literal = z47.string().min(1).max(artifactLintLimits.maxLiteralUnits).regex(/\S/u).refine(isWellFormedText);
4072
4235
  var passage = z47.strictObject({
@@ -4142,7 +4305,7 @@ var ArtifactCheckSchema = z47.discriminatedUnion("kind", [
4142
4305
  ]);
4143
4306
  var sectionDeclaration = z47.strictObject({
4144
4307
  id: id4,
4145
- heading: z47.string().min(1).max(256).regex(/\S/u).refine((value) => !/[\n\r]/u.test(value) && isWellFormedText(value)).nullable(),
4308
+ heading: z47.string().min(1).max(256).regex(/\S/u).refine((value2) => !/[\n\r]/u.test(value2) && isWellFormedText(value2)).nullable(),
4146
4309
  maxUnits: z47.number().int().min(1).max(artifactLintLimits.maxSectionUnits)
4147
4310
  });
4148
4311
  function caseAnswerIssues(checks) {
@@ -4276,16 +4439,16 @@ function unique3(values, context3, path3) {
4276
4439
  context3.addIssue({ code: "custom", path: path3, message: "Duplicate obligation identity or target" });
4277
4440
  }
4278
4441
  }
4279
- function isApprovalTargetValid(item, target, useRef) {
4442
+ function isApprovalTargetValid(item, target2, useRef) {
4280
4443
  switch (item.phase) {
4281
4444
  case "before_decision": {
4282
- return target.kind === "decision";
4445
+ return target2.kind === "decision";
4283
4446
  }
4284
4447
  case "before_generation": {
4285
- return target.kind === "artifact";
4448
+ return target2.kind === "artifact";
4286
4449
  }
4287
4450
  case "before_use": {
4288
- return target.kind === "artifact" || target.kind === "use" && useRef !== null;
4451
+ return target2.kind === "artifact" || target2.kind === "use" && useRef !== null;
4289
4452
  }
4290
4453
  default: {
4291
4454
  return false;
@@ -4293,11 +4456,11 @@ function isApprovalTargetValid(item, target, useRef) {
4293
4456
  }
4294
4457
  }
4295
4458
  function inspectApproval(item, binding, context3) {
4296
- unique3(item.appliesTo.map((target) => JSON.stringify(target)), context3, ["approvals", item.id]);
4297
- const artifacts = new Set(binding.selected.artifacts.map((entry2) => entry2.id));
4298
- for (const target of item.appliesTo) {
4299
- const isKnown = target.kind !== "artifact" || artifacts.has(target.id);
4300
- const isValid = isApprovalTargetValid(item, target, binding.scope.useRef);
4459
+ unique3(item.appliesTo.map((target2) => JSON.stringify(target2)), context3, ["approvals", item.id]);
4460
+ const artifacts = new Set(binding.selected.artifacts.map((entry3) => entry3.id));
4461
+ for (const target2 of item.appliesTo) {
4462
+ const isKnown = target2.kind !== "artifact" || artifacts.has(target2.id);
4463
+ const isValid = isApprovalTargetValid(item, target2, binding.scope.useRef);
4301
4464
  if (!isKnown || !isValid) {
4302
4465
  context3.addIssue({
4303
4466
  code: "custom",
@@ -4307,18 +4470,18 @@ function inspectApproval(item, binding, context3) {
4307
4470
  }
4308
4471
  }
4309
4472
  }
4310
- function inspectManifest(value, context3) {
4473
+ function inspectManifest(value2, context3) {
4311
4474
  if (context3.issues.length > 0) {
4312
4475
  return;
4313
4476
  }
4314
- unique3(value.contracts.map((entry2) => entry2.id), context3, ["contracts"]);
4315
- unique3(value.outcomes.map((entry2) => entry2.outcomeId), context3, ["outcomes"]);
4316
- const contracts = new Map(value.contracts.map((entry2) => [entry2.id, entry2.contentDigest]));
4317
- for (const selected of value.outcomes) {
4318
- unique3(selected.artifacts.map((entry2) => entry2.id), context3, ["outcomes", selected.outcomeId, "artifacts"]);
4319
- unique3(selected.approvals.map((entry2) => entry2.id), context3, ["outcomes", selected.outcomeId, "approvals"]);
4320
- for (const entry2 of selected.artifacts) {
4321
- if (contracts.get(entry2.contract.id) !== entry2.contract.digest) {
4477
+ unique3(value2.contracts.map((entry3) => entry3.id), context3, ["contracts"]);
4478
+ unique3(value2.outcomes.map((entry3) => entry3.outcomeId), context3, ["outcomes"]);
4479
+ const contracts = new Map(value2.contracts.map((entry3) => [entry3.id, entry3.contentDigest]));
4480
+ for (const selected of value2.outcomes) {
4481
+ unique3(selected.artifacts.map((entry3) => entry3.id), context3, ["outcomes", selected.outcomeId, "artifacts"]);
4482
+ unique3(selected.approvals.map((entry3) => entry3.id), context3, ["outcomes", selected.outcomeId, "approvals"]);
4483
+ for (const entry3 of selected.artifacts) {
4484
+ if (contracts.get(entry3.contract.id) !== entry3.contract.digest) {
4322
4485
  context3.addIssue({
4323
4486
  code: "custom",
4324
4487
  message: "Dangling or mismatched specification reference"
@@ -4326,11 +4489,11 @@ function inspectManifest(value, context3) {
4326
4489
  }
4327
4490
  }
4328
4491
  for (const item of selected.approvals) {
4329
- inspectApproval(item, { selected, scope: value.scope }, context3);
4492
+ inspectApproval(item, { selected, scope: value2.scope }, context3);
4330
4493
  }
4331
4494
  }
4332
4495
  const encoder2 = new TextEncoder();
4333
- if (encoder2.encode(JSON.stringify(value)).length > jobObligationsLimits.maxManifestBytes) {
4496
+ if (encoder2.encode(JSON.stringify(value2)).length > jobObligationsLimits.maxManifestBytes) {
4334
4497
  context3.addIssue({ code: "custom", message: "Obligations manifest byte limit exceeded" });
4335
4498
  }
4336
4499
  }
@@ -4343,15 +4506,15 @@ var HostedOutputChecksSchema = z49.strictObject({
4343
4506
  schema: z49.literal("felspar.output-checks.draft/v0"),
4344
4507
  obligations: DraftJobObligationsSchema,
4345
4508
  manifests: z49.array(ArtifactCheckManifestSchema).min(1).max(hostedOutputCheckLimits.maxOutputs)
4346
- }).superRefine((value, context3) => {
4509
+ }).superRefine((value2, context3) => {
4347
4510
  if (context3.issues.length > 0) {
4348
4511
  return;
4349
4512
  }
4350
4513
  const issue = (message) => {
4351
4514
  context3.addIssue({ code: "custom", message });
4352
4515
  };
4353
- const { obligations, manifests } = value;
4354
- const contracts = new Map(obligations.contracts.map((entry2) => [entry2.id, entry2]));
4516
+ const { obligations, manifests } = value2;
4517
+ const contracts = new Map(obligations.contracts.map((entry3) => [entry3.id, entry3]));
4355
4518
  const checked = new Set(manifests.map((manifest2) => manifest2.contract.id));
4356
4519
  if (checked.size !== manifests.length) {
4357
4520
  issue("One manifest per output contract");
@@ -4362,66 +4525,753 @@ var HostedOutputChecksSchema = z49.strictObject({
4362
4525
  issue("A manifest differs from its job or contract");
4363
4526
  }
4364
4527
  }
4365
- const required = obligations.outcomes.flatMap((entry2) => entry2.artifacts.map((artifact2) => artifact2.contract.id));
4528
+ const required = obligations.outcomes.flatMap((entry3) => entry3.artifacts.map((artifact2) => artifact2.contract.id));
4366
4529
  if (required.some((contractId) => !checked.has(contractId)) || checked.size > contracts.size) {
4367
4530
  issue("Every required output needs exactly one manifest");
4368
4531
  }
4369
4532
  });
4370
4533
 
4534
+ // ../schemas/src/draft-pack-revision.ts
4535
+ import { z as z55 } from "zod";
4536
+
4537
+ // ../schemas/src/draft-pack-draft-outputs.ts
4538
+ import { z as z50 } from "zod";
4539
+ var identifier21 = z50.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9_-]*$/u, "Use lowercase letters, digits, - and _");
4540
+ var quote = z50.string().min(1).max(4e3);
4541
+ var wording = z50.string().min(1).max(artifactLintLimits.maxLiteralUnits).regex(/\S/u, "Wording needs a visible character").refine(isWellFormedText, "Wording has a broken character");
4542
+ var packDraftOutputLimits = {
4543
+ maxOutputs: 8,
4544
+ maxChecks: 16,
4545
+ maxQuestions: 24,
4546
+ maxContext: 8,
4547
+ defaultCharacters: 8e3,
4548
+ maxCharacters: artifactLintLimits.maxSectionUnits
4549
+ };
4550
+ var wordingCheck = (max) => z50.strictObject({ id: identifier21, quote, wording: z50.array(wording).min(1).max(max) });
4551
+ var PackDraftOutputSchema = z50.strictObject({
4552
+ id: identifier21,
4553
+ what: quote,
4554
+ outcomes: z50.array(identifier21).min(1).max(64).refine(hasUniqueValues, "Duplicate outcome"),
4555
+ maxCharacters: z50.number().int().min(1).max(packDraftOutputLimits.maxCharacters).optional(),
4556
+ context: z50.array(z50.strictObject({ id: identifier21, quote })).min(1).max(packDraftOutputLimits.maxContext).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate context id").optional(),
4557
+ require: z50.array(wordingCheck(artifactLintLimits.maxAlternatives)).max(packDraftOutputLimits.maxChecks).optional(),
4558
+ prohibit: z50.array(wordingCheck(artifactLintLimits.maxLiterals)).max(packDraftOutputLimits.maxChecks).optional(),
4559
+ ask: z50.array(z50.strictObject({
4560
+ id: identifier21,
4561
+ quote,
4562
+ kind: z50.enum(["require", "prohibit"]),
4563
+ question: z50.string().min(1).max(2e3).regex(/\S/u)
4564
+ })).max(packDraftOutputLimits.maxQuestions).optional(),
4565
+ states: z50.array(z50.strictObject({
4566
+ id: identifier21,
4567
+ quote,
4568
+ question: identifier21,
4569
+ wording: z50.record(identifier21, z50.array(wording).min(1).max(8)).optional()
4570
+ })).max(packDraftOutputLimits.maxQuestions).optional()
4571
+ }).refine((output) => {
4572
+ const ids3 = [
4573
+ ...output.require ?? [],
4574
+ ...output.prohibit ?? [],
4575
+ ...output.ask ?? [],
4576
+ ...output.states ?? []
4577
+ ];
4578
+ return hasUniqueValues(ids3.map((row2) => row2.id));
4579
+ }, "Duplicate check id").refine((output) => {
4580
+ return (output.ask?.length ?? 0) + (output.states?.length ?? 0) <= packDraftOutputLimits.maxQuestions;
4581
+ }, `At most ${packDraftOutputLimits.maxQuestions} asked questions and stated answers together`).refine((output) => {
4582
+ return (output.require?.length ?? 0) + (output.prohibit?.length ?? 0) + (output.ask?.length ?? 0) + (output.states?.length ?? 0) > 0;
4583
+ }, "An output needs at least one check");
4584
+ var PackDraftOutputsSchema = z50.array(PackDraftOutputSchema).min(1).max(packDraftOutputLimits.maxOutputs).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate output");
4585
+
4586
+ // ../schemas/src/draft-pack-draft-scoring.ts
4587
+ import { z as z51 } from "zod";
4588
+ var points = z51.number().min(0).max(1e6);
4589
+ var PackDraftScoreSchema = z51.strictObject({
4590
+ lt: points.optional(),
4591
+ lte: points.optional(),
4592
+ gt: points.optional(),
4593
+ gte: points.optional(),
4594
+ eq: points.optional(),
4595
+ quote: draftQuote
4596
+ }).superRefine((value2, context3) => {
4597
+ const lower = Number(value2.gt !== void 0) + Number(value2.gte !== void 0);
4598
+ const upper = Number(value2.lt !== void 0) + Number(value2.lte !== void 0);
4599
+ const hasEquality = value2.eq !== void 0;
4600
+ if (lower + upper + Number(hasEquality) === 0) {
4601
+ context3.addIssue({ code: "custom", message: "Give a bound: lt, lte, gt, gte or eq" });
4602
+ } else if (lower > 1 || upper > 1) {
4603
+ context3.addIssue({ code: "custom", message: "At most one lower and one upper bound" });
4604
+ } else if (hasEquality && lower + upper > 0) {
4605
+ context3.addIssue({ code: "custom", message: "eq stands alone" });
4606
+ }
4607
+ });
4608
+ var contribution2 = z51.strictObject({
4609
+ id: draftIdentifier,
4610
+ points,
4611
+ quote: draftQuote,
4612
+ when: PackDraftConditionsSchema
4613
+ });
4614
+ var criterion2 = z51.strictObject({
4615
+ id: draftIdentifier,
4616
+ meaning: draftQuote,
4617
+ activeWhen: PackDraftConditionsSchema.optional(),
4618
+ points: z51.array(contribution2).min(1).max(16).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate points id"),
4619
+ otherwise: z51.strictObject({ points, quote: draftQuote }).optional()
4620
+ });
4621
+ var PackDraftScoringSchema = z51.strictObject({
4622
+ scale: z51.union([z51.literal(1), z51.literal(100)]).optional(),
4623
+ criteria: z51.array(criterion2).min(1).max(16).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate criterion")
4624
+ });
4625
+ var packDraftScoreExpectation = {
4626
+ score: z51.number().min(0).optional(),
4627
+ points: z51.record(draftIdentifier, z51.number().min(0).nullable()).optional()
4628
+ };
4629
+
4630
+ // ../schemas/src/draft-pack-draft.ts
4631
+ import { z as z54 } from "zod";
4632
+
4633
+ // ../schemas/src/draft-pack-draft-coverage.ts
4634
+ import { z as z52 } from "zod";
4635
+ var coverageDispositions = ["represented", "needs_review", "unsupported"];
4636
+ var coverageTargetKinds = [
4637
+ "question",
4638
+ "rule",
4639
+ "outcome",
4640
+ "escalation",
4641
+ "subject"
4642
+ ];
4643
+ var coverageFields = [
4644
+ "purpose",
4645
+ "useWhen",
4646
+ "notFor",
4647
+ "owner",
4648
+ "evidenceKinds",
4649
+ "maxEvidenceAgeDays",
4650
+ "manualFacts",
4651
+ "businessDays",
4652
+ "whenUnresolved",
4653
+ "attempts",
4654
+ "scoring",
4655
+ "outputChecks",
4656
+ "subject"
4657
+ ];
4658
+ var target = z52.union([
4659
+ ...coverageTargetKinds.map((kind) => z52.strictObject({ [kind]: draftIdentifier })),
4660
+ z52.strictObject({ field: z52.enum(coverageFields) })
4661
+ ]);
4662
+ var entry2 = z52.strictObject({
4663
+ quote: draftQuote,
4664
+ categories: z52.array(z52.enum(authorityPrimitives)).min(1).max(authorityPrimitives.length).refine(hasUniqueValues, "Duplicate category"),
4665
+ disposition: z52.enum(coverageDispositions),
4666
+ carriedBy: z52.array(target).min(1).max(16).optional(),
4667
+ why: z52.string().min(1).max(600).optional()
4668
+ }).superRefine((row2, context3) => {
4669
+ const isRepresented = row2.disposition === "represented";
4670
+ if (isRepresented && row2.carriedBy === void 0) {
4671
+ context3.addIssue({
4672
+ code: "custom",
4673
+ path: ["carriedBy"],
4674
+ message: "Name what carries a represented passage: a question, rule, outcome, escalation or subject"
4675
+ });
4676
+ }
4677
+ if (!isRepresented && row2.why === void 0) {
4678
+ context3.addIssue({
4679
+ code: "custom",
4680
+ path: ["why"],
4681
+ message: "Say why it is open or left out, for the owner"
4682
+ });
4683
+ }
4684
+ if (!isRepresented && row2.carriedBy !== void 0) {
4685
+ context3.addIssue({
4686
+ code: "custom",
4687
+ path: ["carriedBy"],
4688
+ message: "Only a represented passage is carried by the pack"
4689
+ });
4690
+ }
4691
+ });
4692
+ var PackDraftCoverageSchema = z52.array(entry2).min(1).max(128);
4693
+
4694
+ // ../schemas/src/draft-pack-draft-readings.ts
4695
+ import { z as z53 } from "zod";
4696
+ var readingCheckLimits = {
4697
+ maxPerAnswer: 8,
4698
+ maxPerCheck: 96,
4699
+ maxKept: 200,
4700
+ maxCharacters: 2e3,
4701
+ maxLabelCharacters: 120
4702
+ };
4703
+ var PackDraftReadingTestSchema = z53.strictObject({
4704
+ id: draftIdentifier,
4705
+ question: draftIdentifier,
4706
+ text: z53.string().trim().min(1).max(readingCheckLimits.maxCharacters),
4707
+ expect: draftValue
4708
+ });
4709
+ var PackDraftReadingTestsSchema = z53.array(PackDraftReadingTestSchema).min(1).max(readingCheckLimits.maxKept).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate reading test");
4710
+ function readingTestIssue(row2, questions, path3) {
4711
+ const question3 = questions.find((item) => item.key === row2.question);
4712
+ if (question3 === void 0 || question3.type !== void 0 || question3.derive !== void 0) {
4713
+ return {
4714
+ path: [...path3, "question"],
4715
+ message: `"${row2.question}" is not a choice question Felspar reads from text`
4716
+ };
4717
+ }
4718
+ const answers2 = question3.answers ?? [];
4719
+ return answers2.every((answer) => answer.value !== row2.expect) ? {
4720
+ path: [...path3, "expect"],
4721
+ message: `"${row2.expect}" is not one of the answers of "${row2.question}"`
4722
+ } : null;
4723
+ }
4724
+ function readingTestIssues(tests, questions) {
4725
+ const issues = [];
4726
+ const perAnswer = /* @__PURE__ */ new Map();
4727
+ const rows = tests ?? [];
4728
+ for (const [index, row2] of rows.entries()) {
4729
+ const path3 = ["readingTests", index];
4730
+ const issue = readingTestIssue(row2, questions, path3);
4731
+ const at = JSON.stringify([row2.question, row2.expect]);
4732
+ const count2 = (perAnswer.get(at) ?? 0) + 1;
4733
+ perAnswer.set(at, count2);
4734
+ if (issue !== null) {
4735
+ issues.push(issue);
4736
+ } else if (count2 > readingCheckLimits.maxPerAnswer) {
4737
+ issues.push({
4738
+ path: path3,
4739
+ message: `At most ${readingCheckLimits.maxPerAnswer} reading tests per answer`
4740
+ });
4741
+ }
4742
+ }
4743
+ return issues;
4744
+ }
4745
+ var variant = z53.strictObject({
4746
+ id: draftIdentifier.optional(),
4747
+ question: draftIdentifier,
4748
+ text: z53.string().trim().min(1).max(readingCheckLimits.maxCharacters),
4749
+ expect: draftValue.optional(),
4750
+ label: z53.string().trim().min(1).max(readingCheckLimits.maxLabelCharacters).optional()
4751
+ });
4752
+ var ReadingCheckRequestSchema = z53.strictObject({
4753
+ sourceObjectId: z53.string().min(1).max(200),
4754
+ draft: z53.unknown(),
4755
+ variants: z53.array(variant).max(readingCheckLimits.maxPerCheck).optional(),
4756
+ includeTests: z53.boolean().default(true)
4757
+ });
4758
+ var readingResults = ["as_expected", "different", "held", "read", "not_read"];
4759
+ var readingReasons = [
4760
+ "below_bar",
4761
+ "cannot_tell",
4762
+ "tie",
4763
+ "looks_like_instructions",
4764
+ "evaluation_off",
4765
+ "limit_reached",
4766
+ "not_answered"
4767
+ ];
4768
+ var probability = z53.number().min(0).max(1);
4769
+ var ReadingOutcomeSchema = z53.strictObject({
4770
+ id: z53.string().min(1).max(200),
4771
+ origin: z53.enum(["test", "sent"]),
4772
+ question: z53.string().min(1).max(200),
4773
+ label: z53.string().optional(),
4774
+ expect: z53.string().nullable(),
4775
+ result: z53.enum(readingResults),
4776
+ picked: z53.string().nullable(),
4777
+ leaning: z53.string().nullable(),
4778
+ confidence: probability.nullable(),
4779
+ bar: probability,
4780
+ reason: z53.enum(readingReasons).nullable()
4781
+ });
4782
+ var count = z53.number().int().min(0);
4783
+ var counts = z53.strictObject({
4784
+ as_expected: count,
4785
+ different: count,
4786
+ held: count,
4787
+ read: count,
4788
+ not_read: count
4789
+ });
4790
+ var ReadingCheckSchema = z53.strictObject({
4791
+ schema: z53.literal("felspar.reading-check/v0"),
4792
+ authority: z53.literal("unapproved"),
4793
+ jobId: z53.string(),
4794
+ status: z53.enum(["clean", "misses", "incomplete"]),
4795
+ counts,
4796
+ questions: z53.array(z53.strictObject({ question: z53.string(), bar: probability, counts })),
4797
+ readings: z53.array(ReadingOutcomeSchema)
4798
+ });
4799
+
4800
+ // ../schemas/src/draft-pack-draft.ts
4801
+ var identifier22 = draftIdentifier;
4802
+ var quote2 = draftQuote;
4803
+ var value = draftValue;
4804
+ var conditions = PackDraftConditionsSchema;
4805
+ var ruleOrders = ["first-match", "unordered"];
4806
+ var packDraftVersions = [
4807
+ "felspar.pack-draft/v0",
4808
+ "felspar.pack-draft/v1",
4809
+ "felspar.pack-draft/v2"
4810
+ ];
4811
+ var answers = z54.array(z54.strictObject({
4812
+ value,
4813
+ meaning: quote2,
4814
+ inclusions: z54.array(quote2).max(8).optional(),
4815
+ exclusions: z54.array(quote2).max(8).optional(),
4816
+ examples: z54.array(quote2).max(8).optional(),
4817
+ edgeCases: z54.array(quote2).max(8).optional(),
4818
+ noneOfThese: z54.literal(true).optional()
4819
+ })).min(2).max(64).refine((rows) => hasUniqueValues(rows.map((row2) => row2.value)), "Duplicate answer").refine((rows) => rows.filter((row2) => row2.noneOfThese === true).length <= 1, "Only one answer may be noneOfThese");
4820
+ var derive = z54.strictObject({
4821
+ from: identifier22,
4822
+ when: z54.record(value, z54.union([value, z54.array(value).min(2).max(64)])),
4823
+ otherwise: value.optional()
4824
+ });
4825
+ var notDerived = [
4826
+ "type",
4827
+ "askOnlyWhen",
4828
+ "whereToLook",
4829
+ "about",
4830
+ "evidence",
4831
+ "minimumConfidence",
4832
+ "highConsequence"
4833
+ ];
4834
+ function computedIssue(field) {
4835
+ return {
4836
+ path: [field],
4837
+ message: `A derived question is computed, never asked: it has no ${field}`
4838
+ };
4839
+ }
4840
+ function deriveIssues(row2) {
4841
+ const rule3 = row2.derive;
4842
+ if (rule3 === void 0) {
4843
+ return [];
4844
+ }
4845
+ const present = notDerived.filter((field) => row2[field] !== void 0);
4846
+ const issues = present.map(computedIssue);
4847
+ const values = new Set((row2.answers ?? []).map((answer) => answer.value));
4848
+ const named = [
4849
+ ...Object.keys(rule3.when),
4850
+ ...rule3.otherwise === void 0 ? [] : [rule3.otherwise]
4851
+ ];
4852
+ const unknown = named.filter((item) => !values.has(item));
4853
+ for (const answer of unknown) {
4854
+ issues.push({ path: ["derive"], message: `"${answer}" is not one of this question's answers` });
4855
+ }
4856
+ if (rule3.otherwise !== void 0 && Object.hasOwn(rule3.when, rule3.otherwise)) {
4857
+ issues.push({
4858
+ path: ["derive", "otherwise"],
4859
+ message: "otherwise names an answer already in when"
4860
+ });
4861
+ }
4862
+ if ((row2.answers ?? []).some((answer) => answer.noneOfThese === true)) {
4863
+ issues.push({ path: ["answers"], message: "A derived question has no noneOfThese answer" });
4864
+ }
4865
+ return issues;
4866
+ }
4867
+ var evidenceKinds = z54.array(identifier22).min(1).max(8).refine(hasUniqueValues, "Duplicate kind");
4868
+ var evidenceAge = z54.number().int().min(1).max(3650);
4869
+ var questionEvidence = z54.strictObject({
4870
+ evidenceKinds: evidenceKinds.optional(),
4871
+ maxEvidenceAgeDays: evidenceAge.optional(),
4872
+ quote: quote2
4873
+ }).refine((row2) => row2.evidenceKinds !== void 0 || row2.maxEvidenceAgeDays !== void 0, "Give evidenceKinds, maxEvidenceAgeDays or both");
4874
+ var minimumConfidence = z54.number().min(0.5).max(0.99);
4875
+ var question2 = z54.strictObject({
4876
+ key: identifier22,
4877
+ meaning: quote2,
4878
+ answers: answers.optional(),
4879
+ ...typedQuestionFields,
4880
+ askOnlyWhen: conditions.optional(),
4881
+ whereToLook: z54.array(quote2).max(8).optional(),
4882
+ about: identifier22.optional(),
4883
+ derive: derive.optional(),
4884
+ evidence: questionEvidence.optional(),
4885
+ minimumConfidence: minimumConfidence.optional(),
4886
+ highConsequence: z54.literal(true).optional()
4887
+ }).superRefine((row2, context3) => {
4888
+ if (row2.type !== void 0 && row2.highConsequence !== void 0) {
4889
+ context3.addIssue({
4890
+ code: "custom",
4891
+ path: ["highConsequence"],
4892
+ message: "A number or date is read exactly, with no confidence bar to calibrate"
4893
+ });
4894
+ }
4895
+ if (row2.type !== void 0 && row2.minimumConfidence !== void 0) {
4896
+ context3.addIssue({
4897
+ code: "custom",
4898
+ path: ["minimumConfidence"],
4899
+ message: "A number or date is read exactly, with no confidence bar"
4900
+ });
4901
+ }
4902
+ for (const issue of questionIssues(row2)) {
4903
+ context3.addIssue({ code: "custom", ...issue });
4904
+ }
4905
+ for (const issue of deriveIssues(row2)) {
4906
+ context3.addIssue({ code: "custom", ...issue });
4907
+ }
4908
+ });
4909
+ var shape3 = z54.strictObject({
4910
+ schema: z54.enum(packDraftVersions),
4911
+ job: identifier22,
4912
+ purpose: quote2.optional(),
4913
+ useWhen: z54.array(quote2).min(1).max(8).optional(),
4914
+ notFor: z54.array(quote2).min(1).max(8).optional(),
4915
+ owner: quote2.optional(),
4916
+ evidenceKinds,
4917
+ maxEvidenceAgeDays: evidenceAge,
4918
+ manualFacts: z54.strictObject({ allowed: z54.literal(false), quote: quote2 }).optional(),
4919
+ ...packConventionFields,
4920
+ businessDays: PackDraftBusinessDaysSchema.optional(),
4921
+ questions: z54.array(question2).min(1).max(64).refine((rows) => hasUniqueValues(rows.map((row2) => row2.key)), "Duplicate question"),
4922
+ subjects: PackDraftSubjectsSchema.optional(),
4923
+ subject: identifier22.optional(),
4924
+ escalations: PackDraftEscalationsSchema.optional(),
4925
+ outcomes: z54.array(z54.strictObject({
4926
+ id: identifier22,
4927
+ nextStep: quote2,
4928
+ escalate: identifier22.optional()
4929
+ })).min(1).max(64).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate outcome"),
4930
+ whenUnresolved: z54.union([quote2, z54.strictObject({ quote: quote2, escalate: identifier22 })]),
4931
+ attempts: z54.strictObject({
4932
+ max: z54.number().int().min(1).max(10).optional(),
4933
+ escalate: identifier22.optional()
4934
+ }).optional(),
4935
+ scoring: PackDraftScoringSchema.optional(),
4936
+ ruleOrder: z54.enum(ruleOrders).optional(),
4937
+ rules: z54.array(z54.strictObject({
4938
+ id: identifier22,
4939
+ meaning: quote2,
4940
+ when: conditions.optional(),
4941
+ score: PackDraftScoreSchema.optional(),
4942
+ gate: z54.literal(true).optional(),
4943
+ outcome: identifier22,
4944
+ except: z54.array(identifier22).min(1).max(16).refine(hasUniqueValues, "Duplicate rule").optional()
4945
+ })).min(1).max(256).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate rule"),
4946
+ cases: z54.array(z54.strictObject({
4947
+ id: identifier22,
4948
+ why: z54.string().min(1).max(2e3),
4949
+ facts: z54.record(identifier22, caseFactSchema),
4950
+ decisionDate: caseDecisionDate,
4951
+ subject: z54.strictObject({ id: SubjectIdSchema }).optional(),
4952
+ expect: z54.union([
4953
+ z54.strictObject({
4954
+ outcome: identifier22,
4955
+ rule: identifier22,
4956
+ escalation: identifier22.optional(),
4957
+ ...packDraftScoreExpectation
4958
+ }),
4959
+ z54.strictObject({ held: z54.enum(heldStates), ...packDraftScoreExpectation })
4960
+ ])
4961
+ })).min(1).max(200).refine((rows) => hasUniqueValues(rows.map((row2) => row2.id)), "Duplicate case"),
4962
+ outputChecks: PackDraftOutputsSchema.optional(),
4963
+ readingTests: PackDraftReadingTestsSchema.optional(),
4964
+ coverage: PackDraftCoverageSchema.optional()
4965
+ });
4966
+ function comparisonPaths(when2, at) {
4967
+ const entries2 = Object.entries(when2 ?? {});
4968
+ return entries2.flatMap(([key3, condition]) => isComparison(condition) ? [[...at, key3]] : []);
4969
+ }
4970
+ function presentPaths(row2, fields, at) {
4971
+ return fields.filter((field) => row2[field] !== void 0).map((field) => [...at, field]);
4972
+ }
4973
+ function casePaths(row2, at) {
4974
+ const facts = Object.entries(row2.facts);
4975
+ const isTyped = (fact) => typeof fact !== "string";
4976
+ return [
4977
+ ...presentPaths(row2, ["decisionDate"], at),
4978
+ ...presentPaths(row2.expect, ["score", "points"], [...at, "expect"]),
4979
+ ..."held" in row2.expect ? [[...at, "expect", "held"]] : [],
4980
+ ...facts.flatMap(([key3, fact]) => isTyped(fact) ? [[...at, "facts", key3]] : [])
4981
+ ];
4982
+ }
4983
+ function v1Paths(draft) {
4984
+ const paths = presentPaths(draft, ["numberStyle", "dateOrder", "timeZone", "scoring", "businessDays", "ruleOrder"], []);
4985
+ for (const [index, row2] of draft.questions.entries()) {
4986
+ const at = ["questions", String(index)];
4987
+ paths.push(...presentPaths(row2, ["type", "derive", "evidence", "minimumConfidence", "highConsequence"], at), ...comparisonPaths(row2.askOnlyWhen, [...at, "askOnlyWhen"]));
4988
+ }
4989
+ for (const [index, rule3] of draft.rules.entries()) {
4990
+ const at = ["rules", String(index)];
4991
+ paths.push(...presentPaths(rule3, ["score", "gate", "except"], at), ...comparisonPaths(rule3.when, [...at, "when"]));
4992
+ }
4993
+ for (const [index, row2] of draft.cases.entries()) {
4994
+ paths.push(...casePaths(row2, ["cases", String(index)]));
4995
+ }
4996
+ return paths;
4997
+ }
4998
+ var PackDraftSchema = shape3.superRefine((draft, context3) => {
4999
+ for (const issue of readingTestIssues(draft.readingTests, draft.questions)) {
5000
+ context3.addIssue({ code: "custom", ...issue });
5001
+ }
5002
+ if (draft.schema === "felspar.pack-draft/v2" && draft.purpose === void 0) {
5003
+ context3.addIssue({
5004
+ code: "custom",
5005
+ path: ["purpose"],
5006
+ message: "Quote the job's purpose: why it exists and what it resolves"
5007
+ });
5008
+ }
5009
+ if (draft.schema !== "felspar.pack-draft/v0") {
5010
+ return;
5011
+ }
5012
+ for (const path3 of v1Paths(draft)) {
5013
+ context3.addIssue({
5014
+ code: "custom",
5015
+ path: path3,
5016
+ message: 'Number and date questions, derived questions, thresholds, conventions, scoring, business days, exceptions, rule order, per-question evidence and held cases need "schema": "felspar.pack-draft/v1"'
5017
+ });
5018
+ }
5019
+ });
5020
+
5021
+ // ../schemas/src/draft-pack-revision.ts
5022
+ var KeptPackDraftSchema = z55.looseObject({
5023
+ schema: z55.string().regex(/^felspar\.pack-draft\/v\d{1,3}$/u),
5024
+ job: z55.string().min(1).max(200)
5025
+ });
5026
+ var id6 = z55.string().min(1).max(200);
5027
+ var text7 = z55.string().min(1).max(262144);
5028
+ var texts = z55.array(z55.string()).max(8);
5029
+ var when = PackDraftConditionsSchema;
5030
+ var conventions = packConventionFields;
5031
+ var PackOutlineSchema = z55.strictObject({
5032
+ schema: z55.literal("felspar.pack-outline/v0"),
5033
+ job: id6,
5034
+ purpose: text7.nullable(),
5035
+ useWhen: texts,
5036
+ notFor: texts,
5037
+ owner: text7.nullable(),
5038
+ evidenceKinds: z55.array(id6).max(8),
5039
+ maxEvidenceAgeDays: z55.number().int().min(1).nullable(),
5040
+ numberStyle: z55.enum(numberStyles).nullable(),
5041
+ dateOrder: conventions.dateOrder.unwrap().nullable(),
5042
+ timeZone: z55.string().min(1).max(64).nullable(),
5043
+ businessDays: PackDraftBusinessDaysSchema.nullable(),
5044
+ subject: id6.nullable(),
5045
+ subjects: z55.array(z55.strictObject({
5046
+ id: id6,
5047
+ definition: text7,
5048
+ identifier: z55.string().nullable(),
5049
+ example: z55.string().nullable(),
5050
+ match: z55.string(),
5051
+ relationships: z55.array(z55.strictObject({
5052
+ name: id6,
5053
+ subject: id6,
5054
+ cardinality: z55.enum(["one", "many"]),
5055
+ required: z55.boolean(),
5056
+ definition: text7
5057
+ })).max(16),
5058
+ identity: PackDraftIdentitySchema.nullable()
5059
+ })).max(16),
5060
+ escalations: z55.array(z55.strictObject({ id: id6, quote: text7 })).max(16),
5061
+ questions: z55.array(z55.strictObject({
5062
+ key: id6,
5063
+ type: z55.enum(["enum", "boolean", "number", "date"]),
5064
+ meaning: text7,
5065
+ about: id6.nullable(),
5066
+ askOnlyWhen: z55.string().nullable(),
5067
+ when: when.nullable(),
5068
+ unit: z55.string().nullable(),
5069
+ unitWords: z55.array(z55.string()).max(16).nullable(),
5070
+ integer: z55.boolean().nullable(),
5071
+ minimum: z55.number().nullable(),
5072
+ maximum: z55.number().nullable(),
5073
+ answers: z55.array(z55.strictObject({
5074
+ value: id6,
5075
+ meaning: z55.string().nullable(),
5076
+ inclusions: texts,
5077
+ exclusions: texts,
5078
+ examples: texts,
5079
+ edgeCases: texts
5080
+ })).max(64),
5081
+ whereToLook: texts,
5082
+ evidence: z55.strictObject({
5083
+ evidenceKinds: z55.array(id6).max(8).nullable(),
5084
+ maxEvidenceAgeDays: z55.number().int().min(1).nullable(),
5085
+ quote: text7
5086
+ }).nullable(),
5087
+ minimumConfidence: z55.number().nullable()
5088
+ })).max(64),
5089
+ outcomes: z55.array(z55.strictObject({ id: id6, nextStep: text7.nullable(), escalate: id6.nullable() })).max(64),
5090
+ whenUnresolved: z55.strictObject({ quote: text7, escalate: id6.nullable() }).nullable(),
5091
+ attempts: z55.strictObject({ max: z55.number().int(), escalate: id6.nullable() }).nullable(),
5092
+ rules: z55.array(z55.strictObject({
5093
+ id: id6,
5094
+ meaning: text7,
5095
+ outcome: id6,
5096
+ when: when.nullable(),
5097
+ conditions: z55.string().nullable(),
5098
+ scoreRange: z55.record(z55.string(), z55.unknown()).nullable(),
5099
+ score: PackDraftScoreSchema.nullable(),
5100
+ gate: z55.boolean(),
5101
+ except: z55.array(id6).max(16).nullable()
5102
+ })).max(256),
5103
+ ruleOrder: z55.enum(ruleOrders).nullable(),
5104
+ scoring: PackDraftScoringSchema.nullable(),
5105
+ cases: z55.array(z55.strictObject({
5106
+ id: id6,
5107
+ why: z55.string().nullable(),
5108
+ facts: z55.record(id6, caseFactSchema),
5109
+ decisionDate: CalendarDateSchema.nullable(),
5110
+ subject: z55.strictObject({ id: id6 }).nullable(),
5111
+ expect: z55.union([
5112
+ z55.strictObject({ outcome: id6, rule: id6, score: z55.number().nullable() }),
5113
+ z55.strictObject({ held: z55.enum(heldStates), score: z55.number().nullable() })
5114
+ ])
5115
+ })).max(200),
5116
+ outputChecks: PackDraftOutputsSchema.nullable(),
5117
+ manualFacts: z55.strictObject({ allowed: z55.literal(false), quote: z55.string().min(1) }).nullable(),
5118
+ notKept: z55.array(z55.strictObject({ path: z55.string().min(1), reason: z55.string().min(1) })).max(64)
5119
+ });
5120
+
5121
+ // ../schemas/src/draft-bar-calibration.ts
5122
+ import { z as z56 } from "zod";
5123
+ var barCalibrationPolicy = {
5124
+ lowestBar: 0.8,
5125
+ highestBar: 0.99,
5126
+ targets: { ordinary: 0.9, strict: 0.97 },
5127
+ minimumCases: 10,
5128
+ minimumDecided: 5,
5129
+ maxLabels: 400
5130
+ };
5131
+ var barCalibrationId = "felspar-backtest-bar";
5132
+ var barCalibrationVersion = "v1";
5133
+ var id7 = z56.string().min(1).max(200).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:@-]*$/u);
5134
+ var digest23 = z56.string().regex(/^sha256:[a-f0-9]{64}$/u);
5135
+ var share = z56.number().min(0).max(1);
5136
+ var bar = z56.number().min(barCalibrationPolicy.lowestBar).max(barCalibrationPolicy.highestBar);
5137
+ var BacktestLabelSchema = z56.strictObject({
5138
+ executionObjectId: id7,
5139
+ question: draftValue,
5140
+ answer: draftValue.nullable()
5141
+ });
5142
+ var BacktestLabelsSchema = z56.array(BacktestLabelSchema).min(1).max(barCalibrationPolicy.maxLabels).refine((rows) => {
5143
+ const seen = new Set(rows.map((row2) => JSON.stringify([row2.executionObjectId, row2.question])));
5144
+ return seen.size === rows.length;
5145
+ }, "Label each question of a case once");
5146
+ var calibrationReadings = ["right", "wrong", "held"];
5147
+ var caseRow = z56.strictObject({
5148
+ executionObjectId: id7,
5149
+ label: draftValue.nullable(),
5150
+ leaning: draftValue.nullable(),
5151
+ confidence: share.nullable(),
5152
+ atCurrentBar: z56.enum(calibrationReadings),
5153
+ atSuggestedBar: z56.enum(calibrationReadings).nullable()
5154
+ });
5155
+ var barRow = z56.strictObject({
5156
+ bar,
5157
+ decided: z56.number().int().min(0),
5158
+ right: z56.number().int().min(0),
5159
+ precision: share.nullable(),
5160
+ coverage: share
5161
+ });
5162
+ var calibrationStatuses = [
5163
+ "suggested",
5164
+ "too_few_cases",
5165
+ "coverage_gap",
5166
+ "needs_more_evidence_or_rewrite"
5167
+ ];
5168
+ var QuestionCalibrationSchema = z56.strictObject({
5169
+ question: id7,
5170
+ status: z56.enum(calibrationStatuses),
5171
+ consequence: z56.enum(["ordinary", "strict"]),
5172
+ target: share,
5173
+ currentBar: share,
5174
+ labeled: z56.number().int().min(0),
5175
+ insufficient: z56.number().int().min(0),
5176
+ otherAnswers: z56.number().int().min(0),
5177
+ notRead: z56.number().int().min(0),
5178
+ suggestion: z56.strictObject({
5179
+ bar,
5180
+ precision: share,
5181
+ coverage: share,
5182
+ calibration: z56.strictObject({
5183
+ id: z56.literal(barCalibrationId),
5184
+ version: z56.literal(barCalibrationVersion),
5185
+ contentDigest: digest23
5186
+ })
5187
+ }).optional(),
5188
+ bars: z56.array(barRow).max(20),
5189
+ cases: z56.array(caseRow).max(50)
5190
+ });
5191
+ var BacktestCalibrationSchema = z56.strictObject({
5192
+ schema: z56.literal("felspar.bar-calibration/v1"),
5193
+ calibrationDigest: digest23,
5194
+ minimumCases: z56.number().int().min(1),
5195
+ questions: z56.array(QuestionCalibrationSchema).max(64),
5196
+ ignoredLabels: z56.number().int().min(0)
5197
+ });
5198
+ var AcceptedBarsSchema = z56.strictObject({
5199
+ savedResultId: z56.string().regex(/^backtest-[a-f0-9]{32}$/u),
5200
+ calibrationDigest: digest23,
5201
+ questions: z56.array(id7).min(1).max(64)
5202
+ });
5203
+ var ReleaseCalibrationSchema = AcceptedBarsSchema.extend({
5204
+ acceptedBy: z56.string().min(1).max(200),
5205
+ approvedMaterialDigest: digest23,
5206
+ bars: z56.array(z56.strictObject({ question: id7, bar, calibrationDigest: digest23 })).min(1).max(64)
5207
+ });
5208
+
4371
5209
  // ../schemas/src/draft-hosted-application.ts
4372
- var id6 = z50.string().min(1).max(200).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:@-]*$/u);
4373
- var digest23 = DraftApplicationReleaseSchema.shape.releaseDigest;
4374
- var HostedSourceInputSchema = z50.strictObject({
4375
- sourceId: id6,
4376
- revision: id6,
4377
- title: z50.string().min(1).max(200),
4378
- text: z50.string().min(1).max(1048576)
4379
- });
4380
- var HostedProposalInputV0Schema = z50.strictObject({
4381
- sourceObjectId: id6,
4382
- expectedSourceDigest: digest23,
5210
+ var id8 = z57.string().min(1).max(200).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:@-]*$/u);
5211
+ var digest24 = DraftApplicationReleaseSchema.shape.releaseDigest;
5212
+ var HostedSourceInputSchema = z57.strictObject({
5213
+ sourceId: id8,
5214
+ revision: id8,
5215
+ title: z57.string().min(1).max(200),
5216
+ text: z57.string().min(1).max(1048576)
5217
+ });
5218
+ var HostedProposalInputV0Schema = z57.strictObject({
5219
+ sourceObjectId: id8,
5220
+ expectedSourceDigest: digest24,
4383
5221
  material: DraftApplicationJobMaterialSchema,
4384
5222
  compilation: DraftCompilationSchema
4385
5223
  });
4386
- var HostedProposalInputV2Schema = z50.strictObject({
4387
- schema: z50.literal("felspar.hosted-proposal.draft/v2"),
4388
- sourceObjectId: id6,
4389
- expectedSourceDigest: digest23,
5224
+ var HostedManualFactsRuleSchema = z57.strictObject({
5225
+ allowed: z57.literal(false),
5226
+ text: z57.string().min(1).max(4e3),
5227
+ sourceLocator: z57.string().min(1).max(4096),
5228
+ contentDigest: digest24
5229
+ });
5230
+ var HostedProposalInputV2Schema = z57.strictObject({
5231
+ schema: z57.literal("felspar.hosted-proposal.draft/v2"),
5232
+ sourceObjectId: id8,
5233
+ expectedSourceDigest: digest24,
4390
5234
  material: DraftApplicationJobMaterialV2Schema,
4391
- outputChecks: HostedOutputChecksSchema.optional()
5235
+ outputChecks: HostedOutputChecksSchema.optional(),
5236
+ manualFacts: HostedManualFactsRuleSchema.optional(),
5237
+ draft: KeptPackDraftSchema.optional()
4392
5238
  });
4393
- var HostedProposalInputSchema = z50.union([
5239
+ var HostedProposalInputSchema = z57.union([
4394
5240
  HostedProposalInputV2Schema,
4395
5241
  HostedProposalInputV0Schema
4396
5242
  ]);
4397
- var HostedApprovalInputSchema = z50.strictObject({
4398
- expectedProposalDigest: digest23,
4399
- reviewedMeaning: z50.literal(true),
4400
- reviewedFixtures: z50.literal(true),
4401
- reviewNote: z50.string().min(1).max(2e3)
4402
- });
4403
- var HostedReleaseInputSchema = z50.strictObject({ expectedApprovalDigest: digest23 });
4404
- var HostedReleaseBundleSchema = z50.strictObject({
5243
+ var HostedApprovalInputSchema = z57.strictObject({
5244
+ expectedProposalDigest: digest24,
5245
+ reviewedMeaning: z57.literal(true),
5246
+ reviewedFixtures: z57.literal(true),
5247
+ reviewNote: z57.string().min(1).max(2e3)
5248
+ });
5249
+ var HostedReleaseInputSchema = z57.strictObject({
5250
+ expectedApprovalDigest: digest24,
5251
+ acceptBars: AcceptedBarsSchema.optional()
5252
+ });
5253
+ var HostedReleaseBundleSchema = z57.strictObject({
4405
5254
  release: DraftApplicationReleaseSchema,
4406
5255
  material: DraftAnyApplicationJobMaterialSchema,
4407
- approvalObjectId: id6,
4408
- approvalDigest: digest23,
4409
- proposalDigest: digest23,
4410
- sourceDigest: digest23,
4411
- verifiedCompilation: DraftVerifiedCompilationSchema.optional()
4412
- });
4413
- var HostedJobInputSchema = z50.strictObject({
4414
- executionId: id6,
4415
- expectedReleaseDigest: digest23,
5256
+ approvalObjectId: id8,
5257
+ approvalDigest: digest24,
5258
+ proposalDigest: digest24,
5259
+ sourceDigest: digest24,
5260
+ verifiedCompilation: DraftVerifiedCompilationSchema.optional(),
5261
+ calibration: ReleaseCalibrationSchema.optional()
5262
+ });
5263
+ var HostedJobInputSchema = z57.strictObject({
5264
+ executionId: id8,
5265
+ expectedReleaseDigest: digest24,
4416
5266
  material: DraftAnyApplicationJobMaterialSchema
4417
5267
  });
4418
- var HostedSuppliedJobInputSchema = z50.strictObject({
4419
- mode: z50.literal("supplied"),
4420
- executionId: id6,
4421
- expectedReleaseDigest: digest23,
4422
- expectedAuthorityDigest: digest23,
4423
- jobId: id6,
4424
- entityId: id6,
5268
+ var HostedSuppliedJobInputSchema = z57.strictObject({
5269
+ mode: z57.literal("supplied"),
5270
+ executionId: id8,
5271
+ expectedReleaseDigest: digest24,
5272
+ expectedAuthorityDigest: digest24,
5273
+ jobId: id8,
5274
+ entityId: id8,
4425
5275
  evidence: DraftRequiredDecisionSchema.shape.evidence,
4426
5276
  passages: DraftLayeredEvaluationSchema.shape.passages.max(256)
4427
5277
  });
@@ -4431,97 +5281,185 @@ var hostedFactsLimits = {
4431
5281
  maxFactsBytes: 524288,
4432
5282
  maxQuestions: 64
4433
5283
  };
4434
- var factSourceId = z50.string().refine(isDraftSourceId, "source_id_invalid").describe(`The source's own ID or address, such as its page URL with any query: RFC 3986 characters, starting with a letter or digit, at most ${draftSourceIdLimit} characters.`);
4435
- var observedAt = z50.string().refine((value) => normalizedSourceInstant(value) !== null, "observed_at_invalid").transform((value) => normalizedSourceInstant(value) ?? value).describe(`When the source was read: an RFC 3339 date and time with Z or an offset, such as 2026-10-21T10:00:00Z or 2026-10-21T12:00+02:00, at most ${sourceInstantMaxLength} characters. Stored in UTC.`);
4436
- var factSource = z50.strictObject({
4437
- class: id6,
5284
+ var factSourceId = z57.string().refine(isDraftSourceId, "source_id_invalid").describe(`The source's own ID or address, such as its page URL with any query: RFC 3986 characters, starting with a letter or digit, at most ${draftSourceIdLimit} characters.`);
5285
+ var observedAt = z57.string().refine((value2) => normalizedSourceInstant(value2) !== null, "observed_at_invalid").transform((value2) => normalizedSourceInstant(value2) ?? value2).describe(`When the source was read: an RFC 3339 date and time with Z or an offset, such as 2026-10-21T10:00:00Z or 2026-10-21T12:00+02:00, at most ${sourceInstantMaxLength} characters. Stored in UTC.`);
5286
+ var sourceFields = {
5287
+ class: id8,
4438
5288
  id: factSourceId,
4439
- revision: id6.optional(),
4440
- locator: z50.string().min(1).max(4096).optional(),
5289
+ revision: id8.optional(),
5290
+ locator: z57.string().min(1).max(4096).optional(),
4441
5291
  observedAt,
4442
- sensitivity: id6.optional()
4443
- });
4444
- var excerptText = z50.string().min(1).refine((text7) => text7.length <= hostedFactsLimits.maxExcerptCharacters, "text_too_long");
4445
- var about = z50.string().min(1).max(200).optional();
4446
- var HostedExcerptSchema = z50.strictObject({ text: excerptText, source: factSource, about });
4447
- var HostedValueFactSchema = z50.strictObject({
4448
- value: z50.union([z50.string().min(1).max(200), z50.number(), z50.boolean()]),
4449
- source: factSource.extend({ excerpt: excerptText.optional() }),
4450
- about
4451
- });
4452
- var HostedFactSchema = z50.union([
4453
- HostedValueFactSchema,
4454
- HostedExcerptSchema,
4455
- z50.array(HostedExcerptSchema).min(1).refine((excerpts2) => excerpts2.length <= hostedFactsLimits.maxExcerptsPerQuestion, "too_many_excerpts")
4456
- ]);
5292
+ sensitivity: id8.optional()
5293
+ };
5294
+ var manualSourcePrefix = "felspar:";
5295
+ var suppliedBy = z57.string().trim().min(1).max(200);
5296
+ var isReserved = (sourceId2) => sourceId2?.toLowerCase().startsWith(manualSourcePrefix) === true;
5297
+ function sourceIssues(source3) {
5298
+ if (source3.manual === true) {
5299
+ return [
5300
+ ...source3.id === void 0 ? [] : [{ path: ["id"], code: "manual_source_id" }],
5301
+ ...source3.revision === void 0 ? [] : [{ path: ["revision"], code: "manual_source_id" }]
5302
+ ];
5303
+ }
5304
+ return [
5305
+ ...source3.id === void 0 ? [{ path: ["id"], code: "source_id_required" }] : [],
5306
+ ...isReserved(source3.id) ? [{ path: ["id"], code: "source_id_reserved" }] : [],
5307
+ ...source3.observedAt === void 0 ? [{ path: ["observedAt"], code: "observed_at_required" }] : [],
5308
+ ...source3.suppliedBy === void 0 ? [] : [{ path: ["suppliedBy"], code: "supplied_by_needs_manual" }]
5309
+ ];
5310
+ }
5311
+ function isAdmittedManual(source3) {
5312
+ return source3.by !== void 0 && source3.id === void 0 && source3.revision === void 0;
5313
+ }
5314
+ function isAdmittedOrdinary(source3) {
5315
+ const isUnmarked = source3.by === void 0 && source3.stamped === void 0 && source3.suppliedBy === void 0;
5316
+ return source3.id !== void 0 && isUnmarked;
5317
+ }
5318
+ function isAdmitted(source3) {
5319
+ return source3.manual === true ? isAdmittedManual(source3) : isAdmittedOrdinary(source3);
5320
+ }
5321
+ var excerptText = z57.string().min(1).refine((text8) => text8.length <= hostedFactsLimits.maxExcerptCharacters, "text_too_long");
5322
+ var valueSourceFields = { excerpt: excerptText.optional() };
5323
+ var requestSourceFields = {
5324
+ ...sourceFields,
5325
+ id: factSourceId.optional(),
5326
+ observedAt: observedAt.optional(),
5327
+ manual: z57.literal(true).optional(),
5328
+ suppliedBy: suppliedBy.optional()
5329
+ };
5330
+ function refusedSourceIssues(source3, context3) {
5331
+ for (const issue of sourceIssues(source3)) {
5332
+ context3.addIssue({ code: "custom", path: issue.path, message: issue.code });
5333
+ }
5334
+ }
5335
+ var admittedSourceFields = {
5336
+ ...sourceFields,
5337
+ id: factSourceId.optional(),
5338
+ manual: z57.literal(true).optional(),
5339
+ suppliedBy: suppliedBy.optional(),
5340
+ by: id8.optional(),
5341
+ stamped: z57.literal(true).optional()
5342
+ };
5343
+ var requestSource = z57.strictObject(requestSourceFields).superRefine(refusedSourceIssues);
5344
+ var requestValueSource = z57.strictObject({ ...requestSourceFields, ...valueSourceFields }).superRefine(refusedSourceIssues);
5345
+ var admittedSource = z57.strictObject(admittedSourceFields).refine(isAdmitted, "source_not_admitted");
5346
+ var admittedValueSource = z57.strictObject({ ...admittedSourceFields, ...valueSourceFields }).refine(isAdmitted, "source_not_admitted");
5347
+ var about = z57.string().min(1).max(200).optional();
5348
+ var hostedCaseRecordLimits = {
5349
+ maxExcerptsPerQuestion: 30,
5350
+ maxExcerpts: hostedFactsLimits.maxQuestions * hostedFactsLimits.maxExcerptsPerQuestion,
5351
+ maxAttempts: 12
5352
+ };
5353
+ function factSchemas(source3, valueSource, isRecord) {
5354
+ const excerpt2 = z57.strictObject({ text: excerptText, source: source3, about });
5355
+ const valueFact = z57.strictObject({
5356
+ value: z57.union([z57.string().min(1).max(200), z57.number(), z57.boolean()]),
5357
+ source: valueSource,
5358
+ about
5359
+ });
5360
+ const cap = isRecord ? hostedCaseRecordLimits.maxExcerptsPerQuestion : hostedFactsLimits.maxExcerptsPerQuestion;
5361
+ const listed = isRecord ? z57.union([excerpt2, valueFact]) : excerpt2;
5362
+ const fact = z57.union([
5363
+ valueFact,
5364
+ excerpt2,
5365
+ z57.array(listed).min(1).refine((excerpts2) => excerpts2.length <= cap, "too_many_excerpts")
5366
+ ]);
5367
+ return { excerpt: excerpt2, valueFact, fact };
5368
+ }
5369
+ var admittedFacts = factSchemas(admittedSource, admittedValueSource, true);
5370
+ var requestFacts = factSchemas(requestSource, requestValueSource, false);
5371
+ var HostedExcerptSchema = admittedFacts.excerpt;
5372
+ var HostedValueFactSchema = admittedFacts.valueFact;
5373
+ var HostedFactSchema = admittedFacts.fact;
4457
5374
  function factsBytes(facts) {
4458
5375
  const encoder2 = new TextEncoder();
4459
5376
  return encoder2.encode(JSON.stringify(facts)).length;
4460
5377
  }
4461
- var HostedFactsJobInputSchema = z50.strictObject({
4462
- mode: z50.literal("facts"),
4463
- executionId: id6,
4464
- expectedReleaseDigest: digest23,
4465
- jobId: id6,
4466
- entityId: id6,
5378
+ function questionsOf(fact) {
5379
+ return z57.record(id8, fact).refine((facts) => Object.keys(facts).length <= hostedFactsLimits.maxQuestions, "too_many_questions");
5380
+ }
5381
+ function factsOf(fact) {
5382
+ return questionsOf(fact).refine((facts) => factsBytes(facts) <= hostedFactsLimits.maxFactsBytes, "request_too_large");
5383
+ }
5384
+ var HostedFactsJobInputSchema = z57.strictObject({
5385
+ mode: z57.literal("facts"),
5386
+ executionId: id8,
5387
+ expectedReleaseDigest: digest24,
5388
+ jobId: id8,
5389
+ entityId: id8,
4467
5390
  related: HostedRelatedSubjectsSchema.optional(),
4468
- identity: z50.record(z50.string().min(1).max(128), z50.string().min(1).max(200)).optional(),
4469
- facts: z50.record(id6, HostedFactSchema).refine((facts) => Object.keys(facts).length <= hostedFactsLimits.maxQuestions, "too_many_questions").refine((facts) => factsBytes(facts) <= hostedFactsLimits.maxFactsBytes, "request_too_large")
5391
+ identity: z57.record(z57.string().min(1).max(128), z57.string().min(1).max(200)).optional(),
5392
+ facts: questionsOf(HostedFactSchema)
4470
5393
  });
4471
5394
  var HostedFactsRequestSchema = HostedFactsJobInputSchema.extend({
4472
- entityId: id6.optional()
5395
+ entityId: id8.optional(),
5396
+ facts: factsOf(requestFacts.fact)
4473
5397
  });
4474
- var HostedJobRequestSchema = z50.union([
5398
+ var HostedJobRequestSchema = z57.union([
4475
5399
  HostedJobInputSchema,
4476
5400
  HostedSuppliedJobInputSchema,
4477
5401
  HostedFactsJobInputSchema
4478
5402
  ]);
4479
- var HostedClassificationResultSchema = z50.strictObject({
4480
- key: id6,
4481
- observationId: id6,
5403
+ var HostedClassificationResultSchema = z57.strictObject({
5404
+ key: id8,
5405
+ observationId: id8,
4482
5406
  record: DraftNormalizedEvidenceSchema.shape.normalizations.element,
4483
- reason: z50.string().regex(/^[a-z][a-z_]{2,63}$/u).nullable(),
4484
- cached: z50.boolean()
5407
+ reason: z57.string().regex(/^[a-z][a-z_]{2,63}$/u).nullable(),
5408
+ cached: z57.boolean()
4485
5409
  });
4486
5410
  function retainsFactsExactly(record) {
4487
5411
  const hasFacts = record.facts !== void 0 && record.judgments !== void 0 && record.judgmentsDigest !== void 0;
4488
5412
  return record.schema === "felspar.hosted-supplied-execution/v3" === hasFacts;
4489
5413
  }
4490
- var HostedSuppliedExecutionRecordSchema = z50.strictObject({
4491
- schema: z50.enum([
5414
+ var HostedCaseAttemptSchema = z57.strictObject({
5415
+ executionId: id8,
5416
+ added: z57.array(z57.string().min(1).max(draftSourceIdLimit + 4200)).max(192),
5417
+ considered: z57.boolean()
5418
+ });
5419
+ var HostedCaseRecordSchema = z57.strictObject({
5420
+ rule: z57.literal("whole-case"),
5421
+ attempt: z57.number().int().min(1).max(hostedCaseRecordLimits.maxAttempts + 1),
5422
+ attempts: z57.array(HostedCaseAttemptSchema).min(1).max(hostedCaseRecordLimits.maxAttempts + 1),
5423
+ facts: questionsOf(HostedFactSchema).optional()
5424
+ });
5425
+ var HostedSuppliedExecutionRecordSchema = z57.strictObject({
5426
+ schema: z57.enum([
4492
5427
  "felspar.hosted-supplied-execution/v1",
4493
5428
  "felspar.hosted-supplied-execution/v2",
4494
5429
  "felspar.hosted-supplied-execution/v3"
4495
5430
  ]),
4496
- release: z50.strictObject({ releaseId: id6, releaseDigest: digest23, materialDigest: digest23 }),
4497
- evaluationTime: z50.iso.datetime(),
5431
+ release: z57.strictObject({ releaseId: id8, releaseDigest: digest24, materialDigest: digest24 }),
5432
+ evaluationTime: z57.iso.datetime(),
4498
5433
  input: HostedSuppliedJobInputSchema,
4499
5434
  facts: HostedFactsJobInputSchema.optional(),
4500
- judgments: z50.array(HostedClassificationResultSchema).max(192).optional(),
4501
- judgmentsDigest: digest23.optional(),
4502
- expansion: z50.literal("agreeing-excerpts").optional(),
4503
- job: z50.record(z50.string(), z50.unknown())
4504
- }).refine(retainsFactsExactly, "Version 3 records, and only they, retain facts with their judgments");
4505
- var HostedObjectSchema = z50.strictObject({
4506
- id: id6,
4507
- kind: z50.enum(["source", "proposal", "approval", "release", "evidence", "result", "execution"]),
4508
- payloadDigest: digest23,
4509
- objectKey: z50.string().min(1).max(1e3),
4510
- parentId: id6.nullable(),
4511
- status: z50.enum(["active", "released", "revoked"]),
4512
- metadata: z50.record(z50.string(), z50.unknown())
4513
- });
4514
- var HostedJobResultSchema = z50.object({
4515
- status: z50.string(),
4516
- reason: z50.string().nullable(),
4517
- result: z50.object({
4518
- executionId: z50.string(),
4519
- releaseId: id6,
4520
- releaseDigest: digest23,
4521
- outcome: z50.string().nullable(),
4522
- scoring: z50.unknown(),
4523
- context: z50.unknown(),
4524
- receipt: z50.unknown()
5435
+ judgments: z57.array(HostedClassificationResultSchema).max(192).optional(),
5436
+ judgmentsDigest: digest24.optional(),
5437
+ expansion: z57.literal("agreeing-excerpts").optional(),
5438
+ caseRecord: HostedCaseRecordSchema.optional(),
5439
+ job: z57.record(z57.string(), z57.unknown())
5440
+ }).refine(retainsFactsExactly, "Version 3 records, and only they, retain facts with their judgments").refine((record) => record.caseRecord === void 0 || record.facts !== void 0, {
5441
+ message: "Only a facts record keeps a case record"
5442
+ });
5443
+ var HostedObjectSchema = z57.strictObject({
5444
+ id: id8,
5445
+ kind: z57.enum(["source", "proposal", "approval", "release", "evidence", "result", "execution"]),
5446
+ payloadDigest: digest24,
5447
+ objectKey: z57.string().min(1).max(1e3),
5448
+ parentId: id8.nullable(),
5449
+ status: z57.enum(["active", "released", "revoked"]),
5450
+ metadata: z57.record(z57.string(), z57.unknown())
5451
+ });
5452
+ var HostedJobResultSchema = z57.object({
5453
+ status: z57.string(),
5454
+ reason: z57.string().nullable(),
5455
+ result: z57.object({
5456
+ executionId: z57.string(),
5457
+ releaseId: id8,
5458
+ releaseDigest: digest24,
5459
+ outcome: z57.string().nullable(),
5460
+ scoring: z57.unknown(),
5461
+ context: z57.unknown(),
5462
+ receipt: z57.unknown()
4525
5463
  }).loose().nullable()
4526
5464
  });
4527
5465
 
@@ -4530,12 +5468,18 @@ var limits = hostedFactsLimits;
4530
5468
  var formatFix = "The request does not match the facts request format at this path; follow input.example from get_job_requirements (input.jsonSchema in the REST brief).";
4531
5469
  var fixes = {
4532
5470
  observed_at_invalid: "Send observedAt as the date and time the source was read, with Z or an offset: for example 2026-10-21T10:00:00Z or 2026-10-21T12:00+02:00. A date alone, a time with no offset or words such as yesterday are not accepted.",
4533
- source_id_invalid: `Send source.id as the source's own ID or address, such as the page URL with its query: at most ${draftSourceIdLimit} characters, starting with a letter or digit, using URL characters only (percent-encode spaces and non-ASCII characters).`,
5471
+ source_id_invalid: `Send source.id as the source's own ID or address, such as a ticket number or a document URL with its query: at most ${draftSourceIdLimit} characters, starting with a letter or digit, using URL characters only (percent-encode spaces and non-ASCII characters).`,
5472
+ source_id_required: "Send source.id: the source's own ID or address. For words a person gave you, mark the source manual: true instead and leave id out.",
5473
+ observed_at_required: "Send source.observedAt: when the source was read, with Z or an offset. For words a person gave you, mark the source manual: true and Felspar stamps the time it received them.",
5474
+ source_id_reserved: "Source IDs starting with felspar: are Felspar's own. Send the source's own ID, or mark words a person gave you manual: true with no id.",
5475
+ manual_source_id: "A manual source takes no id or revision. Name the source the person gave in locator, such as the record or message it came from.",
5476
+ supplied_by_needs_manual: "suppliedBy is only for words a person gave you: mark that source manual: true, or leave suppliedBy out.",
5477
+ manual_facts_refused: "This job's pack refuses facts supplied by a person (its manualFacts setting). Quote the source record itself, with its source.id and observedAt, or leave the question out.",
4534
5478
  unknown_question: "This question is not in the released job. Use the question keys from describe.",
4535
5479
  source_class_not_accepted: "This question does not accept this source class. Send an excerpt from a source class the question's evidence policy in describe lists.",
4536
5480
  value_not_in_excerpt: "The quoted words do not state this value. Quote the exact words that state it, or send the text without a typed value.",
4537
5481
  duplicate_excerpt: "The same words from the same source were sent twice for this question. Send each excerpt once.",
4538
- duplicate_source_locator: "Another excerpt in this request names the same source and locator with different words. Give each passage its own locator (for example the page URL with the section heading after #); the same words may answer several questions.",
5482
+ duplicate_source_locator: "Another excerpt in this request names the same source and locator with different words. Give each passage its own locator (for example the document URL with the section heading after #, or the message ID); the same words may answer several questions.",
4539
5483
  label_needs_mapping: "Felspar decides answer choices and yes/no questions from source text. Send the words the source says, not a label.",
4540
5484
  value_not_allowed: "A typed value must be a finite number for a number question or a YYYY-MM-DD date for a date question.",
4541
5485
  answer_choice_needs_excerpt: "Send this question in a facts request with the source text; Felspar classifies answer choices itself.",
@@ -4545,6 +5489,7 @@ var fixes = {
4545
5489
  request_too_large: `The facts in one request are at most ${limits.maxFactsBytes} bytes. Send shorter excerpts.`,
4546
5490
  release_changed: "The release changed. Describe the job again and resend with the current release digest.",
4547
5491
  job_mismatch: "This release serves a different job. Use the job and release from describe.",
5492
+ job_retired: "The workspace owner retired this job. Don't call it again: use the job named in replacement (check it with list_jobs), or, if replacement is null, tell the person the job is retired and stop.",
4548
5493
  attempt_limit_reached: "This case has used its decision attempts. Don't ask again: escalate it with the escalation this refusal names (report its id exactly), or with the next step from your last result.",
4549
5494
  subject_id_invalid: "Send the case's ID as the job's subject describes it (its identifier and example in the job requirements): letters, digits and . _ : @ - only.",
4550
5495
  unknown_relationship: "This job's subject has no relationship of this name. Use a relationship listed under subject.related in the job requirements, or leave related out.",
@@ -4566,14 +5511,55 @@ var fixes = {
4566
5511
  invalid_body: "The body must be JSON or content parts within the size limit.",
4567
5512
  context_graph_invalid: "Felspar would block every decision of this pack because of the context issues listed. Build the pack again from its draft with check_pack until it is clean, then propose it again; a pack with these issues can't be proposed, approved or released.",
4568
5513
  forbidden: "This caller may not run this job on this release, or the release is not available. Check the release ID and the caller's access.",
5514
+ access_denied: "This caller may not do this, or what it names is not available to it. Use a job list_jobs shows; if it should be there, ask a workspace owner to add the job to this agent on the Felspar web page.",
5515
+ unauthenticated: "No credential was sent. Send the agent key as a Bearer token, or sign in.",
5516
+ invalid_arguments: "The tool's arguments don't match its input schema. Correct the field at each issue's path and call the tool again.",
5517
+ not_found: "No Felspar route matches this path and method. Check the URL against the REST reference.",
5518
+ check_not_found: "No output check by this caller with this ID on this job. Send the checkId from your own check_output result.",
5519
+ history_not_found: "No case history matches. Check the case ID.",
5520
+ history_unavailable: "Case history could not be read or changed just now. Try again later.",
5521
+ no_current_release: "The job has no current release to compare with. Release a first version, then backtest later changes.",
5522
+ source_access_required: "Your own connection can't read a document behind this object. Connect or reconnect it on the Felspar Sources page, or ask the document's owner to share it.",
5523
+ operation_unavailable: "Felspar could not complete this request. Try again later with the same request; if it keeps failing, tell a person.",
4569
5524
  source_read_failed: "Felspar couldn't read the document's current version with your own connection. If access is not_connected or reconnect, connect or reconnect Google Drive on the Felspar Sources page; if no_access, ask the document's owner to share it with you; otherwise try again later.",
4570
5525
  source_text_not_allowed: "An MCP client can't submit text as a source. To use a document's newest text, call add_current_version with its sourceObjectId from list_sources.",
4571
5526
  source_not_connected: "This source was not added from a connected document. Use a sourceObjectId from list_sources.",
5527
+ pack_not_found: "No released version or proposal of this job matches. Call list_jobs for the workspace's jobs, their current release and open proposals; for a job not yet released, pass a proposalId it lists.",
5528
+ proposal_out_of_date: "A newer version of this job was released after this proposal was made, so it can't be approved or released. Update it: read_pack for the live pack, apply the change again, preview_change, then propose_pack, which replaces your earlier proposal.",
5529
+ proposal_closed: "This proposal was released, rejected, withdrawn or replaced by a newer proposal, so nothing more can be done with it. Call list_jobs for the job's open proposals.",
5530
+ not_proposer: "Only the person who made a proposal may withdraw it; an approver may reject it.",
5531
+ not_job_approver: "Only this job's owner and named approvers, or a workspace owner, may approve, release or reject its proposals. details.owners names who may; ask one of them to review it on the Felspar web page.",
5532
+ own_proposal: "The person who proposed a change can't approve it while another approver can. details.reason says why; ask one of the job's other approvers to review it on the Felspar web page.",
5533
+ proposal_review_unavailable: "This proposal's review can't be read. Call list_jobs for the job's open proposals.",
5534
+ withdraw_on_web_page: "Withdraw a proposal on the Felspar web page, or propose the job again, which replaces your earlier proposal.",
5535
+ change_request_needs_release: "This job has no release yet, so there is no document version to propose changes on. Draft its first pack with check_pack and propose_pack.",
5536
+ change_request_quote_invalid: "Each change must quote a passage exactly as it is in the release's version of the document (read_source on the source list_jobs names), found exactly once, with changes that don't overlap and a replacement that differs. details.problems names each change by its index: quote_not_found, quote_not_unique (quote more of the passage), edits_overlap or edit_unchanged.",
5537
+ change_request_definition_reason_required: "Give a reason for each definition the revised pack adds or changes: add { id, reason } under definitions for every id details.definitions lists.",
5538
+ change_request_definition_unknown: "A definition under definitions is not one the revised pack adds or changes. Use the question key or question/answer IDs from the revised pack's diff, or drop it.",
5539
+ change_request_too_large: "This change request is too large to store. Split it into smaller change requests.",
5540
+ change_request_not_found: "No change request with this ID. Call list_change_requests for the job's change requests.",
5541
+ change_request_edit_not_found: "The change request has no change at this index. Use an index from its changes, or leave edit out to comment on the whole request.",
5542
+ change_request_comment_limit: "This change request has as many comments as it can hold. Continue the discussion on the Felspar web page.",
5543
+ change_request_closed: "This change request is already closed.",
5544
+ change_request_close_on_web_page: "Withdraw or reject a change request on the Felspar web page; opening the job's change request again replaces your earlier one.",
5545
+ proposal_draft_invalid: "A proposal's draft must be a valid felspar.pack-draft for the proposal's own job. Propose with propose_pack, which keeps the draft it checked.",
5546
+ preview_too_large: "This draft changes more than one preview can show (2,048 item changes or 64 breaking changes). Preview a smaller revision, or split the pack.",
5547
+ backtest_allowance_used: "This proposal has used its whole fresh-read allowance, which all its backtests share. Backtest it again without reinterpret: true: the answers already read are reused and nothing new is read.",
5548
+ preview_reinterpret_blocked: "Fix the draft's blocking findings (check_pack lists them) before previewing with reinterpret: true. A preview without reinterpret still runs.",
5549
+ readings_blocked: "Fix the draft's blocking findings (check_pack lists them) before check_readings reads its wording.",
5550
+ nothing_to_read: "Send phrasings in variants, or add readingTests to the draft: there is nothing to read.",
5551
+ too_many_readings: `Read at most ${readingCheckLimits.maxPerCheck} phrasings per check_readings call, the draft's readingTests included. Split them across calls, or send include_tests: false.`,
5552
+ too_many_per_answer: `Send at most ${readingCheckLimits.maxPerAnswer} phrasings per answer (and per question for phrasings with no expected answer), the draft's readingTests included.`,
5553
+ duplicate_reading: "Two phrasings have the same id (a readingTests id counts too). Give each its own id, or leave id out.",
5554
+ question_not_read: "check_readings reads only choice questions Felspar classifies from text: not number, date or derived questions. Use a choice question's key from the draft.",
5555
+ answer_not_in_question: "expect must be one of that question's answer values in the draft.",
5556
+ pack_job_mismatch: "That release or proposal belongs to another job. Pass the jobId list_jobs shows with it.",
4572
5557
  decision_not_found: "Check the output against a decision this caller made: send the executionId from your get_job_decision result for this job.",
4573
5558
  decision_not_decided: "This decision has no outcome, so nothing is written for it. Follow its next step instead.",
4574
5559
  no_output_checks: "This job's release declares no output checks. Use the decision's next step; nothing is checked before sending.",
4575
5560
  output_not_required: "The decided outcome does not require this output. Send one of the outputs listed in required, or none when it is empty.",
4576
5561
  output_too_large: "The text is longer than this output allows. Shorten it and check again.",
5562
+ invalid_input: "The request does not match the format. Correct each issue at its path: follow input.example from get_job_requirements (input.jsonSchema in the REST brief).",
4577
5563
  invalid_type: formatFix,
4578
5564
  invalid_union: formatFix,
4579
5565
  invalid_value: formatFix,
@@ -4582,241 +5568,279 @@ var fixes = {
4582
5568
  too_big: formatFix,
4583
5569
  too_small: formatFix
4584
5570
  };
5571
+ var hostedRefusalCodes = Object.freeze(Object.keys(fixes));
4585
5572
  function hostedRefusalFix(code) {
4586
5573
  return Object.hasOwn(fixes, code) ? fixes[code] ?? null : null;
4587
5574
  }
5575
+ var retried = /* @__PURE__ */ new Set(["rate_limited", "history_unavailable", "operation_unavailable"]);
5576
+ var escalated = /* @__PURE__ */ new Set([
5577
+ "unauthenticated",
5578
+ "forbidden",
5579
+ "access_denied",
5580
+ "job_retired",
5581
+ "attempt_limit_reached",
5582
+ "source_access_required",
5583
+ "source_read_failed",
5584
+ "no_current_release"
5585
+ ]);
5586
+ function hostedRefusalRecovery(code) {
5587
+ if (!Object.hasOwn(fixes, code)) {
5588
+ return null;
5589
+ }
5590
+ if (retried.has(code)) {
5591
+ return "retry";
5592
+ }
5593
+ return escalated.has(code) ? "escalate" : "fix_input";
5594
+ }
4588
5595
 
4589
5596
  // ../schemas/src/draft-hosted-job-description.ts
4590
- import { z as z52 } from "zod";
5597
+ import { z as z59 } from "zod";
4591
5598
 
4592
5599
  // ../schemas/src/draft-hosted-output-guides.ts
4593
- import { z as z51 } from "zod";
4594
- var id7 = z51.string().min(1).max(200);
4595
- var located = z51.strictObject({
4596
- text: z51.string().min(1).max(262144),
4597
- locator: z51.string().min(1).max(4096)
5600
+ import { z as z58 } from "zod";
5601
+ var id9 = z58.string().min(1).max(200);
5602
+ var located = z58.strictObject({
5603
+ text: z58.string().min(1).max(262144),
5604
+ locator: z58.string().min(1).max(4096)
4598
5605
  });
4599
5606
  var hostedOutputGuideLimits = { maxOutputs: 8, maxContext: 8, maxChecks: 64 };
4600
- var HostedOutputGuideSchema = z51.strictObject({
4601
- id: id7,
5607
+ var HostedOutputGuideSchema = z58.strictObject({
5608
+ id: id9,
4602
5609
  what: located,
4603
- maxCharacters: z51.number().int().min(1),
4604
- context: z51.array(located.extend({ id: id7 })).max(hostedOutputGuideLimits.maxContext).optional(),
4605
- checks: z51.array(z51.strictObject({
4606
- check: id7,
4607
- rule: z51.string().nullable(),
4608
- must: z51.string().min(1).max(8e3)
5610
+ maxCharacters: z58.number().int().min(1),
5611
+ context: z58.array(located.extend({ id: id9 })).max(hostedOutputGuideLimits.maxContext).optional(),
5612
+ checks: z58.array(z58.strictObject({
5613
+ check: id9,
5614
+ rule: z58.string().nullable(),
5615
+ must: z58.string().min(1).max(8e3)
4609
5616
  })).max(hostedOutputGuideLimits.maxChecks)
4610
5617
  });
4611
- var HostedOutputGuidesSchema = z51.array(HostedOutputGuideSchema).max(hostedOutputGuideLimits.maxOutputs);
5618
+ var HostedOutputGuidesSchema = z58.array(HostedOutputGuideSchema).max(hostedOutputGuideLimits.maxOutputs);
4612
5619
 
4613
5620
  // ../schemas/src/draft-hosted-job-description.ts
4614
- var id8 = z52.string().min(1).max(200);
4615
- var digest24 = DraftApplicationReleaseSchema.shape.releaseDigest;
5621
+ var id10 = z59.string().min(1).max(200);
5622
+ var digest25 = DraftApplicationReleaseSchema.shape.releaseDigest;
4616
5623
  var { requirements, rules } = DraftRequiredProposalSchema.shape;
4617
- var quotedText = z52.strictObject({
4618
- text: z52.string().min(1).max(262144),
5624
+ var quotedText = z59.strictObject({
5625
+ text: z59.string().min(1).max(262144),
4619
5626
  source: DraftSourceReferenceSchema.omit({ contentDigest: true }).extend({
4620
- locator: z52.string().min(1).max(4096),
4621
- contentDigest: digest24
5627
+ locator: z59.string().min(1).max(4096),
5628
+ contentDigest: digest25
4622
5629
  }),
4623
- parts: z52.array(z52.strictObject({ locator: z52.string().min(1).max(4096), text: z52.string() })).max(16)
5630
+ parts: z59.array(z59.strictObject({ locator: z59.string().min(1).max(4096), text: z59.string() })).max(16)
4624
5631
  });
4625
5632
  var subjectShape = {
4626
- identifier: z52.string().min(1).max(200),
4627
- example: z52.string().min(1).max(200),
4628
- match: z52.enum(subjectMatchRules)
5633
+ identifier: z59.string().min(1).max(200),
5634
+ example: z59.string().min(1).max(200),
5635
+ match: z59.enum(subjectMatchRules)
4629
5636
  };
4630
- var HostedJobSubjectSchema = z52.strictObject({
4631
- type: id8,
5637
+ var HostedJobSubjectSchema = z59.strictObject({
5638
+ type: id10,
4632
5639
  definition: quotedText,
4633
5640
  identifier: subjectShape.identifier.optional(),
4634
5641
  example: subjectShape.example.optional(),
4635
5642
  match: subjectShape.match,
4636
- related: z52.array(z52.strictObject({
4637
- relationship: id8,
5643
+ related: z59.array(z59.strictObject({
5644
+ relationship: id10,
4638
5645
  meaning: quotedText,
4639
- cardinality: z52.enum(relationshipCardinalities),
4640
- required: z52.boolean(),
4641
- subject: id8,
5646
+ cardinality: z59.enum(relationshipCardinalities),
5647
+ required: z59.boolean(),
5648
+ subject: id10,
4642
5649
  definition: quotedText,
4643
5650
  ...subjectShape
4644
5651
  })).max(16),
4645
- send: z52.string().min(1).max(2e4)
5652
+ send: z59.string().min(1).max(2e4)
4646
5653
  });
4647
- var HostedJobEscalationsSchema = z52.strictObject({
4648
- routes: z52.array(z52.strictObject({ id: id8, quote: quotedText })).min(1).max(16),
4649
- unresolved: id8.nullable(),
4650
- attemptLimit: id8.nullable(),
4651
- rule: z52.string().min(1).max(1e3)
5654
+ var HostedJobEscalationsSchema = z59.strictObject({
5655
+ routes: z59.array(z59.strictObject({ id: id10, quote: quotedText })).min(1).max(16),
5656
+ unresolved: id10.nullable(),
5657
+ attemptLimit: id10.nullable(),
5658
+ rule: z59.string().min(1).max(1e3)
4652
5659
  });
4653
- var HostedEscalationSchema = z52.strictObject({
4654
- id: id8,
4655
- trigger: z52.enum(escalationTriggers),
5660
+ var HostedEscalationSchema = z59.strictObject({
5661
+ id: id10,
5662
+ trigger: z59.enum(escalationTriggers),
4656
5663
  why: quotedText
4657
5664
  });
4658
- var HostedJobDescriptionSchema = z52.strictObject({
4659
- schema: z52.literal("felspar.hosted-job-description.draft/v0"),
4660
- job: id8,
5665
+ var HostedJobDescriptionSchema = z59.strictObject({
5666
+ schema: z59.literal("felspar.hosted-job-description.draft/v0"),
5667
+ job: id10,
4661
5668
  purpose: quotedText.optional(),
4662
- useWhen: z52.array(quotedText).max(8).optional(),
4663
- notFor: z52.array(quotedText).max(8).optional(),
5669
+ useWhen: z59.array(quotedText).max(8).optional(),
5670
+ notFor: z59.array(quotedText).max(8).optional(),
4664
5671
  owner: quotedText.optional(),
4665
5672
  subject: HostedJobSubjectSchema.optional(),
4666
- identity: z52.strictObject({
4667
- mode: z52.enum(identityModes),
4668
- send: z52.string().min(1).max(4e3),
4669
- fields: z52.array(z52.strictObject({ name: id8, ...subjectShape })).max(8).optional(),
4670
- question: id8.optional()
5673
+ identity: z59.strictObject({
5674
+ mode: z59.enum(identityModes),
5675
+ send: z59.string().min(1).max(4e3),
5676
+ fields: z59.array(z59.strictObject({ name: id10, ...subjectShape })).max(8).optional(),
5677
+ question: id10.optional()
4671
5678
  }).optional(),
4672
- trustDomain: id8,
4673
- release: z52.strictObject({
4674
- releaseId: id8,
4675
- releaseDigest: digest24,
4676
- materialDigest: digest24,
4677
- expectedAuthorityDigest: digest24
5679
+ manualFacts: z59.strictObject({ allowed: z59.literal(false), quote: z59.string().min(1).max(4e3) }).optional(),
5680
+ trustDomain: id10,
5681
+ release: z59.strictObject({
5682
+ releaseId: id10,
5683
+ releaseDigest: digest25,
5684
+ materialDigest: digest25,
5685
+ expectedAuthorityDigest: digest25
4678
5686
  }),
4679
5687
  resolutionPolicy: DraftRequiredProposalSchema.shape.resolutionPolicy,
4680
- questions: z52.array(requirements.element.extend({
4681
- key: id8,
4682
- type: z52.enum(["enum", "boolean", "number", "date"]),
5688
+ questions: z59.array(requirements.element.extend({
5689
+ key: id10,
5690
+ type: z59.enum(["enum", "boolean", "number", "date"]),
4683
5691
  meaning: quotedText,
4684
- answer: z52.strictObject({
4685
- send: z52.enum(["text", "text_or_value"]),
4686
- valueFormat: z52.enum(["number", "calendar-date"]).nullable(),
4687
- interpretation: z52.enum(["classified", "exact_read", "unsupported"]),
4688
- threshold: z52.number().gt(0).max(1).nullable(),
4689
- applies: z52.enum(["always", "conditional"]),
4690
- dependsOn: z52.array(id8).max(32),
4691
- appliesWhen: z52.string().min(1).max(2e3).nullable(),
5692
+ answer: z59.strictObject({
5693
+ send: z59.enum(["text", "text_or_value"]),
5694
+ valueFormat: z59.enum(["number", "calendar-date"]).nullable(),
5695
+ interpretation: z59.enum(["classified", "exact_read", "unsupported"]),
5696
+ threshold: z59.number().gt(0).max(1).nullable(),
5697
+ applies: z59.enum(["always", "conditional"]),
5698
+ dependsOn: z59.array(id10).max(32),
5699
+ appliesWhen: z59.string().min(1).max(2e3).nullable(),
4692
5700
  reading: ExactReaderSchema.optional()
4693
5701
  }),
4694
- answers: z52.array(z52.strictObject({
4695
- value: id8,
4696
- meaning: z52.string().nullable(),
4697
- inclusions: z52.array(z52.string()).max(8),
4698
- exclusions: z52.array(z52.string()).max(8),
4699
- examples: z52.array(z52.string()).max(8),
4700
- edgeCases: z52.array(z52.string()).max(8)
5702
+ answers: z59.array(z59.strictObject({
5703
+ value: id10,
5704
+ meaning: z59.string().nullable(),
5705
+ inclusions: z59.array(z59.string()).max(8),
5706
+ exclusions: z59.array(z59.string()).max(8),
5707
+ examples: z59.array(z59.string()).max(8),
5708
+ edgeCases: z59.array(z59.string()).max(8)
4701
5709
  })).max(64).optional(),
4702
- whereToLook: z52.array(quotedText).max(8).optional(),
4703
- about: z52.strictObject({ relationship: id8, subject: id8 }).optional()
5710
+ whereToLook: z59.array(quotedText).max(8).optional(),
5711
+ about: z59.strictObject({ relationship: id10, subject: id10 }).optional()
4704
5712
  })).max(64),
4705
- rules: z52.array(rules.element.extend({ text: quotedText })).max(256),
4706
- outcomes: z52.array(z52.strictObject({
4707
- id: id8,
5713
+ rules: z59.array(rules.element.extend({ text: quotedText })).max(256),
5714
+ outcomes: z59.array(z59.strictObject({
5715
+ id: id10,
4708
5716
  meaning: quotedText.nullable(),
4709
5717
  nextStep: quotedText.nullable().optional(),
4710
5718
  outputs: HostedOutputGuidesSchema.optional(),
4711
- escalate: id8.optional()
5719
+ escalate: id10.optional()
4712
5720
  })).max(64),
4713
5721
  escalations: HostedJobEscalationsSchema.optional(),
4714
5722
  whenUnresolved: quotedText.nullable().optional(),
4715
- attempts: z52.strictObject({
4716
- max: z52.number().int().min(1).max(10),
4717
- withProgress: z52.number().int().min(1).max(10),
4718
- rule: z52.string().min(1).max(1e3)
5723
+ attempts: z59.strictObject({
5724
+ max: z59.number().int().min(1).max(10),
5725
+ withProgress: z59.number().int().min(1).max(10),
5726
+ rule: z59.string().min(1).max(1e3)
4719
5727
  }).optional(),
4720
- guidance: z52.strictObject({ gather: z52.string().min(1).max(2e3) }),
4721
- input: z52.strictObject({
4722
- jsonSchema: z52.record(z52.string(), z52.unknown()),
5728
+ guidance: z59.strictObject({ gather: z59.string().min(1).max(2e3) }),
5729
+ input: z59.strictObject({
5730
+ jsonSchema: z59.record(z59.string(), z59.unknown()),
4723
5731
  example: HostedFactsJobInputSchema.nullable(),
4724
- exampleNote: z52.string().max(1e3)
5732
+ exampleNote: z59.string().max(1e3)
4725
5733
  }),
4726
- limits: z52.strictObject({
4727
- maxEvidenceItems: z52.number().int().positive(),
4728
- maxPassages: z52.number().int().positive(),
4729
- facts: z52.strictObject({
4730
- maxExcerptCharacters: z52.literal(hostedFactsLimits.maxExcerptCharacters),
4731
- maxExcerptsPerQuestion: z52.literal(hostedFactsLimits.maxExcerptsPerQuestion),
4732
- maxFactsBytes: z52.literal(hostedFactsLimits.maxFactsBytes),
4733
- maxQuestions: z52.literal(hostedFactsLimits.maxQuestions)
5734
+ limits: z59.strictObject({
5735
+ maxEvidenceItems: z59.number().int().positive(),
5736
+ maxPassages: z59.number().int().positive(),
5737
+ facts: z59.strictObject({
5738
+ maxExcerptCharacters: z59.literal(hostedFactsLimits.maxExcerptCharacters),
5739
+ maxExcerptsPerQuestion: z59.literal(hostedFactsLimits.maxExcerptsPerQuestion),
5740
+ maxFactsBytes: z59.literal(hostedFactsLimits.maxFactsBytes),
5741
+ maxQuestions: z59.literal(hostedFactsLimits.maxQuestions)
4734
5742
  })
4735
5743
  })
4736
5744
  });
4737
- var interpretedExcerpt = z52.strictObject({
4738
- id: id8,
4739
- method: z52.enum(["value", "exact_read", "classified"]),
4740
- status: z52.enum(["accepted", "needs_evidence", "not_needed"]),
4741
- value: z52.union([z52.string(), z52.number(), z52.boolean()]).optional(),
4742
- reasons: z52.array(z52.string()),
4743
- classification: z52.strictObject({
4744
- candidate: z52.string().nullable(),
4745
- probability: z52.number().min(0).max(1).nullable(),
4746
- abstention: z52.number().min(0).max(1).nullable(),
4747
- threshold: z52.number().min(0).max(1),
4748
- alternatives: z52.array(z52.strictObject({ value: z52.string(), probability: z52.number() }))
5745
+ var interpretedExcerpt = z59.strictObject({
5746
+ id: id10,
5747
+ method: z59.enum(["value", "exact_read", "classified"]),
5748
+ status: z59.enum(["accepted", "needs_evidence", "not_needed"]),
5749
+ value: z59.union([z59.string(), z59.number(), z59.boolean()]).optional(),
5750
+ reasons: z59.array(z59.string()),
5751
+ classification: z59.strictObject({
5752
+ candidate: z59.string().nullable(),
5753
+ probability: z59.number().min(0).max(1).nullable(),
5754
+ abstention: z59.number().min(0).max(1).nullable(),
5755
+ threshold: z59.number().min(0).max(1),
5756
+ alternatives: z59.array(z59.strictObject({ value: z59.string(), probability: z59.number() }))
4749
5757
  }).optional()
4750
5758
  });
4751
- var ruleSummary = z52.strictObject({ id: id8, outcome: id8, text: quotedText });
4752
- var HostedJobExplanationSchema = z52.strictObject({
4753
- schema: z52.literal("felspar.hosted-job-explanation.draft/v0"),
4754
- decision: z52.strictObject({ status: z52.string().nullable(), reasons: z52.array(z52.string()) }),
4755
- needs: z52.array(z52.strictObject({
4756
- key: id8,
4757
- status: z52.string(),
4758
- reasons: z52.array(z52.string()),
4759
- acceptedSourceClasses: z52.array(z52.string()),
4760
- maxAgeMs: z52.number().int().nonnegative(),
5759
+ var ruleSummary = z59.strictObject({ id: id10, outcome: id10, text: quotedText });
5760
+ var HostedJobExplanationSchema = z59.strictObject({
5761
+ schema: z59.literal("felspar.hosted-job-explanation.draft/v0"),
5762
+ decision: z59.strictObject({ status: z59.string().nullable(), reasons: z59.array(z59.string()) }),
5763
+ needs: z59.array(z59.strictObject({
5764
+ key: id10,
5765
+ status: z59.string(),
5766
+ reasons: z59.array(z59.string()),
5767
+ acceptedSourceClasses: z59.array(z59.string()),
5768
+ maxAgeMs: z59.number().int().nonnegative(),
4761
5769
  requiredWhen: HostedJobDescriptionSchema.shape.questions.element.shape.requiredWhen,
4762
- excerpts: z52.array(interpretedExcerpt).optional()
5770
+ excerpts: z59.array(interpretedExcerpt).optional()
4763
5771
  })),
4764
- why: z52.strictObject({
4765
- rules: z52.array(ruleSummary),
4766
- overrides: z52.array(z52.strictObject({ by: id8, target: id8 })),
4767
- suppressedRuleIds: z52.array(id8),
4768
- evidence: z52.array(z52.record(z52.string(), z52.unknown()))
5772
+ why: z59.strictObject({
5773
+ rules: z59.array(ruleSummary),
5774
+ overrides: z59.array(z59.strictObject({ by: id10, target: id10 })),
5775
+ suppressedRuleIds: z59.array(id10),
5776
+ evidence: z59.array(z59.record(z59.string(), z59.unknown()))
4769
5777
  }).nullable(),
4770
- context: z52.strictObject({ status: z52.string(), reason: z52.string().nullable() }).nullable(),
4771
- reviewNeeds: z52.array(z52.string()),
4772
- evidenceFreshUntil: z52.iso.datetime().nullable()
5778
+ context: z59.strictObject({ status: z59.string(), reason: z59.string().nullable() }).nullable(),
5779
+ reviewNeeds: z59.array(z59.string()),
5780
+ evidenceFreshUntil: z59.iso.datetime().nullable()
4773
5781
  });
4774
- var HostedReceiptVerificationInputSchema = z52.strictObject({
5782
+ var HostedReceiptVerificationInputSchema = z59.strictObject({
4775
5783
  receipt: DraftJobReceiptSchema,
4776
- expectedReceiptDigest: digest24,
5784
+ expectedReceiptDigest: digest25,
4777
5785
  deliveredCapsule: DraftContextVerificationOptionsSchema.shape.deliveredCapsule
4778
5786
  });
4779
- var HostedReceiptVerificationSchema = z52.strictObject({
4780
- authority: z52.literal("unapproved"),
4781
- status: z52.enum(["reproduced", "mismatch"]),
4782
- mismatches: z52.array(z52.string()),
4783
- decided: z52.strictObject({
4784
- jobId: id8,
4785
- entityId: id8,
4786
- releaseId: id8,
4787
- outcome: id8.nullable(),
4788
- case: z52.strictObject({ id: id8, mode: z52.enum(identityModes) }).optional(),
4789
- subject: z52.strictObject({
4790
- type: id8,
4791
- related: z52.array(z52.strictObject({ relationship: id8, subject: id8, id: id8, questions: z52.array(id8).max(64) })).max(256)
5787
+ var HostedReceiptVerificationSchema = z59.strictObject({
5788
+ authority: z59.literal("unapproved"),
5789
+ status: z59.enum(["reproduced", "mismatch"]),
5790
+ mismatches: z59.array(z59.string()),
5791
+ decided: z59.strictObject({
5792
+ jobId: id10,
5793
+ entityId: id10,
5794
+ releaseId: id10,
5795
+ outcome: id10.nullable(),
5796
+ case: z59.strictObject({ id: id10, mode: z59.enum(identityModes) }).optional(),
5797
+ subject: z59.strictObject({
5798
+ type: id10,
5799
+ related: z59.array(z59.strictObject({ relationship: id10, subject: id10, id: id10, questions: z59.array(id10).max(64) })).max(256)
4792
5800
  }).optional(),
4793
- escalation: HostedEscalationSchema.omit({ why: true }).optional()
5801
+ escalation: HostedEscalationSchema.omit({ why: true }).optional(),
5802
+ manualFacts: z59.array(z59.strictObject({
5803
+ question: id10,
5804
+ excerpt: z59.number().int().min(0).max(hostedCaseRecordLimits.maxExcerptsPerQuestion - 1),
5805
+ via: z59.strictObject({
5806
+ principal: id10,
5807
+ agent: z59.strictObject({ name: z59.string(), accountable: id10 }).nullable()
5808
+ }),
5809
+ observedAt: z59.string(),
5810
+ stampedByFelspar: z59.boolean(),
5811
+ suppliedBy: z59.strictObject({ text: z59.string(), verified: z59.literal(false) }).optional()
5812
+ })).max(192).optional(),
5813
+ caseRecord: z59.strictObject({
5814
+ rule: z59.literal("whole-case"),
5815
+ attempt: z59.number().int().min(1),
5816
+ attempts: z59.array(HostedCaseAttemptSchema).max(hostedCaseRecordLimits.maxAttempts + 1)
5817
+ }).optional()
4794
5818
  }).optional()
4795
5819
  });
4796
5820
 
4797
5821
  // ../schemas/src/draft-hosted-output-check-record.ts
4798
- import { z as z55 } from "zod";
5822
+ import { z as z62 } from "zod";
4799
5823
 
4800
5824
  // ../schemas/src/draft-artifact-lint.ts
4801
- import { z as z54 } from "zod";
5825
+ import { z as z61 } from "zod";
4802
5826
 
4803
5827
  // ../schemas/src/draft-job-obligations.ts
4804
- import { z as z53 } from "zod";
4805
- var id9 = DraftApplicationScopeSchema.shape.authorityId;
4806
- var digest25 = DraftJobReceiptSchema.shape.receiptDigest;
5828
+ import { z as z60 } from "zod";
5829
+ var id11 = DraftApplicationScopeSchema.shape.authorityId;
5830
+ var digest26 = DraftJobReceiptSchema.shape.receiptDigest;
4807
5831
  var outcome2 = DraftJobObligationsOutcomeSchema;
4808
5832
  var DraftApplicationJobMaterialV3Schema = DraftApplicationJobMaterialV2Schema.extend({
4809
- schema: z53.literal("felspar.application-job-material.draft/v3"),
5833
+ schema: z60.literal("felspar.application-job-material.draft/v3"),
4810
5834
  obligations: DraftJobObligationsSchema
4811
- }).superRefine((value, context3) => {
5835
+ }).superRefine((value2, context3) => {
4812
5836
  if (context3.issues.length > 0) {
4813
5837
  return;
4814
5838
  }
4815
- const { obligations, discovery } = value;
4816
- const { proposal } = value.input.invocation.authority.catalog;
5839
+ const { obligations, discovery } = value2;
5840
+ const { proposal } = value2.input.invocation.authority.catalog;
4817
5841
  const isSourceMatches = Object.entries(proposal.source).every(([key3, expected2]) => Reflect.get(obligations.source, key3) === expected2);
4818
- const outcomes = new Set(obligations.outcomes.map((entry2) => entry2.outcomeId));
4819
- const isComplete = outcomes.size === proposal.allowedOutcomes.length && proposal.allowedOutcomes.every((entry2) => outcomes.has(entry2));
5842
+ const outcomes = new Set(obligations.outcomes.map((entry3) => entry3.outcomeId));
5843
+ const isComplete = outcomes.size === proposal.allowedOutcomes.length && proposal.allowedOutcomes.every((entry3) => outcomes.has(entry3));
4820
5844
  const matches = [
4821
5845
  isSourceMatches,
4822
5846
  isComplete,
@@ -4834,57 +5858,57 @@ var DraftApplicationJobMaterialV3Schema = DraftApplicationJobMaterialV2Schema.ex
4834
5858
  }
4835
5859
  });
4836
5860
  var HostedProposalInputV3Schema = HostedProposalInputV2Schema.extend({
4837
- schema: z53.literal("felspar.hosted-proposal.draft/v3"),
5861
+ schema: z60.literal("felspar.hosted-proposal.draft/v3"),
4838
5862
  material: DraftApplicationJobMaterialV3Schema
4839
5863
  });
4840
5864
  var jobObligationsReplayRoutes = ["supplied", "evaluated"];
4841
5865
  var replayRoutes = new Set(jobObligationsReplayRoutes);
4842
5866
  var DraftJobObligationsExecutionSchema = DraftAnyJobExecutionSchema.refine((execution) => replayRoutes.has(execution.invocation.route), "Obligations assessments support supplied and evaluated native executions");
4843
- var DraftJobObligationsNativeResultSchema = z53.strictObject({
4844
- authority: z53.literal("unapproved"),
4845
- discovery: z53.record(z53.string(), z53.unknown()),
4846
- executed: z53.record(z53.string(), z53.unknown()),
5867
+ var DraftJobObligationsNativeResultSchema = z60.strictObject({
5868
+ authority: z60.literal("unapproved"),
5869
+ discovery: z60.record(z60.string(), z60.unknown()),
5870
+ executed: z60.record(z60.string(), z60.unknown()),
4847
5871
  receipt: DraftJobReceiptSchema
4848
5872
  });
4849
- var DraftJobObligationsInputSchema = z53.strictObject({
5873
+ var DraftJobObligationsInputSchema = z60.strictObject({
4850
5874
  release: DraftApplicationReleaseSchema,
4851
- material: z53.union([DraftApplicationJobMaterialV3Schema, DraftAnyApplicationJobMaterialSchema]),
5875
+ material: z60.union([DraftApplicationJobMaterialV3Schema, DraftAnyApplicationJobMaterialSchema]),
4852
5876
  execution: DraftJobObligationsExecutionSchema,
4853
- expectedReceiptDigest: digest25,
5877
+ expectedReceiptDigest: digest26,
4854
5878
  job: DraftJobObligationsNativeResultSchema,
4855
5879
  explanation: HostedJobExplanationSchema,
4856
- invocation: DraftJobObligationsScopeSchema.extend({ caseId: id9 })
5880
+ invocation: DraftJobObligationsScopeSchema.extend({ caseId: id11 })
4857
5881
  });
4858
- var requirements2 = z53.strictObject({
4859
- status: z53.enum(["established", "unresolved"]),
5882
+ var requirements2 = z60.strictObject({
5883
+ status: z60.enum(["established", "unresolved"]),
4860
5884
  scope: DraftJobObligationsScopeSchema,
4861
5885
  artifacts: outcome2.shape.artifacts,
4862
5886
  approvals: outcome2.shape.approvals,
4863
- unresolved: z53.array(z53.strictObject({ scopeRef: id9, reasonCodes: z53.array(id9).min(1).max(64) })).max(64)
5887
+ unresolved: z60.array(z60.strictObject({ scopeRef: id11, reasonCodes: z60.array(id11).min(1).max(64) })).max(64)
4864
5888
  });
4865
- var nextReference = z53.discriminatedUnion("kind", [
4866
- z53.strictObject({ kind: z53.literal("evidence_need"), id: id9 }),
4867
- z53.strictObject({ kind: z53.literal("artifact_requirement"), id: id9 }),
4868
- z53.strictObject({ kind: z53.literal("approval_requirement"), id: id9 }),
4869
- z53.strictObject({ kind: z53.literal("unresolved_scope"), scopeRef: id9 })
5889
+ var nextReference = z60.discriminatedUnion("kind", [
5890
+ z60.strictObject({ kind: z60.literal("evidence_need"), id: id11 }),
5891
+ z60.strictObject({ kind: z60.literal("artifact_requirement"), id: id11 }),
5892
+ z60.strictObject({ kind: z60.literal("approval_requirement"), id: id11 }),
5893
+ z60.strictObject({ kind: z60.literal("unresolved_scope"), scopeRef: id11 })
4870
5894
  ]);
4871
- var DraftJobObligationsAssessmentBodySchema = z53.strictObject({
4872
- schema: z53.literal("felspar.job-obligations-assessment.draft/v0"),
4873
- binding: z53.strictObject({
4874
- releaseDigest: digest25,
4875
- materialDigest: digest25,
4876
- nativeReceiptDigest: digest25,
4877
- jobId: id9,
5895
+ var DraftJobObligationsAssessmentBodySchema = z60.strictObject({
5896
+ schema: z60.literal("felspar.job-obligations-assessment.draft/v0"),
5897
+ binding: z60.strictObject({
5898
+ releaseDigest: digest26,
5899
+ materialDigest: digest26,
5900
+ nativeReceiptDigest: digest26,
5901
+ jobId: id11,
4878
5902
  applicationScope: DraftApplicationScopeSchema,
4879
- caseId: id9,
4880
- entityId: id9,
4881
- evaluationTime: z53.iso.datetime({ offset: true }),
4882
- purposeRef: id9,
4883
- useRef: id9.nullable()
5903
+ caseId: id11,
5904
+ entityId: id11,
5905
+ evaluationTime: z60.iso.datetime({ offset: true }),
5906
+ purposeRef: id11,
5907
+ useRef: id11.nullable()
4884
5908
  }),
4885
5909
  requirements: requirements2,
4886
- next: z53.strictObject({
4887
- kind: z53.enum([
5910
+ next: z60.strictObject({
5911
+ kind: z60.enum([
4888
5912
  "stop",
4889
5913
  "review_required",
4890
5914
  "gather_evidence",
@@ -4892,20 +5916,20 @@ var DraftJobObligationsAssessmentBodySchema = z53.strictObject({
4892
5916
  "verify_before_action",
4893
5917
  "return_result"
4894
5918
  ]),
4895
- reasonCodes: z53.array(id9).max(64),
4896
- refs: z53.array(nextReference).max(64)
5919
+ reasonCodes: z60.array(id11).max(64),
5920
+ refs: z60.array(nextReference).max(64)
4897
5921
  })
4898
5922
  });
4899
5923
  function isNextRefDeclared(ref, required) {
4900
5924
  switch (ref.kind) {
4901
5925
  case "artifact_requirement": {
4902
- return required.artifacts.some((entry2) => entry2.id === ref.id);
5926
+ return required.artifacts.some((entry3) => entry3.id === ref.id);
4903
5927
  }
4904
5928
  case "approval_requirement": {
4905
- return required.approvals.some((entry2) => entry2.id === ref.id);
5929
+ return required.approvals.some((entry3) => entry3.id === ref.id);
4906
5930
  }
4907
5931
  case "unresolved_scope": {
4908
- return required.unresolved.some((entry2) => entry2.scopeRef === ref.scopeRef);
5932
+ return required.unresolved.some((entry3) => entry3.scopeRef === ref.scopeRef);
4909
5933
  }
4910
5934
  case "evidence_need": {
4911
5935
  return true;
@@ -4916,13 +5940,13 @@ function isNextRefDeclared(ref, required) {
4916
5940
  }
4917
5941
  }
4918
5942
  var DraftJobObligationsAssessmentSchema = DraftJobObligationsAssessmentBodySchema.extend({
4919
- assessmentDigest: digest25
4920
- }).superRefine((value, context3) => {
4921
- const { requirements: required } = value;
5943
+ assessmentDigest: digest26
5944
+ }).superRefine((value2, context3) => {
5945
+ const { requirements: required } = value2;
4922
5946
  if (required.status === "established" !== (required.unresolved.length === 0) || required.status === "unresolved" && (required.artifacts.length > 0 || required.approvals.length > 0)) {
4923
5947
  context3.addIssue({ code: "custom", message: "Requirements completeness differs" });
4924
5948
  }
4925
- for (const ref of value.next.refs) {
5949
+ for (const ref of value2.next.refs) {
4926
5950
  if (!isNextRefDeclared(ref, required)) {
4927
5951
  context3.addIssue({ code: "custom", message: "Dangling next reference" });
4928
5952
  }
@@ -4930,48 +5954,48 @@ var DraftJobObligationsAssessmentSchema = DraftJobObligationsAssessmentBodySchem
4930
5954
  });
4931
5955
 
4932
5956
  // ../schemas/src/draft-artifact-lint.ts
4933
- var id10 = DraftApplicationScopeSchema.shape.authorityId;
4934
- var digest26 = DraftJobReceiptSchema.shape.receiptDigest;
5957
+ var id12 = DraftApplicationScopeSchema.shape.authorityId;
5958
+ var digest27 = DraftJobReceiptSchema.shape.receiptDigest;
4935
5959
  var passage3 = ArtifactSpecificationSchema;
4936
- var plainArtifact = z54.strictObject({
4937
- id: id10,
4938
- revision: id10,
4939
- mediaType: z54.literal("text/plain"),
4940
- exportProfile: id10.nullable(),
4941
- content: z54.string().max(artifactLintLimits.maxTotalBytes),
4942
- expectedContentDigest: digest26
4943
- });
4944
- var structuredArtifact = z54.strictObject({
4945
- id: id10,
4946
- revision: id10,
4947
- mediaType: z54.literal("application/vnd.felspar.structured-output+json"),
4948
- exportProfile: id10.nullable(),
5960
+ var plainArtifact = z61.strictObject({
5961
+ id: id12,
5962
+ revision: id12,
5963
+ mediaType: z61.literal("text/plain"),
5964
+ exportProfile: id12.nullable(),
5965
+ content: z61.string().max(artifactLintLimits.maxTotalBytes),
5966
+ expectedContentDigest: digest27
5967
+ });
5968
+ var structuredArtifact = z61.strictObject({
5969
+ id: id12,
5970
+ revision: id12,
5971
+ mediaType: z61.literal("application/vnd.felspar.structured-output+json"),
5972
+ exportProfile: id12.nullable(),
4949
5973
  content: DraftStructuredOutputSchema,
4950
- expectedContentDigest: digest26
5974
+ expectedContentDigest: digest27
4951
5975
  });
4952
- var ArtifactLintArtifactSchema = z54.discriminatedUnion("mediaType", [
5976
+ var ArtifactLintArtifactSchema = z61.discriminatedUnion("mediaType", [
4953
5977
  plainArtifact,
4954
5978
  structuredArtifact
4955
5979
  ]);
4956
- var ArtifactLintDecisionSchema = z54.strictObject({
5980
+ var ArtifactLintDecisionSchema = z61.strictObject({
4957
5981
  inputs: DraftJobObligationsInputSchema,
4958
5982
  assessment: DraftJobObligationsAssessmentSchema,
4959
- expectedAssessmentDigest: digest26
5983
+ expectedAssessmentDigest: digest27
4960
5984
  });
4961
- var ArtifactLintInputSchema = z54.strictObject({
4962
- schema: z54.literal("felspar.lint.draft/v1"),
4963
- requestId: id10,
5985
+ var ArtifactLintInputSchema = z61.strictObject({
5986
+ schema: z61.literal("felspar.lint.draft/v1"),
5987
+ requestId: id12,
4964
5988
  release: DraftApplicationReleaseSchema,
4965
5989
  material: DraftApplicationJobMaterialV3Schema,
4966
5990
  manifest: ArtifactCheckManifestSchema,
4967
- expectedManifestDigest: digest26,
4968
- attachedObligations: z54.strictObject({ expectedObligationsDigest: digest26 }).optional(),
4969
- attachedCase: z54.strictObject({
4970
- decisionReceiptDigest: digest26,
4971
- answers: z54.array(z54.strictObject({ key: id10, value: z54.union([z54.string().min(1).max(200), z54.null()]) })).max(256)
5991
+ expectedManifestDigest: digest27,
5992
+ attachedObligations: z61.strictObject({ expectedObligationsDigest: digest27 }).optional(),
5993
+ attachedCase: z61.strictObject({
5994
+ decisionReceiptDigest: digest27,
5995
+ answers: z61.array(z61.strictObject({ key: id12, value: z61.union([z61.string().min(1).max(200), z61.null()]) })).max(256)
4972
5996
  }).optional(),
4973
- case: z54.strictObject({ caseId: id10, purposeRef: id10, useRef: id10.nullable() }),
4974
- artifactRequirementId: id10.nullable(),
5997
+ case: z61.strictObject({ caseId: id12, purposeRef: id12, useRef: id12.nullable() }),
5998
+ artifactRequirementId: id12.nullable(),
4975
5999
  decision: ArtifactLintDecisionSchema.nullable(),
4976
6000
  artifact: ArtifactLintArtifactSchema
4977
6001
  });
@@ -4984,11 +6008,11 @@ var artifactCheckStatuses = [
4984
6008
  "not_applicable",
4985
6009
  "skipped"
4986
6010
  ];
4987
- var range = z54.strictObject({
4988
- sectionId: id10,
4989
- start: z54.number().int().min(0).max(artifactLintLimits.maxSectionUnits),
4990
- end: z54.number().int().min(1).max(artifactLintLimits.maxSectionUnits),
4991
- offsetUnit: z54.literal("utf16_code_units")
6011
+ var range = z61.strictObject({
6012
+ sectionId: id12,
6013
+ start: z61.number().int().min(0).max(artifactLintLimits.maxSectionUnits),
6014
+ end: z61.number().int().min(1).max(artifactLintLimits.maxSectionUnits),
6015
+ offsetUnit: z61.literal("utf16_code_units")
4992
6016
  });
4993
6017
  var findingCodes = [
4994
6018
  "section_missing",
@@ -5009,6 +6033,7 @@ var findingCodes = [
5009
6033
  "semantic_violation",
5010
6034
  "semantic_missing",
5011
6035
  "semantic_unresolved",
6036
+ "possible_prompt_injection",
5012
6037
  "case_answer_conflict",
5013
6038
  "case_answer_missing",
5014
6039
  "case_answer_unconfirmed",
@@ -5016,148 +6041,148 @@ var findingCodes = [
5016
6041
  "evaluation_budget_exceeded",
5017
6042
  "evaluation_skipped"
5018
6043
  ];
5019
- var ArtifactFindingSchema = z54.strictObject({
5020
- code: z54.enum(findingCodes),
5021
- checkId: id10.nullable(),
5022
- severity: z54.enum(["error", "warning"]),
6044
+ var ArtifactFindingSchema = z61.strictObject({
6045
+ code: z61.enum(findingCodes),
6046
+ checkId: id12.nullable(),
6047
+ severity: z61.enum(["error", "warning"]),
5023
6048
  specification: passage3.nullable(),
5024
6049
  location: range.nullable(),
5025
- insertionAnchor: z54.strictObject({ sectionId: id10.nullable(), at: z54.number().int().min(0) }).nullable(),
5026
- literalIndex: z54.number().int().min(0).max(artifactLintLimits.maxLiterals).nullable()
5027
- });
5028
- var ArtifactCheckObservationSchema = z54.strictObject({
5029
- checkId: id10,
5030
- kind: z54.enum(artifactCheckKinds),
5031
- required: z54.boolean(),
5032
- method: z54.enum(["deterministic", "semantic"]),
5033
- status: z54.enum(artifactCheckStatuses),
5034
- occurrences: z54.number().int().min(0),
5035
- parsedValue: z54.number().nullable(),
5036
- caseValue: z54.number().nullable()
5037
- });
5038
- var ArtifactLintRecordBodySchema = z54.strictObject({
5039
- schema: z54.literal("felspar.lint-record.draft/v1"),
5040
- requestId: id10,
5041
- status: z54.enum(["pass", "revise", "unavailable", "review_required"]),
5042
- caseContext: z54.enum(["bound", "not_required"]),
5043
- binding: z54.strictObject({
6050
+ insertionAnchor: z61.strictObject({ sectionId: id12.nullable(), at: z61.number().int().min(0) }).nullable(),
6051
+ literalIndex: z61.number().int().min(0).max(artifactLintLimits.maxLiterals).nullable()
6052
+ });
6053
+ var ArtifactCheckObservationSchema = z61.strictObject({
6054
+ checkId: id12,
6055
+ kind: z61.enum(artifactCheckKinds),
6056
+ required: z61.boolean(),
6057
+ method: z61.enum(["deterministic", "semantic"]),
6058
+ status: z61.enum(artifactCheckStatuses),
6059
+ occurrences: z61.number().int().min(0),
6060
+ parsedValue: z61.number().nullable(),
6061
+ caseValue: z61.number().nullable()
6062
+ });
6063
+ var ArtifactLintRecordBodySchema = z61.strictObject({
6064
+ schema: z61.literal("felspar.lint-record.draft/v1"),
6065
+ requestId: id12,
6066
+ status: z61.enum(["pass", "revise", "unavailable", "review_required"]),
6067
+ caseContext: z61.enum(["bound", "not_required"]),
6068
+ binding: z61.strictObject({
5044
6069
  scope: DraftApplicationScopeSchema,
5045
- releaseId: id10,
5046
- releaseDigest: digest26,
5047
- materialDigest: digest26,
5048
- obligationsDigest: digest26.optional(),
5049
- caseFactsDigest: digest26.optional(),
5050
- jobId: id10,
5051
- manifestId: id10,
5052
- manifestDigest: digest26,
5053
- contract: z54.strictObject({ id: id10, digest: digest26 }),
5054
- caseId: id10,
5055
- purposeRef: id10,
5056
- useRef: id10.nullable(),
5057
- artifactRequirementId: id10.nullable(),
5058
- decisionReceiptDigest: digest26.nullable(),
5059
- obligationsAssessmentDigest: digest26.nullable()
6070
+ releaseId: id12,
6071
+ releaseDigest: digest27,
6072
+ materialDigest: digest27,
6073
+ obligationsDigest: digest27.optional(),
6074
+ caseFactsDigest: digest27.optional(),
6075
+ jobId: id12,
6076
+ manifestId: id12,
6077
+ manifestDigest: digest27,
6078
+ contract: z61.strictObject({ id: id12, digest: digest27 }),
6079
+ caseId: id12,
6080
+ purposeRef: id12,
6081
+ useRef: id12.nullable(),
6082
+ artifactRequirementId: id12.nullable(),
6083
+ decisionReceiptDigest: digest27.nullable(),
6084
+ obligationsAssessmentDigest: digest27.nullable()
5060
6085
  }),
5061
- artifact: z54.strictObject({
5062
- id: id10,
5063
- revision: id10,
5064
- mediaType: z54.enum(artifactLintMediaTypes),
5065
- exportProfile: id10.nullable(),
5066
- contentDigest: digest26,
5067
- sections: z54.array(z54.strictObject({
5068
- id: id10,
5069
- units: z54.number().int().min(0),
5070
- contentDigest: digest26.nullable()
6086
+ artifact: z61.strictObject({
6087
+ id: id12,
6088
+ revision: id12,
6089
+ mediaType: z61.enum(artifactLintMediaTypes),
6090
+ exportProfile: id12.nullable(),
6091
+ contentDigest: digest27,
6092
+ sections: z61.array(z61.strictObject({
6093
+ id: id12,
6094
+ units: z61.number().int().min(0),
6095
+ contentDigest: digest27.nullable()
5071
6096
  })).max(artifactLintLimits.maxSections)
5072
6097
  }),
5073
- checks: z54.array(ArtifactCheckObservationSchema).max(artifactLintLimits.maxChecks),
5074
- findings: z54.array(ArtifactFindingSchema).max(2048),
6098
+ checks: z61.array(ArtifactCheckObservationSchema).max(artifactLintLimits.maxChecks),
6099
+ findings: z61.array(ArtifactFindingSchema).max(2048),
5075
6100
  semantic: ArtifactSemanticRecordSchema.nullable(),
5076
- coverage: z54.strictObject({
5077
- scope: z54.literal("declared_checks_only"),
5078
- declared: z54.number().int().min(0),
5079
- applicable: z54.number().int().min(0),
5080
- completed: z54.number().int().min(0),
5081
- required: z54.number().int().min(0),
5082
- requiredCompleted: z54.number().int().min(0),
5083
- textAssigned: z54.enum(["complete", "incomplete"]),
5084
- semantic: z54.enum(["not_declared", "complete", "incomplete"]),
5085
- nativeDocumentLayout: z54.literal("not_checked")
6101
+ coverage: z61.strictObject({
6102
+ scope: z61.literal("declared_checks_only"),
6103
+ declared: z61.number().int().min(0),
6104
+ applicable: z61.number().int().min(0),
6105
+ completed: z61.number().int().min(0),
6106
+ required: z61.number().int().min(0),
6107
+ requiredCompleted: z61.number().int().min(0),
6108
+ textAssigned: z61.enum(["complete", "incomplete"]),
6109
+ semantic: z61.enum(["not_declared", "complete", "incomplete"]),
6110
+ nativeDocumentLayout: z61.literal("not_checked")
5086
6111
  }),
5087
- actionAuthorized: z54.literal(false)
6112
+ actionAuthorized: z61.literal(false)
5088
6113
  });
5089
6114
  var ArtifactLintRecordSchema = ArtifactLintRecordBodySchema.extend({
5090
- recordDigest: digest26
5091
- });
5092
- var ArtifactLintReceiptSchema = z54.strictObject({
5093
- schema: z54.literal("felspar.lint-receipt.draft/v1"),
5094
- recordDigest: digest26,
5095
- releaseDigest: digest26,
5096
- manifestDigest: digest26,
5097
- contractDigest: digest26,
5098
- caseId: id10,
5099
- caseContext: z54.enum(["bound", "not_required"]),
5100
- decisionReceiptDigest: digest26.nullable(),
5101
- obligationsAssessmentDigest: digest26.nullable(),
5102
- artifactId: id10,
5103
- artifactRevision: id10,
5104
- artifactDigest: digest26,
5105
- actionAuthorized: z54.literal(false),
5106
- receiptDigest: digest26
6115
+ recordDigest: digest27
6116
+ });
6117
+ var ArtifactLintReceiptSchema = z61.strictObject({
6118
+ schema: z61.literal("felspar.lint-receipt.draft/v1"),
6119
+ recordDigest: digest27,
6120
+ releaseDigest: digest27,
6121
+ manifestDigest: digest27,
6122
+ contractDigest: digest27,
6123
+ caseId: id12,
6124
+ caseContext: z61.enum(["bound", "not_required"]),
6125
+ decisionReceiptDigest: digest27.nullable(),
6126
+ obligationsAssessmentDigest: digest27.nullable(),
6127
+ artifactId: id12,
6128
+ artifactRevision: id12,
6129
+ artifactDigest: digest27,
6130
+ actionAuthorized: z61.literal(false),
6131
+ receiptDigest: digest27
5107
6132
  });
5108
6133
 
5109
6134
  // ../schemas/src/draft-hosted-output-check-record.ts
5110
- var id11 = DraftApplicationScopeSchema.shape.authorityId;
5111
- var digest27 = DraftJobReceiptSchema.shape.receiptDigest;
5112
- var HostedOutputCheckInputSchema = z55.strictObject({
5113
- executionId: id11,
5114
- output: id11.optional(),
5115
- text: z55.string().min(1).max(artifactLintLimits.maxTotalBytes).refine(isWellFormedText, "text_not_well_formed"),
5116
- revision: id11.optional()
5117
- });
5118
- var HostedOutputCheckRecordSchema = z55.strictObject({
5119
- schema: z55.literal("felspar.hosted-output-check/v0"),
5120
- checkId: id11,
5121
- jobId: id11,
5122
- output: id11,
5123
- decision: z55.strictObject({ executionId: id11, outcome: id11, receiptDigest: digest27 }),
5124
- release: z55.strictObject({ releaseId: id11, releaseDigest: digest27 }),
6135
+ var id13 = DraftApplicationScopeSchema.shape.authorityId;
6136
+ var digest28 = DraftJobReceiptSchema.shape.receiptDigest;
6137
+ var HostedOutputCheckInputSchema = z62.strictObject({
6138
+ executionId: id13,
6139
+ output: id13.optional(),
6140
+ text: z62.string().min(1).max(artifactLintLimits.maxTotalBytes).refine(isWellFormedText, "text_not_well_formed"),
6141
+ revision: id13.optional()
6142
+ });
6143
+ var HostedOutputCheckRecordSchema = z62.strictObject({
6144
+ schema: z62.literal("felspar.hosted-output-check/v0"),
6145
+ checkId: id13,
6146
+ jobId: id13,
6147
+ output: id13,
6148
+ decision: z62.strictObject({ executionId: id13, outcome: id13, receiptDigest: digest28 }),
6149
+ release: z62.strictObject({ releaseId: id13, releaseDigest: digest28 }),
5125
6150
  record: ArtifactLintRecordSchema,
5126
6151
  receipt: ArtifactLintReceiptSchema.nullable(),
5127
- evaluation: z55.strictObject({
5128
- modelCalls: z55.number().int().min(0),
5129
- reason: z55.string().regex(/^[a-z][a-z_]{2,63}$/u).nullable()
6152
+ evaluation: z62.strictObject({
6153
+ modelCalls: z62.number().int().min(0),
6154
+ reason: z62.string().regex(/^[a-z][a-z_]{2,63}$/u).nullable()
5130
6155
  })
5131
6156
  });
5132
6157
 
5133
6158
  // src/draft-hosted-client.ts
5134
- import { z as z56 } from "zod";
5135
- var digestText = z56.string().regex(/^sha256:[a-f0-9]{64}$/u);
5136
- var HostedOutputCheckReplySchema = z56.object({
5137
- status: z56.enum(["pass", "revise", "review_required", "unavailable"]),
5138
- checkId: z56.string(),
5139
- output: z56.string(),
5140
- findings: z56.array(z56.record(z56.string(), z56.unknown())),
5141
- receipt: z56.object({ receiptDigest: digestText, artifactDigest: digestText }).loose().nullable(),
5142
- decision: z56.object({ executionId: z56.string(), receiptDigest: digestText }),
5143
- actionAuthorized: z56.literal(false)
6159
+ import { z as z63 } from "zod";
6160
+ var digestText = z63.string().regex(/^sha256:[a-f0-9]{64}$/u);
6161
+ var HostedOutputCheckReplySchema = z63.object({
6162
+ status: z63.enum(["pass", "revise", "review_required", "unavailable"]),
6163
+ checkId: z63.string(),
6164
+ output: z63.string(),
6165
+ findings: z63.array(z63.record(z63.string(), z63.unknown())),
6166
+ receipt: z63.object({ receiptDigest: digestText, artifactDigest: digestText }).loose().nullable(),
6167
+ decision: z63.object({ executionId: z63.string(), receiptDigest: digestText }),
6168
+ actionAuthorized: z63.literal(false)
5144
6169
  }).loose();
5145
- var quotedWords = z56.object({ text: z56.string() }).loose();
5146
- var FelsparCaseSchema = z56.object({ id: z56.string().min(1).max(200), mode: z56.enum(identityModes) });
5147
- var FelsparRelatedSchema = z56.object({
5148
- relationship: z56.string(),
5149
- subject: z56.string(),
5150
- id: z56.string(),
5151
- questions: z56.array(z56.string())
5152
- });
5153
- var FelsparResultSubjectSchema = z56.object({
5154
- type: z56.string(),
5155
- id: z56.string(),
5156
- related: z56.array(FelsparRelatedSchema)
5157
- });
5158
- var FelsparEscalationSchema = z56.object({
5159
- id: z56.string().min(1).max(200),
5160
- trigger: z56.enum(escalationTriggers),
6170
+ var quotedWords = z63.object({ text: z63.string() }).loose();
6171
+ var FelsparCaseSchema = z63.object({ id: z63.string().min(1).max(200), mode: z63.enum(identityModes) });
6172
+ var FelsparRelatedSchema = z63.object({
6173
+ relationship: z63.string(),
6174
+ subject: z63.string(),
6175
+ id: z63.string(),
6176
+ questions: z63.array(z63.string())
6177
+ });
6178
+ var FelsparResultSubjectSchema = z63.object({
6179
+ type: z63.string(),
6180
+ id: z63.string(),
6181
+ related: z63.array(FelsparRelatedSchema)
6182
+ });
6183
+ var FelsparEscalationSchema = z63.object({
6184
+ id: z63.string().min(1).max(200),
6185
+ trigger: z63.enum(escalationTriggers),
5161
6186
  why: quotedWords
5162
6187
  });
5163
6188
  var FelsparJobResultSchema = HostedJobResultSchema.extend({
@@ -5165,25 +6190,25 @@ var FelsparJobResultSchema = HostedJobResultSchema.extend({
5165
6190
  case: FelsparCaseSchema.optional(),
5166
6191
  subject: FelsparResultSubjectSchema.optional(),
5167
6192
  escalation: FelsparEscalationSchema.optional(),
5168
- missing: z56.array(z56.string()).optional()
6193
+ missing: z63.array(z63.string()).optional()
5169
6194
  }).nullable()
5170
6195
  });
5171
- var FelsparJobListSchema = z56.object({
5172
- jobs: z56.array(z56.object({ id: z56.string().min(1).max(200) })).max(256)
6196
+ var FelsparJobListSchema = z63.object({
6197
+ jobs: z63.array(z63.object({ id: z63.string().min(1).max(200) })).max(256)
5173
6198
  });
5174
6199
  var hostedPartsContentType = "application/x.felspar-content-parts";
5175
- async function partsBody(value) {
5176
- const packed = await packContentParts(value);
6200
+ async function partsBody(value2) {
6201
+ const packed = await packContentParts(value2);
5177
6202
  return packed.text;
5178
6203
  }
5179
- async function factsRequest(value, describeRelease) {
5180
- if (typeof value.expectedReleaseDigest === "string") {
5181
- return HostedFactsRequestSchema.parse({ mode: "facts", ...value });
6204
+ async function factsRequest(value2, describeRelease) {
6205
+ if (typeof value2.expectedReleaseDigest === "string") {
6206
+ return HostedFactsRequestSchema.parse({ mode: "facts", ...value2 });
5182
6207
  }
5183
- const described = await describeRelease(HostedObjectSchema.shape.id.parse(value.jobId));
6208
+ const described = await describeRelease(HostedObjectSchema.shape.id.parse(value2.jobId));
5184
6209
  return HostedFactsRequestSchema.parse({
5185
6210
  mode: "facts",
5186
- ...value,
6211
+ ...value2,
5187
6212
  expectedReleaseDigest: described.release.releaseDigest
5188
6213
  });
5189
6214
  }
@@ -5221,29 +6246,31 @@ ${jobId}`;
5221
6246
  return result;
5222
6247
  };
5223
6248
  }
5224
- var refusalCode = z56.string().regex(/^[a-z][a-z_]{2,63}$/u);
5225
- var fieldPath = z56.array(z56.string().max(256)).max(32);
5226
- var refusalEscalationSchema = z56.object({
5227
- id: z56.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/@-]{0,199}$/u),
5228
- trigger: z56.enum(escalationTriggers),
5229
- why: z56.object({ text: z56.string().max(2e4) })
6249
+ var refusalCode = z63.string().regex(/^[a-z][a-z_]{2,63}$/u);
6250
+ var fieldPath = z63.array(z63.string().max(256)).max(32);
6251
+ var refusalEscalationSchema = z63.object({
6252
+ id: z63.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/@-]{0,199}$/u),
6253
+ trigger: z63.enum(escalationTriggers),
6254
+ why: z63.object({ text: z63.string().max(2e4) })
5230
6255
  });
5231
- var refusalSchema = z56.object({
6256
+ var refusalSchema = z63.object({
5232
6257
  error: refusalCode,
5233
6258
  path: fieldPath.optional(),
5234
- currentReleaseDigest: z56.string().regex(/^sha256:[a-f0-9]{64}$/u).optional(),
5235
- retryAfterSeconds: z56.number().int().min(1).max(3600).optional(),
5236
- escalation: z56.unknown().optional(),
5237
- issues: z56.array(z56.object({ code: refusalCode, path: fieldPath })).max(64).optional()
5238
- }).transform(({ escalation: named, ...value }) => {
5239
- const fix = hostedRefusalFix(value.error);
6259
+ currentReleaseDigest: z63.string().regex(/^sha256:[a-f0-9]{64}$/u).optional(),
6260
+ retryAfterSeconds: z63.number().int().min(1).max(3600).optional(),
6261
+ escalation: z63.unknown().optional(),
6262
+ issues: z63.array(z63.object({ code: refusalCode, path: fieldPath })).max(64).optional()
6263
+ }).transform(({ escalation: named, ...value2 }) => {
6264
+ const fix = hostedRefusalFix(value2.error);
6265
+ const recovery = hostedRefusalRecovery(value2.error);
5240
6266
  const escalation = refusalEscalationSchema.safeParse(named).data;
5241
6267
  return {
5242
- ...value,
6268
+ ...value2,
5243
6269
  ...escalation !== void 0 && { escalation },
5244
6270
  ...fix !== null && { fix },
5245
- ...value.issues && {
5246
- issues: value.issues.map((issue) => {
6271
+ ...recovery !== null && { recovery },
6272
+ ...value2.issues && {
6273
+ issues: value2.issues.map((issue) => {
5247
6274
  const issueFix = hostedRefusalFix(issue.code);
5248
6275
  return issueFix === null ? issue : { ...issue, fix: issueFix };
5249
6276
  })
@@ -5262,8 +6289,8 @@ var FelsparRequestError = class extends Error {
5262
6289
  }
5263
6290
  };
5264
6291
  async function refusalOf(response) {
5265
- const text7 = await response.text();
5266
- const parsed = refusalSchema.safeParse(text7.length <= 65536 ? JSON.parse(text7) : null);
6292
+ const text8 = await response.text();
6293
+ const parsed = refusalSchema.safeParse(text8.length <= 65536 ? JSON.parse(text8) : null);
5267
6294
  return parsed.success ? parsed.data : null;
5268
6295
  }
5269
6296
  async function requestError(response) {
@@ -5287,7 +6314,7 @@ function outputCheckCalls(call) {
5287
6314
  const objectId = HostedObjectSchema.shape.id;
5288
6315
  const checksOf = (job) => `/v0/jobs/${encodeURIComponent(objectId.parse(job))}/output-checks`;
5289
6316
  return {
5290
- checkOutput: async (job, value) => await call(checksOf(job), HostedOutputCheckReplySchema, HostedOutputCheckInputSchema.parse(value)),
6317
+ checkOutput: async (job, value2) => await call(checksOf(job), HostedOutputCheckReplySchema, HostedOutputCheckInputSchema.parse(value2)),
5291
6318
  readOutputCheck: async (job, checkId) => await call(`${checksOf(job)}/${encodeURIComponent(objectId.parse(checkId))}`, HostedOutputCheckReplySchema)
5292
6319
  };
5293
6320
  }
@@ -5295,9 +6322,10 @@ function agentCalls(call) {
5295
6322
  const objectId = HostedObjectSchema.shape.id;
5296
6323
  return {
5297
6324
  listJobs: async () => await call("/v0/jobs", FelsparJobListSchema),
5298
- resolveJob: async (id12, value) => {
5299
- const input = HostedSuppliedJobInputSchema.parse(value);
5300
- const releaseId = objectId.parse(id12);
6325
+ describeCurrentJob: async (job) => await call(`/v0/jobs/${encodeURIComponent(objectId.parse(job))}/brief`, HostedJobDescriptionSchema),
6326
+ resolveJob: async (id14, value2) => {
6327
+ const input = HostedSuppliedJobInputSchema.parse(value2);
6328
+ const releaseId = objectId.parse(id14);
5301
6329
  const path3 = `/v0/releases/${encodeURIComponent(releaseId)}/jobs`;
5302
6330
  return pinnedResult(await call(path3, FelsparJobResultSchema, input), releaseId, input);
5303
6331
  }
@@ -5318,14 +6346,14 @@ function createHostedFelsparClient(configuration) {
5318
6346
  }
5319
6347
  const authorization = authorizationOf(configuration);
5320
6348
  const fetcher = configuration.fetcher ?? fetch;
5321
- async function call(path3, schema, value) {
6349
+ async function call(path3, schema, value2) {
5322
6350
  const headers = new Headers(authorization === null ? {} : { Authorization: authorization });
5323
- const body = value === void 0 ? void 0 : await partsBody(value);
6351
+ const body = value2 === void 0 ? void 0 : await partsBody(value2);
5324
6352
  if (body !== void 0) {
5325
6353
  headers.set("Content-Type", hostedPartsContentType);
5326
6354
  }
5327
6355
  const response = await fetcher(`${origin.origin}${path3}`, {
5328
- method: value === void 0 ? "GET" : "POST",
6356
+ method: value2 === void 0 ? "GET" : "POST",
5329
6357
  headers,
5330
6358
  credentials: "include",
5331
6359
  redirect: "error",
@@ -5340,19 +6368,19 @@ function createHostedFelsparClient(configuration) {
5340
6368
  const objectId = HostedObjectSchema.shape.id;
5341
6369
  const describe = jobDescriber(async (releaseId, jobId) => await call(describePath(releaseId, jobId), HostedJobDescriptionSchema));
5342
6370
  return {
5343
- submitSource: async (value) => await call("/v0/sources", HostedObjectSchema, HostedSourceInputSchema.parse(value)),
5344
- submitProposal: async (value) => await call("/v0/proposals", HostedObjectSchema, HostedProposalInputSchema.parse(value)),
5345
- approveProposal: async (id12, value) => await call(`/v0/proposals/${encodeURIComponent(objectId.parse(id12))}/approve`, HostedObjectSchema, HostedApprovalInputSchema.parse(value)),
5346
- releasePack: async (id12, value) => await call(`/v0/approvals/${encodeURIComponent(objectId.parse(id12))}/release`, DraftApplicationReleaseSchema, HostedReleaseInputSchema.parse(value)),
5347
- loadRelease: async (id12) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id12))}`, HostedReleaseBundleSchema),
5348
- describeJob: async (id12, job) => await describe(objectId.parse(id12), objectId.parse(job)),
5349
- verifyReceipt: async (executionObjectId, value) => await call(`/v0/executions/${encodeURIComponent(objectId.parse(executionObjectId))}/verify`, HostedReceiptVerificationSchema, HostedReceiptVerificationInputSchema.parse(value)),
6371
+ submitSource: async (value2) => await call("/v0/sources", HostedObjectSchema, HostedSourceInputSchema.parse(value2)),
6372
+ submitProposal: async (value2) => await call("/v0/proposals", HostedObjectSchema, HostedProposalInputSchema.parse(value2)),
6373
+ approveProposal: async (id14, value2) => await call(`/v0/proposals/${encodeURIComponent(objectId.parse(id14))}/approve`, HostedObjectSchema, HostedApprovalInputSchema.parse(value2)),
6374
+ releasePack: async (id14, value2) => await call(`/v0/approvals/${encodeURIComponent(objectId.parse(id14))}/release`, DraftApplicationReleaseSchema, HostedReleaseInputSchema.parse(value2)),
6375
+ loadRelease: async (id14) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id14))}`, HostedReleaseBundleSchema),
6376
+ describeJob: async (id14, job) => await describe(objectId.parse(id14), objectId.parse(job)),
6377
+ verifyReceipt: async (executionObjectId, value2) => await call(`/v0/executions/${encodeURIComponent(objectId.parse(executionObjectId))}/verify`, HostedReceiptVerificationSchema, HostedReceiptVerificationInputSchema.parse(value2)),
5350
6378
  ...outputCheckCalls(call),
5351
- executeJob: async (id12, value) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id12))}/jobs`, HostedJobResultSchema, HostedJobInputSchema.parse(value)),
6379
+ executeJob: async (id14, value2) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id14))}/jobs`, HostedJobResultSchema, HostedJobInputSchema.parse(value2)),
5352
6380
  ...agentCalls(call),
5353
- resolveFacts: async (id12, value) => {
5354
- const releaseId = objectId.parse(id12);
5355
- const input = await factsRequest(value, async (jobId) => await describe(releaseId, jobId));
6381
+ resolveFacts: async (id14, value2) => {
6382
+ const releaseId = objectId.parse(id14);
6383
+ const input = await factsRequest(value2, async (jobId) => await describe(releaseId, jobId));
5356
6384
  const path3 = `/v0/releases/${encodeURIComponent(releaseId)}/jobs`;
5357
6385
  return pinnedResult(await call(path3, FelsparJobResultSchema, input), releaseId, input);
5358
6386
  }