@felspar/sdk 0.4.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() });
@@ -316,8 +316,8 @@ async function sha256(text8) {
316
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,8 +483,8 @@ 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);
@@ -495,7 +495,7 @@ async function packContentParts(value) {
495
495
  const storedBytes = utf8(text8);
496
496
  admitStored(parts.length, storedBytes);
497
497
  return {
498
- digest: digest28,
498
+ digest: digest29,
499
499
  text: text8,
500
500
  parts: parts.length,
501
501
  storedBytes,
@@ -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);
@@ -1286,7 +1286,7 @@ function isGuardImplied(guard, clause) {
1286
1286
  const allowed = choiceValues(guard);
1287
1287
  const values = choiceValues(clause);
1288
1288
  const isSameKey = clause.key === guard.key;
1289
- return isSameKey && values.length > 0 && values.every((value) => allowed.includes(value));
1289
+ return isSameKey && values.length > 0 && values.every((value2) => allowed.includes(value2));
1290
1290
  }
1291
1291
  function isPolicyValid(proposal, context3) {
1292
1292
  const clauses2 = [
@@ -1534,7 +1534,7 @@ function inspectScoredPolicy(proposal, context3) {
1534
1534
  }
1535
1535
  inspectScoringReferences(scoring, proposal.requirements, context3);
1536
1536
  const ids3 = new Set(rules2.map((rule3) => rule3.id));
1537
- if (gates.some((id13) => !ids3.has(id13))) {
1537
+ if (gates.some((id14) => !ids3.has(id14))) {
1538
1538
  fail("Unknown mandatory gate rule");
1539
1539
  }
1540
1540
  if (rules2.every((rule3) => gates.includes(rule3.id))) {
@@ -1547,7 +1547,7 @@ function inspectScoredPolicy(proposal, context3) {
1547
1547
  if (isGate ? hasRange || rule3.when.length === 0 : !hasRange) {
1548
1548
  fail("Mandatory gates require fact predicates only; other rules require score ranges");
1549
1549
  }
1550
- if (rule3.overrides.some((id13) => gates.includes(id13) !== isGate)) {
1550
+ if (rule3.overrides.some((id14) => gates.includes(id14) !== isGate)) {
1551
1551
  fail("Explicit overrides cannot cross mandatory-gate and score-band classes");
1552
1552
  }
1553
1553
  const range2 = rule3.scoreRange;
@@ -1569,6 +1569,7 @@ function areScoredRulesDisjoint(proposal, left, right) {
1569
1569
 
1570
1570
  // ../schemas/src/draft-required-decision.ts
1571
1571
  var typedResolutionPolicy = "strict-required-types/direct-overrides/v2";
1572
+ var valueAgreementOutcomeRegions = "outcome-regions";
1572
1573
  var identifier8 = DraftEvidenceScopeSchema.shape.entityId;
1573
1574
  var duplicateIdentity = "Duplicate identity";
1574
1575
  var uniqueIds = z15.array(identifier8).max(64).refine(hasUniqueValues, duplicateIdentity);
@@ -1611,7 +1612,8 @@ var shape = z15.strictObject({
1611
1612
  }),
1612
1613
  scope: z15.strictObject({
1613
1614
  entityId: identifier8,
1614
- evaluationTime: DraftObservationChecksSchema.shape.evaluationTime
1615
+ evaluationTime: DraftObservationChecksSchema.shape.evaluationTime,
1616
+ valueAgreement: z15.literal(valueAgreementOutcomeRegions).optional()
1615
1617
  }),
1616
1618
  evidence: z15.array(DraftEvidenceValidationSchema).max(64)
1617
1619
  });
@@ -1631,23 +1633,44 @@ function draftRulePriority(ranked) {
1631
1633
  function hasDraftRulePrecedence(winner, other) {
1632
1634
  return winner.overrides.includes(other.id) || draftRulePriority(winner) > draftRulePriority(other);
1633
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
+ }
1634
1657
  function hasCycle(rules2) {
1635
1658
  const graph = new Map(rules2.map((item) => [item.id, item.overrides]));
1636
1659
  const visiting = /* @__PURE__ */ new Set();
1637
1660
  const visited = /* @__PURE__ */ new Set();
1638
- const hasPathCycle = (id13) => {
1639
- if (visiting.has(id13)) {
1661
+ const hasPathCycle = (id14) => {
1662
+ if (visiting.has(id14)) {
1640
1663
  return true;
1641
1664
  }
1642
- if (visited.has(id13)) {
1665
+ if (visited.has(id14)) {
1643
1666
  return false;
1644
1667
  }
1645
- visiting.add(id13);
1646
- if ((graph.get(id13) ?? []).some(hasPathCycle)) {
1668
+ visiting.add(id14);
1669
+ if ((graph.get(id14) ?? []).some(hasPathCycle)) {
1647
1670
  return true;
1648
1671
  }
1649
- visiting.delete(id13);
1650
- visited.add(id13);
1672
+ visiting.delete(id14);
1673
+ visited.add(id14);
1651
1674
  return false;
1652
1675
  };
1653
1676
  return rules2.some((item) => hasPathCycle(item.id));
@@ -1656,7 +1679,7 @@ function inspectRules(proposal, context3) {
1656
1679
  const { rules: rules2, requirements: requirements3, allowedOutcomes } = proposal;
1657
1680
  const definitions = new Map(requirements3.map((item) => [item.definition.key, item.definition]));
1658
1681
  const ids3 = new Set(rules2.map((item) => item.id));
1659
- const byId = new Map(rules2.map((entry2) => [entry2.id, entry2]));
1682
+ const byId = new Map(rules2.map((entry3) => [entry3.id, entry3]));
1660
1683
  for (const [index, item] of rules2.entries()) {
1661
1684
  const fail = (message) => {
1662
1685
  context3.addIssue({
@@ -1676,22 +1699,22 @@ function inspectRules(proposal, context3) {
1676
1699
  fail("Undeclared condition key or value");
1677
1700
  }
1678
1701
  }
1679
- if (item.overrides.some((id13) => id13 === item.id || !ids3.has(id13))) {
1702
+ if (item.overrides.some((id14) => id14 === item.id || !ids3.has(id14))) {
1680
1703
  fail("Unknown or self override");
1681
1704
  }
1682
- if (item.overrides.some((id13) => {
1683
- const target = byId.get(id13);
1684
- 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);
1685
1708
  })) {
1686
1709
  fail("Override points to a higher priority tier");
1687
1710
  }
1688
- const laterRules = rules2.slice(index + 1);
1689
- for (const other of laterRules) {
1690
- const isContradictory = item.outcome !== other.outcome && !areScoredRulesDisjoint(proposal, item, other) && hasOverlap(item, other, definitions);
1691
- if (isContradictory && !hasDraftRulePrecedence(item, other) && !hasDraftRulePrecedence(other, item)) {
1692
- fail("Overlapping contradictory rules require a direct override");
1693
- }
1694
- }
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
+ });
1695
1718
  }
1696
1719
  if (hasCycle(rules2)) {
1697
1720
  context3.addIssue({ code: "custom", path: ["rules"], message: "Override cycle" });
@@ -1817,26 +1840,26 @@ function unique2(values, context3, path3) {
1817
1840
  }
1818
1841
  function checkObservations(candidate2, context3) {
1819
1842
  const { authority, observations } = candidate2;
1820
- unique2(observations.map((entry2) => entry2.id), context3, ["observations"]);
1821
- for (const [index, entry2] of observations.entries()) {
1843
+ unique2(observations.map((entry3) => entry3.id), context3, ["observations"]);
1844
+ for (const [index, entry3] of observations.entries()) {
1822
1845
  const at = ["observations", index];
1823
- requireBinding2(entry2.key === authority.definition.key, context3, {
1846
+ requireBinding2(entry3.key === authority.definition.key, context3, {
1824
1847
  path: [...at, "key"],
1825
1848
  message: unknownDefinition2
1826
1849
  });
1827
- requireBinding2(authority.definition.allowedValues.includes(entry2.value), context3, {
1850
+ requireBinding2(authority.definition.allowedValues.includes(entry3.value), context3, {
1828
1851
  path: [...at, "value"],
1829
1852
  message: "Unknown definition value"
1830
1853
  });
1831
- requireBinding2(entry2.definitionDigest === authority.definition.contentDigest, context3, {
1854
+ requireBinding2(entry3.definitionDigest === authority.definition.contentDigest, context3, {
1832
1855
  path: [...at, "definitionDigest"],
1833
1856
  message: "Definition fingerprint mismatch"
1834
1857
  });
1835
- requireBinding2(entry2.evidence.entityId === candidate2.entityId, context3, {
1858
+ requireBinding2(entry3.evidence.entityId === candidate2.entityId, context3, {
1836
1859
  path: [...at, "evidence", "entityId"],
1837
1860
  message: "Evidence belongs to a different entity"
1838
1861
  });
1839
- requireBinding2(Date.parse(entry2.observedAt) <= Date.parse(candidate2.evaluatedAt), context3, {
1862
+ requireBinding2(Date.parse(entry3.observedAt) <= Date.parse(candidate2.evaluatedAt), context3, {
1840
1863
  path: [...at, "observedAt"],
1841
1864
  message: "Observation is later than evaluation"
1842
1865
  });
@@ -1852,9 +1875,9 @@ function checkExpected(candidate2, context3) {
1852
1875
  return;
1853
1876
  }
1854
1877
  unique2(result.observationIds, context3, ["expected", "observationIds"]);
1855
- const observationIds = new Set(candidate2.observations.map((entry2) => entry2.id));
1856
- for (const [index, id13] of result.observationIds.entries()) {
1857
- requireBinding2(observationIds.has(id13), 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, {
1858
1881
  path: ["expected", "observationIds", index],
1859
1882
  message: "Unknown observation"
1860
1883
  });
@@ -1866,7 +1889,7 @@ function checkExpected(candidate2, context3) {
1866
1889
  path: ["expected", "outcome"],
1867
1890
  message: "Unknown outcome"
1868
1891
  });
1869
- 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" });
1870
1893
  }
1871
1894
  var DraftDecisionCaseSchema = shape2.superRefine((candidate2, context3) => {
1872
1895
  checkObservations(candidate2, context3);
@@ -1994,10 +2017,10 @@ var expectation = z19.strictObject({
1994
2017
  status: z19.enum(["ready", "blocked", "review_required", "stale", "conflict", "gap"]),
1995
2018
  outcome: identifier11.nullable(),
1996
2019
  selectedRuleIds: z19.array(identifier11).max(256).refine(hasUniqueValues, "Duplicate rule identity")
1997
- }).superRefine((value, context3) => {
1998
- const hasOutcome = value.outcome !== null;
1999
- const hasRules = value.selectedRuleIds.length > 0;
2000
- 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";
2001
2024
  if (isReady ? !hasOutcome || !hasRules : hasOutcome || hasRules) {
2002
2025
  context3.addIssue({
2003
2026
  code: "custom",
@@ -2014,9 +2037,22 @@ var DraftEvidenceFixtureSchema = z19.strictObject({
2014
2037
  ...fixtureIdentity,
2015
2038
  evidence: DraftRequiredDecisionSchema.shape.evidence
2016
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
+ });
2017
2053
  var DraftFactFixtureSchema = z19.strictObject({
2018
2054
  ...fixtureIdentity,
2019
- 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")
2020
2056
  });
2021
2057
  var DraftAnyCompilationFixtureSchema = z19.union([
2022
2058
  DraftEvidenceFixtureSchema,
@@ -2148,40 +2184,40 @@ function boundedDraftInput(limits2) {
2148
2184
  let nodes = 0;
2149
2185
  let text8 = 0;
2150
2186
  const budgetError = new Error("Draft input budget exceeded or non-data input");
2151
- function copy(value, depth) {
2187
+ function copy(value2, depth) {
2152
2188
  nodes += 1;
2153
2189
  if (nodes > limits2.nodes || depth > maxDepth) {
2154
2190
  throw budgetError;
2155
2191
  }
2156
- if (typeof value === "string") {
2157
- text8 += value.length;
2158
- if (value.length > limits2.stringLength || text8 > limits2.totalText) {
2192
+ if (typeof value2 === "string") {
2193
+ text8 += value2.length;
2194
+ if (value2.length > limits2.stringLength || text8 > limits2.totalText) {
2159
2195
  throw budgetError;
2160
2196
  }
2161
- return value;
2197
+ return value2;
2162
2198
  }
2163
- if (value === null || typeof value !== "object") {
2164
- return value;
2199
+ if (value2 === null || typeof value2 !== "object") {
2200
+ return value2;
2165
2201
  }
2166
- const isArray = Array.isArray(value);
2167
- const prototype = Object.getPrototypeOf(value);
2202
+ const isArray = Array.isArray(value2);
2203
+ const prototype = Object.getPrototypeOf(value2);
2168
2204
  if (prototype !== null && prototype !== (isArray ? Array.prototype : Object.prototype)) {
2169
2205
  throw budgetError;
2170
2206
  }
2171
- if (isArray && value.length > limits2.arrayLength) {
2207
+ if (isArray && value2.length > limits2.arrayLength) {
2172
2208
  throw budgetError;
2173
2209
  }
2174
- const output = isArray ? Array.from({ length: value.length }) : {};
2210
+ const output = isArray ? Array.from({ length: value2.length }) : {};
2175
2211
  let properties = 0;
2176
- for (const key3 in value) {
2177
- if (!Object.hasOwn(value, key3)) {
2212
+ for (const key3 in value2) {
2213
+ if (!Object.hasOwn(value2, key3)) {
2178
2214
  continue;
2179
2215
  }
2180
2216
  properties += 1;
2181
2217
  if (properties > (isArray ? limits2.arrayLength : 32)) {
2182
2218
  throw budgetError;
2183
2219
  }
2184
- const descriptor = Object.getOwnPropertyDescriptor(value, key3);
2220
+ const descriptor = Object.getOwnPropertyDescriptor(value2, key3);
2185
2221
  if (!descriptor || !("value" in descriptor)) {
2186
2222
  throw budgetError;
2187
2223
  }
@@ -2206,7 +2242,7 @@ function boundedDraftInput(limits2) {
2206
2242
  }
2207
2243
  });
2208
2244
  }
2209
- var isUnicodeText = (value) => !/[\uD800-\uDFFF]/u.test(value);
2245
+ var isUnicodeText = (value2) => !/[\uD800-\uDFFF]/u.test(value2);
2210
2246
  var isSplitCharacter = (text8, offset) => offset > 0 && offset < text8.length && /[\uDC00-\uDFFF]/u.test(text8.charAt(offset));
2211
2247
  var sourceText = DraftSourceReferenceSchema.omit({ contentDigest: true }).extend({
2212
2248
  text: z21.string().min(1).max(1048576).refine(isUnicodeText, "Lone Unicode surrogate"),
@@ -2571,22 +2607,22 @@ var DraftPrimitiveMappingSchema = z26.strictObject({
2571
2607
  caseId: id,
2572
2608
  rows: z26.array(row).min(requiredAuthorityPrimitives.length).max(authorityPrimitives.length)
2573
2609
  }).superRefine((mapping, context3) => {
2574
- if (!coversAuthorityPrimitives(mapping.rows.map((entry2) => entry2.primitive))) {
2610
+ if (!coversAuthorityPrimitives(mapping.rows.map((entry3) => entry3.primitive))) {
2575
2611
  context3.addIssue({ code: "custom", path: ["rows"], message: "Every category is explicit" });
2576
2612
  }
2577
2613
  const seen = /* @__PURE__ */ new Set();
2578
- for (const [index, entry2] of mapping.rows.entries()) {
2614
+ for (const [index, entry3] of mapping.rows.entries()) {
2579
2615
  const path3 = ["rows", index];
2580
- if (seen.has(entry2.primitive)) {
2616
+ if (seen.has(entry3.primitive)) {
2581
2617
  context3.addIssue({ code: "custom", path: path3, message: "Duplicate primitive" });
2582
2618
  }
2583
- seen.add(entry2.primitive);
2584
- if (entry2.status !== "mapped") {
2619
+ seen.add(entry3.primitive);
2620
+ if (entry3.status !== "mapped") {
2585
2621
  continue;
2586
2622
  }
2587
2623
  const references = /* @__PURE__ */ new Set();
2588
- for (const [at, ref] of entry2.references.entries()) {
2589
- if (!kinds[entry2.primitive].includes(ref.kind)) {
2624
+ for (const [at, ref] of entry3.references.entries()) {
2625
+ if (!kinds[entry3.primitive].includes(ref.kind)) {
2590
2626
  context3.addIssue({
2591
2627
  code: "custom",
2592
2628
  path: [...path3, "references", at],
@@ -2606,7 +2642,7 @@ var DraftPrimitiveMappingSchema = z26.strictObject({
2606
2642
  }
2607
2643
  });
2608
2644
  function readObservation(input, ref) {
2609
- const index = input.observations.findIndex((entry2) => entry2.id === ref.observationId);
2645
+ const index = input.observations.findIndex((entry3) => entry3.id === ref.observationId);
2610
2646
  const observation2 = input.observations[index];
2611
2647
  if (!observation2) {
2612
2648
  return void 0;
@@ -2642,7 +2678,7 @@ function readReference(input, ref) {
2642
2678
  return { path: "expected", value: input.expected };
2643
2679
  }
2644
2680
  case "rule": {
2645
- const index = authority.rules.findIndex((entry2) => entry2.id === ref.ruleId);
2681
+ const index = authority.rules.findIndex((entry3) => entry3.id === ref.ruleId);
2646
2682
  const rule3 = authority.rules[index];
2647
2683
  return rule3 ? {
2648
2684
  path: `authority.rules.${index}`,
@@ -2671,18 +2707,18 @@ var DraftMappedCaseSchema = z26.strictObject({
2671
2707
  message: "Mapping belongs to a different case"
2672
2708
  });
2673
2709
  }
2674
- for (const [index, entry2] of mapping.rows.entries()) {
2675
- if (entry2.status !== "mapped") {
2710
+ for (const [index, entry3] of mapping.rows.entries()) {
2711
+ if (entry3.status !== "mapped") {
2676
2712
  continue;
2677
2713
  }
2678
- if (entry2.primitive === "gaps" && input.expected.state === "ready") {
2714
+ if (entry3.primitive === "gaps" && input.expected.state === "ready") {
2679
2715
  context3.addIssue({
2680
2716
  code: "custom",
2681
2717
  path: ["mapping", "rows", index],
2682
2718
  message: "Ready expectation cannot demonstrate an unresolved gap or conflict"
2683
2719
  });
2684
2720
  }
2685
- for (const [at, ref] of entry2.references.entries()) {
2721
+ for (const [at, ref] of entry3.references.entries()) {
2686
2722
  if (!readReference(input, ref)) {
2687
2723
  context3.addIssue({
2688
2724
  code: "custom",
@@ -2849,6 +2885,8 @@ var PackDraftBoundSchema = z29.union([
2849
2885
  z29.number(),
2850
2886
  CalendarDateSchema,
2851
2887
  z29.strictObject({ question: draftIdentifier, days: dayOffset }),
2888
+ z29.strictObject({ question: draftIdentifier, businessDays: dayOffset }),
2889
+ z29.strictObject({ question: draftIdentifier }),
2852
2890
  z29.strictObject({ decisionDate: dayOffset })
2853
2891
  ]);
2854
2892
  var PackDraftComparisonSchema = z29.strictObject({
@@ -2858,10 +2896,10 @@ var PackDraftComparisonSchema = z29.strictObject({
2858
2896
  gte: PackDraftBoundSchema.optional(),
2859
2897
  eq: PackDraftBoundSchema.optional(),
2860
2898
  quote: draftQuote
2861
- }).superRefine((value, context3) => {
2862
- const lower = Number(value.gt !== void 0) + Number(value.gte !== void 0);
2863
- const upper = Number(value.lt !== void 0) + Number(value.lte !== void 0);
2864
- 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;
2865
2903
  if (lower + upper + Number(hasEquality) === 0) {
2866
2904
  context3.addIssue({ code: "custom", message: "Give a bound: lt, lte, gt, gte or eq" });
2867
2905
  } else if (lower > 1 || upper > 1) {
@@ -2876,6 +2914,9 @@ var PackDraftConditionSchema = z29.union([
2876
2914
  PackDraftComparisonSchema
2877
2915
  ]);
2878
2916
  var PackDraftConditionsSchema = z29.record(draftIdentifier, PackDraftConditionSchema);
2917
+ function isComparison(condition) {
2918
+ return typeof condition === "object" && !Array.isArray(condition);
2919
+ }
2879
2920
  var questionTypes = ["number", "date"];
2880
2921
  var typedQuestionFields = {
2881
2922
  type: z29.enum(questionTypes).optional(),
@@ -2885,6 +2926,66 @@ var typedQuestionFields = {
2885
2926
  minimum: z29.number().optional(),
2886
2927
  maximum: z29.number().optional()
2887
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
+ }
2888
2989
  var declaredDateOrders = [
2889
2990
  "month-first",
2890
2991
  "day-first"
@@ -2894,7 +2995,51 @@ var packConventionFields = {
2894
2995
  dateOrder: z29.enum(declaredDateOrders).optional(),
2895
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()
2896
2997
  };
2897
- 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
+ });
2898
3043
  var caseDecisionDate = CalendarDateSchema.optional();
2899
3044
 
2900
3045
  // ../schemas/src/draft-pack-subjects.ts
@@ -3017,7 +3162,7 @@ var group = z31.strictObject({
3017
3162
  min: z31.number().int().min(0).max(64),
3018
3163
  max: z31.number().int().min(0).max(64),
3019
3164
  candidates: z31.array(candidate).max(64)
3020
- }).refine((value) => value.min <= value.max, "Group minimum exceeds maximum");
3165
+ }).refine((value2) => value2.min <= value2.max, "Group minimum exceeds maximum");
3021
3166
  function areSubjectsValid(subjects, isIsolated) {
3022
3167
  const types = new Set(subjects.types.map((row2) => row2.id));
3023
3168
  const job = subjects.types.find((row2) => row2.id === subjects.job);
@@ -3038,13 +3183,13 @@ function areSubjectsValid(subjects, isIsolated) {
3038
3183
  function areEscalationsValid(escalations, context3) {
3039
3184
  const { isIsolated, outcomes } = context3;
3040
3185
  const ids3 = new Set(escalations.routes.map((row2) => row2.id));
3041
- const named = [escalations.unresolved, escalations.attemptLimit].filter((id13) => id13 !== null);
3186
+ const named = [escalations.unresolved, escalations.attemptLimit].filter((id14) => id14 !== null);
3042
3187
  return [
3043
3188
  ids3.size === escalations.routes.length,
3044
3189
  escalations.routes.every((row2) => isIsolated(row2.entryId, "routing_jobs")),
3045
3190
  hasUniqueValues(escalations.outcomes.map((row2) => row2.outcome)),
3046
3191
  escalations.outcomes.every((row2) => ids3.has(row2.escalation) && outcomes.has(row2.outcome)),
3047
- named.every((id13) => ids3.has(id13))
3192
+ named.every((id14) => ids3.has(id14))
3048
3193
  ].every(Boolean);
3049
3194
  }
3050
3195
  function isGuideValid(guide, isIsolated) {
@@ -3060,10 +3205,10 @@ function subjectPlanIssues(plan) {
3060
3205
  const issues = [];
3061
3206
  const candidates = plan.groups.flatMap((item) => item.candidates);
3062
3207
  const isIsolated = (entryId, primitive) => {
3063
- const entry2 = plan.entries.find((row2) => row2.id === entryId);
3208
+ const entry3 = plan.entries.find((row2) => row2.id === entryId);
3064
3209
  return [
3065
- entry2?.primitive === primitive,
3066
- entry2?.dependencies.length === 0,
3210
+ entry3?.primitive === primitive,
3211
+ entry3?.dependencies.length === 0,
3067
3212
  !plan.requiredIds.includes(entryId),
3068
3213
  candidates.every((row2) => row2.entryId !== entryId),
3069
3214
  plan.entries.every((row2) => !row2.dependencies.includes(entryId))
@@ -3102,7 +3247,7 @@ var DraftContextSelectionPlanSchema = z31.strictObject({
3102
3247
  attempts: z31.strictObject({
3103
3248
  max: z31.number().int().min(1).max(10),
3104
3249
  withProgress: z31.number().int().min(1).max(10)
3105
- }).refine((value) => value.withProgress >= value.max, "withProgress below max").optional(),
3250
+ }).refine((value2) => value2.withProgress >= value2.max, "withProgress below max").optional(),
3106
3251
  entries: base2.entries,
3107
3252
  requiredIds: base2.requiredIds,
3108
3253
  budget: base2.budget,
@@ -3134,19 +3279,19 @@ var DraftContextSelectionPlanSchema = z31.strictObject({
3134
3279
  if (candidateIds.length > 64 || !hasUniqueIds(candidateIds) || !hasUniqueIds(plan.groups.map((item) => item.id)) || !hasUniqueIds(plan.entries.map((item) => item.id))) {
3135
3280
  context3.addIssue({ code: "custom", message: "Duplicate identities or too many candidates" });
3136
3281
  }
3137
- if (plan.requiredIds.some((id13) => candidateIds.includes(id13))) {
3282
+ if (plan.requiredIds.some((id14) => candidateIds.includes(id14))) {
3138
3283
  context3.addIssue({ code: "custom", message: "Global required root cannot be a candidate" });
3139
3284
  }
3140
3285
  const guidanceId = plan.unresolvedGuidanceEntryId;
3141
3286
  if (guidanceId === void 0) {
3142
3287
  return;
3143
3288
  }
3144
- const entry2 = plan.entries.find((row2) => row2.id === guidanceId);
3289
+ const entry3 = plan.entries.find((row2) => row2.id === guidanceId);
3145
3290
  if ([
3146
- !entry2,
3147
- entry2?.primitive !== "gaps",
3148
- entry2?.dependencies.length,
3149
- entry2?.conflictsWith.length,
3291
+ !entry3,
3292
+ entry3?.primitive !== "gaps",
3293
+ entry3?.dependencies.length,
3294
+ entry3?.conflictsWith.length,
3150
3295
  plan.requiredIds.includes(guidanceId),
3151
3296
  candidateIds.includes(guidanceId),
3152
3297
  plan.entries.some((row2) => row2.dependencies.includes(guidanceId))
@@ -3669,7 +3814,7 @@ var DraftApplicationTargetSchema = DraftApplicationScopeSchema.extend({
3669
3814
  action,
3670
3815
  resourceId: identifier18,
3671
3816
  jobId: identifier18.nullable()
3672
- }).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");
3673
3818
  var DraftApplicationActorSchema = z43.strictObject({
3674
3819
  principalId: identifier18,
3675
3820
  organizationId: identifier18,
@@ -3725,7 +3870,7 @@ var DraftApplicationReleaseSchema = z43.strictObject({
3725
3870
  });
3726
3871
 
3727
3872
  // ../schemas/src/draft-hosted-application.ts
3728
- import { z as z53 } from "zod";
3873
+ import { z as z57 } from "zod";
3729
3874
 
3730
3875
  // ../schemas/src/draft-source-instant.ts
3731
3876
  var localPattern = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?([^.\d].*)$/u;
@@ -3765,11 +3910,11 @@ function utcOf(local, offset) {
3765
3910
  const utc = date.toISOString();
3766
3911
  return utcYear.test(utc) ? utc.slice(0, 19) : null;
3767
3912
  }
3768
- function normalizedSourceInstant(value) {
3769
- if (value.length > sourceInstantMaxLength) {
3913
+ function normalizedSourceInstant(value2) {
3914
+ if (value2.length > sourceInstantMaxLength) {
3770
3915
  return null;
3771
3916
  }
3772
- const match = localPattern.exec(value);
3917
+ const match = localPattern.exec(value2);
3773
3918
  if (match === null) {
3774
3919
  return null;
3775
3920
  }
@@ -3838,7 +3983,7 @@ var DraftOutputContractSchema = z44.strictObject({
3838
3983
  }
3839
3984
  const encoder2 = new TextEncoder();
3840
3985
  for (const section of contract.sections) {
3841
- 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)) {
3842
3987
  context3.addIssue({ code: "custom", message: "Exact alternative exceeds section budget" });
3843
3988
  }
3844
3989
  }
@@ -3985,8 +4130,10 @@ var ArtifactSemanticRequestSchema = z46.strictObject({
3985
4130
  calibration: recipe.calibration,
3986
4131
  requestDigest: digest20
3987
4132
  });
4133
+ var artifactInjectionScreen = z46.literal("paragraph-injection/v1");
3988
4134
  var ArtifactSemanticResponseSchema = z46.strictObject({
3989
4135
  schema: z46.literal("felspar.artifact-question-response.draft/v1"),
4136
+ screen: artifactInjectionScreen.optional(),
3990
4137
  preparationDigest: digest20,
3991
4138
  evaluator: recipe.evaluator,
3992
4139
  calibrationDigest: digest20,
@@ -4007,6 +4154,7 @@ var ArtifactSemanticJudgmentSchema = z46.strictObject({
4007
4154
  });
4008
4155
  var ArtifactSemanticRecordSchema = z46.strictObject({
4009
4156
  state: z46.enum(["ready", "skipped", "over_budget", "not_evaluated"]),
4157
+ screen: artifactInjectionScreen.optional(),
4010
4158
  preparationDigest: digest20,
4011
4159
  evaluator: ArtifactSemanticRecipeSchema.shape.evaluator,
4012
4160
  calibrationDigest: digest20,
@@ -4029,13 +4177,13 @@ var ArtifactSemanticRecordSchema = z46.strictObject({
4029
4177
  });
4030
4178
  var caseNotStated = "not_stated";
4031
4179
  var abstain = "cannot_determine";
4032
- function isMatchOf(question2, check) {
4033
- if (check?.kind !== "case_answer" || question2.aggregation !== "match") {
4034
- 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";
4035
4183
  }
4036
- const offered = new Set(question2.options.map((option2) => option2.value));
4184
+ const offered = new Set(question3.options.map((option2) => option2.value));
4037
4185
  const expected2 = [...(check.answers ?? []).map((row2) => row2.value), caseNotStated, abstain];
4038
- 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));
4039
4187
  }
4040
4188
  function isAsking(check) {
4041
4189
  const isAsker = check.kind === "semantic_question" || check.kind === "case_answer";
@@ -4045,22 +4193,22 @@ function inspectSemantic(manifest2, issue) {
4045
4193
  const askers = manifest2.checks.filter(isAsking);
4046
4194
  const asked = askers.map((check) => check.questionId ?? "");
4047
4195
  const questions = manifest2.semantic?.questions ?? [];
4048
- for (const question2 of questions) {
4049
- const asker = askers.find((check) => check.questionId === question2.id);
4050
- 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)) {
4051
4199
  issue("A semantic question's aggregation differs from the check that asks it");
4052
4200
  }
4053
4201
  }
4054
4202
  const distinctAsked = new Set(asked);
4055
- 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))) {
4056
4204
  issue("Every released semantic question is asked by exactly one check");
4057
4205
  }
4058
- for (const question2 of questions) {
4059
- if (question2.aggregation === "match") {
4206
+ for (const question3 of questions) {
4207
+ if (question3.aggregation === "match") {
4060
4208
  continue;
4061
4209
  }
4062
- const effects = new Set(question2.options.map((option2) => option2.effect));
4063
- 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";
4064
4212
  if (!effects.has(needed)) {
4065
4213
  issue("A semantic question needs an option that can decide its aggregation");
4066
4214
  }
@@ -4080,8 +4228,8 @@ var artifactLintLimits = {
4080
4228
  maxLiteralUnits: 512,
4081
4229
  maxOccurrencesPerCheck: 16
4082
4230
  };
4083
- function isWellFormedText(value) {
4084
- return !/\p{Cs}/u.test(value);
4231
+ function isWellFormedText(value2) {
4232
+ return !/\p{Cs}/u.test(value2);
4085
4233
  }
4086
4234
  var literal = z47.string().min(1).max(artifactLintLimits.maxLiteralUnits).regex(/\S/u).refine(isWellFormedText);
4087
4235
  var passage = z47.strictObject({
@@ -4157,7 +4305,7 @@ var ArtifactCheckSchema = z47.discriminatedUnion("kind", [
4157
4305
  ]);
4158
4306
  var sectionDeclaration = z47.strictObject({
4159
4307
  id: id4,
4160
- 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(),
4161
4309
  maxUnits: z47.number().int().min(1).max(artifactLintLimits.maxSectionUnits)
4162
4310
  });
4163
4311
  function caseAnswerIssues(checks) {
@@ -4291,16 +4439,16 @@ function unique3(values, context3, path3) {
4291
4439
  context3.addIssue({ code: "custom", path: path3, message: "Duplicate obligation identity or target" });
4292
4440
  }
4293
4441
  }
4294
- function isApprovalTargetValid(item, target, useRef) {
4442
+ function isApprovalTargetValid(item, target2, useRef) {
4295
4443
  switch (item.phase) {
4296
4444
  case "before_decision": {
4297
- return target.kind === "decision";
4445
+ return target2.kind === "decision";
4298
4446
  }
4299
4447
  case "before_generation": {
4300
- return target.kind === "artifact";
4448
+ return target2.kind === "artifact";
4301
4449
  }
4302
4450
  case "before_use": {
4303
- return target.kind === "artifact" || target.kind === "use" && useRef !== null;
4451
+ return target2.kind === "artifact" || target2.kind === "use" && useRef !== null;
4304
4452
  }
4305
4453
  default: {
4306
4454
  return false;
@@ -4308,11 +4456,11 @@ function isApprovalTargetValid(item, target, useRef) {
4308
4456
  }
4309
4457
  }
4310
4458
  function inspectApproval(item, binding, context3) {
4311
- unique3(item.appliesTo.map((target) => JSON.stringify(target)), context3, ["approvals", item.id]);
4312
- const artifacts = new Set(binding.selected.artifacts.map((entry2) => entry2.id));
4313
- for (const target of item.appliesTo) {
4314
- const isKnown = target.kind !== "artifact" || artifacts.has(target.id);
4315
- 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);
4316
4464
  if (!isKnown || !isValid) {
4317
4465
  context3.addIssue({
4318
4466
  code: "custom",
@@ -4322,18 +4470,18 @@ function inspectApproval(item, binding, context3) {
4322
4470
  }
4323
4471
  }
4324
4472
  }
4325
- function inspectManifest(value, context3) {
4473
+ function inspectManifest(value2, context3) {
4326
4474
  if (context3.issues.length > 0) {
4327
4475
  return;
4328
4476
  }
4329
- unique3(value.contracts.map((entry2) => entry2.id), context3, ["contracts"]);
4330
- unique3(value.outcomes.map((entry2) => entry2.outcomeId), context3, ["outcomes"]);
4331
- const contracts = new Map(value.contracts.map((entry2) => [entry2.id, entry2.contentDigest]));
4332
- for (const selected of value.outcomes) {
4333
- unique3(selected.artifacts.map((entry2) => entry2.id), context3, ["outcomes", selected.outcomeId, "artifacts"]);
4334
- unique3(selected.approvals.map((entry2) => entry2.id), context3, ["outcomes", selected.outcomeId, "approvals"]);
4335
- for (const entry2 of selected.artifacts) {
4336
- 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) {
4337
4485
  context3.addIssue({
4338
4486
  code: "custom",
4339
4487
  message: "Dangling or mismatched specification reference"
@@ -4341,11 +4489,11 @@ function inspectManifest(value, context3) {
4341
4489
  }
4342
4490
  }
4343
4491
  for (const item of selected.approvals) {
4344
- inspectApproval(item, { selected, scope: value.scope }, context3);
4492
+ inspectApproval(item, { selected, scope: value2.scope }, context3);
4345
4493
  }
4346
4494
  }
4347
4495
  const encoder2 = new TextEncoder();
4348
- if (encoder2.encode(JSON.stringify(value)).length > jobObligationsLimits.maxManifestBytes) {
4496
+ if (encoder2.encode(JSON.stringify(value2)).length > jobObligationsLimits.maxManifestBytes) {
4349
4497
  context3.addIssue({ code: "custom", message: "Obligations manifest byte limit exceeded" });
4350
4498
  }
4351
4499
  }
@@ -4358,15 +4506,15 @@ var HostedOutputChecksSchema = z49.strictObject({
4358
4506
  schema: z49.literal("felspar.output-checks.draft/v0"),
4359
4507
  obligations: DraftJobObligationsSchema,
4360
4508
  manifests: z49.array(ArtifactCheckManifestSchema).min(1).max(hostedOutputCheckLimits.maxOutputs)
4361
- }).superRefine((value, context3) => {
4509
+ }).superRefine((value2, context3) => {
4362
4510
  if (context3.issues.length > 0) {
4363
4511
  return;
4364
4512
  }
4365
4513
  const issue = (message) => {
4366
4514
  context3.addIssue({ code: "custom", message });
4367
4515
  };
4368
- const { obligations, manifests } = value;
4369
- 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]));
4370
4518
  const checked = new Set(manifests.map((manifest2) => manifest2.contract.id));
4371
4519
  if (checked.size !== manifests.length) {
4372
4520
  issue("One manifest per output contract");
@@ -4377,14 +4525,14 @@ var HostedOutputChecksSchema = z49.strictObject({
4377
4525
  issue("A manifest differs from its job or contract");
4378
4526
  }
4379
4527
  }
4380
- 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));
4381
4529
  if (required.some((contractId) => !checked.has(contractId)) || checked.size > contracts.size) {
4382
4530
  issue("Every required output needs exactly one manifest");
4383
4531
  }
4384
4532
  });
4385
4533
 
4386
4534
  // ../schemas/src/draft-pack-revision.ts
4387
- import { z as z52 } from "zod";
4535
+ import { z as z55 } from "zod";
4388
4536
 
4389
4537
  // ../schemas/src/draft-pack-draft-outputs.ts
4390
4538
  import { z as z50 } from "zod";
@@ -4445,10 +4593,10 @@ var PackDraftScoreSchema = z51.strictObject({
4445
4593
  gte: points.optional(),
4446
4594
  eq: points.optional(),
4447
4595
  quote: draftQuote
4448
- }).superRefine((value, context3) => {
4449
- const lower = Number(value.gt !== void 0) + Number(value.gte !== void 0);
4450
- const upper = Number(value.lt !== void 0) + Number(value.lte !== void 0);
4451
- const hasEquality = value.eq !== void 0;
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;
4452
4600
  if (lower + upper + Number(hasEquality) === 0) {
4453
4601
  context3.addIssue({ code: "custom", message: "Give a bound: lt, lte, gt, gte or eq" });
4454
4602
  } else if (lower > 1 || upper > 1) {
@@ -4479,148 +4627,651 @@ var packDraftScoreExpectation = {
4479
4627
  points: z51.record(draftIdentifier, z51.number().min(0).nullable()).optional()
4480
4628
  };
4481
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
+
4482
5021
  // ../schemas/src/draft-pack-revision.ts
4483
- var KeptPackDraftSchema = z52.looseObject({
4484
- schema: z52.string().regex(/^felspar\.pack-draft\/v\d{1,3}$/u),
4485
- job: z52.string().min(1).max(200)
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)
4486
5025
  });
4487
- var id6 = z52.string().min(1).max(200);
4488
- var text7 = z52.string().min(1).max(262144);
4489
- var texts = z52.array(z52.string()).max(8);
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);
4490
5029
  var when = PackDraftConditionsSchema;
4491
5030
  var conventions = packConventionFields;
4492
- var PackOutlineSchema = z52.strictObject({
4493
- schema: z52.literal("felspar.pack-outline/v0"),
5031
+ var PackOutlineSchema = z55.strictObject({
5032
+ schema: z55.literal("felspar.pack-outline/v0"),
4494
5033
  job: id6,
4495
5034
  purpose: text7.nullable(),
4496
5035
  useWhen: texts,
4497
5036
  notFor: texts,
4498
5037
  owner: text7.nullable(),
4499
- evidenceKinds: z52.array(id6).max(8),
4500
- maxEvidenceAgeDays: z52.number().int().min(1).nullable(),
4501
- numberStyle: z52.enum(numberStyles).nullable(),
5038
+ evidenceKinds: z55.array(id6).max(8),
5039
+ maxEvidenceAgeDays: z55.number().int().min(1).nullable(),
5040
+ numberStyle: z55.enum(numberStyles).nullable(),
4502
5041
  dateOrder: conventions.dateOrder.unwrap().nullable(),
4503
- timeZone: z52.string().min(1).max(64).nullable(),
5042
+ timeZone: z55.string().min(1).max(64).nullable(),
5043
+ businessDays: PackDraftBusinessDaysSchema.nullable(),
4504
5044
  subject: id6.nullable(),
4505
- subjects: z52.array(z52.strictObject({
5045
+ subjects: z55.array(z55.strictObject({
4506
5046
  id: id6,
4507
5047
  definition: text7,
4508
- identifier: z52.string().nullable(),
4509
- example: z52.string().nullable(),
4510
- match: z52.string(),
4511
- relationships: z52.array(z52.strictObject({
5048
+ identifier: z55.string().nullable(),
5049
+ example: z55.string().nullable(),
5050
+ match: z55.string(),
5051
+ relationships: z55.array(z55.strictObject({
4512
5052
  name: id6,
4513
5053
  subject: id6,
4514
- cardinality: z52.enum(["one", "many"]),
4515
- required: z52.boolean(),
5054
+ cardinality: z55.enum(["one", "many"]),
5055
+ required: z55.boolean(),
4516
5056
  definition: text7
4517
5057
  })).max(16),
4518
5058
  identity: PackDraftIdentitySchema.nullable()
4519
5059
  })).max(16),
4520
- escalations: z52.array(z52.strictObject({ id: id6, quote: text7 })).max(16),
4521
- questions: z52.array(z52.strictObject({
5060
+ escalations: z55.array(z55.strictObject({ id: id6, quote: text7 })).max(16),
5061
+ questions: z55.array(z55.strictObject({
4522
5062
  key: id6,
4523
- type: z52.enum(["enum", "boolean", "number", "date"]),
5063
+ type: z55.enum(["enum", "boolean", "number", "date"]),
4524
5064
  meaning: text7,
4525
5065
  about: id6.nullable(),
4526
- askOnlyWhen: z52.string().nullable(),
5066
+ askOnlyWhen: z55.string().nullable(),
4527
5067
  when: when.nullable(),
4528
- unit: z52.string().nullable(),
4529
- unitWords: z52.array(z52.string()).max(16).nullable(),
4530
- integer: z52.boolean().nullable(),
4531
- minimum: z52.number().nullable(),
4532
- maximum: z52.number().nullable(),
4533
- answers: z52.array(z52.strictObject({
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({
4534
5074
  value: id6,
4535
- meaning: z52.string().nullable(),
5075
+ meaning: z55.string().nullable(),
4536
5076
  inclusions: texts,
4537
5077
  exclusions: texts,
4538
5078
  examples: texts,
4539
5079
  edgeCases: texts
4540
5080
  })).max(64),
4541
- whereToLook: texts
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()
4542
5088
  })).max(64),
4543
- outcomes: z52.array(z52.strictObject({ id: id6, nextStep: text7.nullable(), escalate: id6.nullable() })).max(64),
4544
- whenUnresolved: z52.strictObject({ quote: text7, escalate: id6.nullable() }).nullable(),
4545
- attempts: z52.strictObject({ max: z52.number().int(), escalate: id6.nullable() }).nullable(),
4546
- rules: z52.array(z52.strictObject({
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({
4547
5093
  id: id6,
4548
5094
  meaning: text7,
4549
5095
  outcome: id6,
4550
5096
  when: when.nullable(),
4551
- conditions: z52.string().nullable(),
4552
- scoreRange: z52.record(z52.string(), z52.unknown()).nullable(),
5097
+ conditions: z55.string().nullable(),
5098
+ scoreRange: z55.record(z55.string(), z55.unknown()).nullable(),
4553
5099
  score: PackDraftScoreSchema.nullable(),
4554
- gate: z52.boolean()
5100
+ gate: z55.boolean(),
5101
+ except: z55.array(id6).max(16).nullable()
4555
5102
  })).max(256),
5103
+ ruleOrder: z55.enum(ruleOrders).nullable(),
4556
5104
  scoring: PackDraftScoringSchema.nullable(),
4557
- cases: z52.array(z52.strictObject({
5105
+ cases: z55.array(z55.strictObject({
4558
5106
  id: id6,
4559
- why: z52.string().nullable(),
4560
- facts: z52.record(id6, caseFactSchema),
5107
+ why: z55.string().nullable(),
5108
+ facts: z55.record(id6, caseFactSchema),
4561
5109
  decisionDate: CalendarDateSchema.nullable(),
4562
- subject: z52.strictObject({ id: id6 }).nullable(),
4563
- expect: z52.strictObject({ outcome: id6, rule: id6, score: z52.number().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
+ ])
4564
5115
  })).max(200),
4565
5116
  outputChecks: PackDraftOutputsSchema.nullable(),
4566
- notKept: z52.array(z52.strictObject({ path: z52.string().min(1), reason: z52.string().min(1) })).max(64)
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)
4567
5207
  });
4568
5208
 
4569
5209
  // ../schemas/src/draft-hosted-application.ts
4570
- var id7 = z53.string().min(1).max(200).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:@-]*$/u);
4571
- var digest23 = DraftApplicationReleaseSchema.shape.releaseDigest;
4572
- var HostedSourceInputSchema = z53.strictObject({
4573
- sourceId: id7,
4574
- revision: id7,
4575
- title: z53.string().min(1).max(200),
4576
- text: z53.string().min(1).max(1048576)
4577
- });
4578
- var HostedProposalInputV0Schema = z53.strictObject({
4579
- sourceObjectId: id7,
4580
- 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,
4581
5221
  material: DraftApplicationJobMaterialSchema,
4582
5222
  compilation: DraftCompilationSchema
4583
5223
  });
4584
- var HostedProposalInputV2Schema = z53.strictObject({
4585
- schema: z53.literal("felspar.hosted-proposal.draft/v2"),
4586
- sourceObjectId: id7,
4587
- 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,
4588
5234
  material: DraftApplicationJobMaterialV2Schema,
4589
5235
  outputChecks: HostedOutputChecksSchema.optional(),
5236
+ manualFacts: HostedManualFactsRuleSchema.optional(),
4590
5237
  draft: KeptPackDraftSchema.optional()
4591
5238
  });
4592
- var HostedProposalInputSchema = z53.union([
5239
+ var HostedProposalInputSchema = z57.union([
4593
5240
  HostedProposalInputV2Schema,
4594
5241
  HostedProposalInputV0Schema
4595
5242
  ]);
4596
- var HostedApprovalInputSchema = z53.strictObject({
4597
- expectedProposalDigest: digest23,
4598
- reviewedMeaning: z53.literal(true),
4599
- reviewedFixtures: z53.literal(true),
4600
- reviewNote: z53.string().min(1).max(2e3)
4601
- });
4602
- var HostedReleaseInputSchema = z53.strictObject({ expectedApprovalDigest: digest23 });
4603
- var HostedReleaseBundleSchema = z53.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({
4604
5254
  release: DraftApplicationReleaseSchema,
4605
5255
  material: DraftAnyApplicationJobMaterialSchema,
4606
- approvalObjectId: id7,
4607
- approvalDigest: digest23,
4608
- proposalDigest: digest23,
4609
- sourceDigest: digest23,
4610
- verifiedCompilation: DraftVerifiedCompilationSchema.optional()
4611
- });
4612
- var HostedJobInputSchema = z53.strictObject({
4613
- executionId: id7,
4614
- 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,
4615
5266
  material: DraftAnyApplicationJobMaterialSchema
4616
5267
  });
4617
- var HostedSuppliedJobInputSchema = z53.strictObject({
4618
- mode: z53.literal("supplied"),
4619
- executionId: id7,
4620
- expectedReleaseDigest: digest23,
4621
- expectedAuthorityDigest: digest23,
4622
- jobId: id7,
4623
- entityId: id7,
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,
4624
5275
  evidence: DraftRequiredDecisionSchema.shape.evidence,
4625
5276
  passages: DraftLayeredEvaluationSchema.shape.passages.max(256)
4626
5277
  });
@@ -4630,97 +5281,185 @@ var hostedFactsLimits = {
4630
5281
  maxFactsBytes: 524288,
4631
5282
  maxQuestions: 64
4632
5283
  };
4633
- var factSourceId = z53.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.`);
4634
- var observedAt = z53.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.`);
4635
- var factSource = z53.strictObject({
4636
- class: id7,
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,
4637
5288
  id: factSourceId,
4638
- revision: id7.optional(),
4639
- locator: z53.string().min(1).max(4096).optional(),
5289
+ revision: id8.optional(),
5290
+ locator: z57.string().min(1).max(4096).optional(),
4640
5291
  observedAt,
4641
- sensitivity: id7.optional()
4642
- });
4643
- var excerptText = z53.string().min(1).refine((text8) => text8.length <= hostedFactsLimits.maxExcerptCharacters, "text_too_long");
4644
- var about = z53.string().min(1).max(200).optional();
4645
- var HostedExcerptSchema = z53.strictObject({ text: excerptText, source: factSource, about });
4646
- var HostedValueFactSchema = z53.strictObject({
4647
- value: z53.union([z53.string().min(1).max(200), z53.number(), z53.boolean()]),
4648
- source: factSource.extend({ excerpt: excerptText.optional() }),
4649
- about
4650
- });
4651
- var HostedFactSchema = z53.union([
4652
- HostedValueFactSchema,
4653
- HostedExcerptSchema,
4654
- z53.array(HostedExcerptSchema).min(1).refine((excerpts2) => excerpts2.length <= hostedFactsLimits.maxExcerptsPerQuestion, "too_many_excerpts")
4655
- ]);
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;
4656
5374
  function factsBytes(facts) {
4657
5375
  const encoder2 = new TextEncoder();
4658
5376
  return encoder2.encode(JSON.stringify(facts)).length;
4659
5377
  }
4660
- var HostedFactsJobInputSchema = z53.strictObject({
4661
- mode: z53.literal("facts"),
4662
- executionId: id7,
4663
- expectedReleaseDigest: digest23,
4664
- jobId: id7,
4665
- entityId: id7,
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,
4666
5390
  related: HostedRelatedSubjectsSchema.optional(),
4667
- identity: z53.record(z53.string().min(1).max(128), z53.string().min(1).max(200)).optional(),
4668
- facts: z53.record(id7, 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)
4669
5393
  });
4670
5394
  var HostedFactsRequestSchema = HostedFactsJobInputSchema.extend({
4671
- entityId: id7.optional()
5395
+ entityId: id8.optional(),
5396
+ facts: factsOf(requestFacts.fact)
4672
5397
  });
4673
- var HostedJobRequestSchema = z53.union([
5398
+ var HostedJobRequestSchema = z57.union([
4674
5399
  HostedJobInputSchema,
4675
5400
  HostedSuppliedJobInputSchema,
4676
5401
  HostedFactsJobInputSchema
4677
5402
  ]);
4678
- var HostedClassificationResultSchema = z53.strictObject({
4679
- key: id7,
4680
- observationId: id7,
5403
+ var HostedClassificationResultSchema = z57.strictObject({
5404
+ key: id8,
5405
+ observationId: id8,
4681
5406
  record: DraftNormalizedEvidenceSchema.shape.normalizations.element,
4682
- reason: z53.string().regex(/^[a-z][a-z_]{2,63}$/u).nullable(),
4683
- cached: z53.boolean()
5407
+ reason: z57.string().regex(/^[a-z][a-z_]{2,63}$/u).nullable(),
5408
+ cached: z57.boolean()
4684
5409
  });
4685
5410
  function retainsFactsExactly(record) {
4686
5411
  const hasFacts = record.facts !== void 0 && record.judgments !== void 0 && record.judgmentsDigest !== void 0;
4687
5412
  return record.schema === "felspar.hosted-supplied-execution/v3" === hasFacts;
4688
5413
  }
4689
- var HostedSuppliedExecutionRecordSchema = z53.strictObject({
4690
- schema: z53.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([
4691
5427
  "felspar.hosted-supplied-execution/v1",
4692
5428
  "felspar.hosted-supplied-execution/v2",
4693
5429
  "felspar.hosted-supplied-execution/v3"
4694
5430
  ]),
4695
- release: z53.strictObject({ releaseId: id7, releaseDigest: digest23, materialDigest: digest23 }),
4696
- evaluationTime: z53.iso.datetime(),
5431
+ release: z57.strictObject({ releaseId: id8, releaseDigest: digest24, materialDigest: digest24 }),
5432
+ evaluationTime: z57.iso.datetime(),
4697
5433
  input: HostedSuppliedJobInputSchema,
4698
5434
  facts: HostedFactsJobInputSchema.optional(),
4699
- judgments: z53.array(HostedClassificationResultSchema).max(192).optional(),
4700
- judgmentsDigest: digest23.optional(),
4701
- expansion: z53.literal("agreeing-excerpts").optional(),
4702
- job: z53.record(z53.string(), z53.unknown())
4703
- }).refine(retainsFactsExactly, "Version 3 records, and only they, retain facts with their judgments");
4704
- var HostedObjectSchema = z53.strictObject({
4705
- id: id7,
4706
- kind: z53.enum(["source", "proposal", "approval", "release", "evidence", "result", "execution"]),
4707
- payloadDigest: digest23,
4708
- objectKey: z53.string().min(1).max(1e3),
4709
- parentId: id7.nullable(),
4710
- status: z53.enum(["active", "released", "revoked"]),
4711
- metadata: z53.record(z53.string(), z53.unknown())
4712
- });
4713
- var HostedJobResultSchema = z53.object({
4714
- status: z53.string(),
4715
- reason: z53.string().nullable(),
4716
- result: z53.object({
4717
- executionId: z53.string(),
4718
- releaseId: id7,
4719
- releaseDigest: digest23,
4720
- outcome: z53.string().nullable(),
4721
- scoring: z53.unknown(),
4722
- context: z53.unknown(),
4723
- receipt: z53.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()
4724
5463
  }).loose().nullable()
4725
5464
  });
4726
5465
 
@@ -4730,6 +5469,12 @@ var formatFix = "The request does not match the facts request format at this pat
4730
5469
  var fixes = {
4731
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.",
4732
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.",
4733
5478
  unknown_question: "This question is not in the released job. Use the question keys from describe.",
4734
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.",
4735
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.",
@@ -4784,6 +5529,8 @@ var fixes = {
4784
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.",
4785
5530
  not_proposer: "Only the person who made a proposal may withdraw it; an approver may reject it.",
4786
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.",
4787
5534
  withdraw_on_web_page: "Withdraw a proposal on the Felspar web page, or propose the job again, which replaces your earlier proposal.",
4788
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.",
4789
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.",
@@ -4797,7 +5544,15 @@ var fixes = {
4797
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.",
4798
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.",
4799
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.",
4800
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.",
4801
5556
  pack_job_mismatch: "That release or proposal belongs to another job. Pass the jobId list_jobs shows with it.",
4802
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.",
4803
5558
  decision_not_decided: "This decision has no outcome, so nothing is written for it. Follow its next step instead.",
@@ -4839,236 +5594,253 @@ function hostedRefusalRecovery(code) {
4839
5594
  }
4840
5595
 
4841
5596
  // ../schemas/src/draft-hosted-job-description.ts
4842
- import { z as z55 } from "zod";
5597
+ import { z as z59 } from "zod";
4843
5598
 
4844
5599
  // ../schemas/src/draft-hosted-output-guides.ts
4845
- import { z as z54 } from "zod";
4846
- var id8 = z54.string().min(1).max(200);
4847
- var located = z54.strictObject({
4848
- text: z54.string().min(1).max(262144),
4849
- locator: z54.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)
4850
5605
  });
4851
5606
  var hostedOutputGuideLimits = { maxOutputs: 8, maxContext: 8, maxChecks: 64 };
4852
- var HostedOutputGuideSchema = z54.strictObject({
4853
- id: id8,
5607
+ var HostedOutputGuideSchema = z58.strictObject({
5608
+ id: id9,
4854
5609
  what: located,
4855
- maxCharacters: z54.number().int().min(1),
4856
- context: z54.array(located.extend({ id: id8 })).max(hostedOutputGuideLimits.maxContext).optional(),
4857
- checks: z54.array(z54.strictObject({
4858
- check: id8,
4859
- rule: z54.string().nullable(),
4860
- must: z54.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)
4861
5616
  })).max(hostedOutputGuideLimits.maxChecks)
4862
5617
  });
4863
- var HostedOutputGuidesSchema = z54.array(HostedOutputGuideSchema).max(hostedOutputGuideLimits.maxOutputs);
5618
+ var HostedOutputGuidesSchema = z58.array(HostedOutputGuideSchema).max(hostedOutputGuideLimits.maxOutputs);
4864
5619
 
4865
5620
  // ../schemas/src/draft-hosted-job-description.ts
4866
- var id9 = z55.string().min(1).max(200);
4867
- var digest24 = DraftApplicationReleaseSchema.shape.releaseDigest;
5621
+ var id10 = z59.string().min(1).max(200);
5622
+ var digest25 = DraftApplicationReleaseSchema.shape.releaseDigest;
4868
5623
  var { requirements, rules } = DraftRequiredProposalSchema.shape;
4869
- var quotedText = z55.strictObject({
4870
- text: z55.string().min(1).max(262144),
5624
+ var quotedText = z59.strictObject({
5625
+ text: z59.string().min(1).max(262144),
4871
5626
  source: DraftSourceReferenceSchema.omit({ contentDigest: true }).extend({
4872
- locator: z55.string().min(1).max(4096),
4873
- contentDigest: digest24
5627
+ locator: z59.string().min(1).max(4096),
5628
+ contentDigest: digest25
4874
5629
  }),
4875
- parts: z55.array(z55.strictObject({ locator: z55.string().min(1).max(4096), text: z55.string() })).max(16)
5630
+ parts: z59.array(z59.strictObject({ locator: z59.string().min(1).max(4096), text: z59.string() })).max(16)
4876
5631
  });
4877
5632
  var subjectShape = {
4878
- identifier: z55.string().min(1).max(200),
4879
- example: z55.string().min(1).max(200),
4880
- match: z55.enum(subjectMatchRules)
5633
+ identifier: z59.string().min(1).max(200),
5634
+ example: z59.string().min(1).max(200),
5635
+ match: z59.enum(subjectMatchRules)
4881
5636
  };
4882
- var HostedJobSubjectSchema = z55.strictObject({
4883
- type: id9,
5637
+ var HostedJobSubjectSchema = z59.strictObject({
5638
+ type: id10,
4884
5639
  definition: quotedText,
4885
5640
  identifier: subjectShape.identifier.optional(),
4886
5641
  example: subjectShape.example.optional(),
4887
5642
  match: subjectShape.match,
4888
- related: z55.array(z55.strictObject({
4889
- relationship: id9,
5643
+ related: z59.array(z59.strictObject({
5644
+ relationship: id10,
4890
5645
  meaning: quotedText,
4891
- cardinality: z55.enum(relationshipCardinalities),
4892
- required: z55.boolean(),
4893
- subject: id9,
5646
+ cardinality: z59.enum(relationshipCardinalities),
5647
+ required: z59.boolean(),
5648
+ subject: id10,
4894
5649
  definition: quotedText,
4895
5650
  ...subjectShape
4896
5651
  })).max(16),
4897
- send: z55.string().min(1).max(2e4)
5652
+ send: z59.string().min(1).max(2e4)
4898
5653
  });
4899
- var HostedJobEscalationsSchema = z55.strictObject({
4900
- routes: z55.array(z55.strictObject({ id: id9, quote: quotedText })).min(1).max(16),
4901
- unresolved: id9.nullable(),
4902
- attemptLimit: id9.nullable(),
4903
- rule: z55.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)
4904
5659
  });
4905
- var HostedEscalationSchema = z55.strictObject({
4906
- id: id9,
4907
- trigger: z55.enum(escalationTriggers),
5660
+ var HostedEscalationSchema = z59.strictObject({
5661
+ id: id10,
5662
+ trigger: z59.enum(escalationTriggers),
4908
5663
  why: quotedText
4909
5664
  });
4910
- var HostedJobDescriptionSchema = z55.strictObject({
4911
- schema: z55.literal("felspar.hosted-job-description.draft/v0"),
4912
- job: id9,
5665
+ var HostedJobDescriptionSchema = z59.strictObject({
5666
+ schema: z59.literal("felspar.hosted-job-description.draft/v0"),
5667
+ job: id10,
4913
5668
  purpose: quotedText.optional(),
4914
- useWhen: z55.array(quotedText).max(8).optional(),
4915
- notFor: z55.array(quotedText).max(8).optional(),
5669
+ useWhen: z59.array(quotedText).max(8).optional(),
5670
+ notFor: z59.array(quotedText).max(8).optional(),
4916
5671
  owner: quotedText.optional(),
4917
5672
  subject: HostedJobSubjectSchema.optional(),
4918
- identity: z55.strictObject({
4919
- mode: z55.enum(identityModes),
4920
- send: z55.string().min(1).max(4e3),
4921
- fields: z55.array(z55.strictObject({ name: id9, ...subjectShape })).max(8).optional(),
4922
- question: id9.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()
4923
5678
  }).optional(),
4924
- trustDomain: id9,
4925
- release: z55.strictObject({
4926
- releaseId: id9,
4927
- releaseDigest: digest24,
4928
- materialDigest: digest24,
4929
- 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
4930
5686
  }),
4931
5687
  resolutionPolicy: DraftRequiredProposalSchema.shape.resolutionPolicy,
4932
- questions: z55.array(requirements.element.extend({
4933
- key: id9,
4934
- type: z55.enum(["enum", "boolean", "number", "date"]),
5688
+ questions: z59.array(requirements.element.extend({
5689
+ key: id10,
5690
+ type: z59.enum(["enum", "boolean", "number", "date"]),
4935
5691
  meaning: quotedText,
4936
- answer: z55.strictObject({
4937
- send: z55.enum(["text", "text_or_value"]),
4938
- valueFormat: z55.enum(["number", "calendar-date"]).nullable(),
4939
- interpretation: z55.enum(["classified", "exact_read", "unsupported"]),
4940
- threshold: z55.number().gt(0).max(1).nullable(),
4941
- applies: z55.enum(["always", "conditional"]),
4942
- dependsOn: z55.array(id9).max(32),
4943
- appliesWhen: z55.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(),
4944
5700
  reading: ExactReaderSchema.optional()
4945
5701
  }),
4946
- answers: z55.array(z55.strictObject({
4947
- value: id9,
4948
- meaning: z55.string().nullable(),
4949
- inclusions: z55.array(z55.string()).max(8),
4950
- exclusions: z55.array(z55.string()).max(8),
4951
- examples: z55.array(z55.string()).max(8),
4952
- edgeCases: z55.array(z55.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)
4953
5709
  })).max(64).optional(),
4954
- whereToLook: z55.array(quotedText).max(8).optional(),
4955
- about: z55.strictObject({ relationship: id9, subject: id9 }).optional()
5710
+ whereToLook: z59.array(quotedText).max(8).optional(),
5711
+ about: z59.strictObject({ relationship: id10, subject: id10 }).optional()
4956
5712
  })).max(64),
4957
- rules: z55.array(rules.element.extend({ text: quotedText })).max(256),
4958
- outcomes: z55.array(z55.strictObject({
4959
- id: id9,
5713
+ rules: z59.array(rules.element.extend({ text: quotedText })).max(256),
5714
+ outcomes: z59.array(z59.strictObject({
5715
+ id: id10,
4960
5716
  meaning: quotedText.nullable(),
4961
5717
  nextStep: quotedText.nullable().optional(),
4962
5718
  outputs: HostedOutputGuidesSchema.optional(),
4963
- escalate: id9.optional()
5719
+ escalate: id10.optional()
4964
5720
  })).max(64),
4965
5721
  escalations: HostedJobEscalationsSchema.optional(),
4966
5722
  whenUnresolved: quotedText.nullable().optional(),
4967
- attempts: z55.strictObject({
4968
- max: z55.number().int().min(1).max(10),
4969
- withProgress: z55.number().int().min(1).max(10),
4970
- rule: z55.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)
4971
5727
  }).optional(),
4972
- guidance: z55.strictObject({ gather: z55.string().min(1).max(2e3) }),
4973
- input: z55.strictObject({
4974
- jsonSchema: z55.record(z55.string(), z55.unknown()),
5728
+ guidance: z59.strictObject({ gather: z59.string().min(1).max(2e3) }),
5729
+ input: z59.strictObject({
5730
+ jsonSchema: z59.record(z59.string(), z59.unknown()),
4975
5731
  example: HostedFactsJobInputSchema.nullable(),
4976
- exampleNote: z55.string().max(1e3)
5732
+ exampleNote: z59.string().max(1e3)
4977
5733
  }),
4978
- limits: z55.strictObject({
4979
- maxEvidenceItems: z55.number().int().positive(),
4980
- maxPassages: z55.number().int().positive(),
4981
- facts: z55.strictObject({
4982
- maxExcerptCharacters: z55.literal(hostedFactsLimits.maxExcerptCharacters),
4983
- maxExcerptsPerQuestion: z55.literal(hostedFactsLimits.maxExcerptsPerQuestion),
4984
- maxFactsBytes: z55.literal(hostedFactsLimits.maxFactsBytes),
4985
- maxQuestions: z55.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)
4986
5742
  })
4987
5743
  })
4988
5744
  });
4989
- var interpretedExcerpt = z55.strictObject({
4990
- id: id9,
4991
- method: z55.enum(["value", "exact_read", "classified"]),
4992
- status: z55.enum(["accepted", "needs_evidence", "not_needed"]),
4993
- value: z55.union([z55.string(), z55.number(), z55.boolean()]).optional(),
4994
- reasons: z55.array(z55.string()),
4995
- classification: z55.strictObject({
4996
- candidate: z55.string().nullable(),
4997
- probability: z55.number().min(0).max(1).nullable(),
4998
- abstention: z55.number().min(0).max(1).nullable(),
4999
- threshold: z55.number().min(0).max(1),
5000
- alternatives: z55.array(z55.strictObject({ value: z55.string(), probability: z55.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() }))
5001
5757
  }).optional()
5002
5758
  });
5003
- var ruleSummary = z55.strictObject({ id: id9, outcome: id9, text: quotedText });
5004
- var HostedJobExplanationSchema = z55.strictObject({
5005
- schema: z55.literal("felspar.hosted-job-explanation.draft/v0"),
5006
- decision: z55.strictObject({ status: z55.string().nullable(), reasons: z55.array(z55.string()) }),
5007
- needs: z55.array(z55.strictObject({
5008
- key: id9,
5009
- status: z55.string(),
5010
- reasons: z55.array(z55.string()),
5011
- acceptedSourceClasses: z55.array(z55.string()),
5012
- maxAgeMs: z55.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(),
5013
5769
  requiredWhen: HostedJobDescriptionSchema.shape.questions.element.shape.requiredWhen,
5014
- excerpts: z55.array(interpretedExcerpt).optional()
5770
+ excerpts: z59.array(interpretedExcerpt).optional()
5015
5771
  })),
5016
- why: z55.strictObject({
5017
- rules: z55.array(ruleSummary),
5018
- overrides: z55.array(z55.strictObject({ by: id9, target: id9 })),
5019
- suppressedRuleIds: z55.array(id9),
5020
- evidence: z55.array(z55.record(z55.string(), z55.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()))
5021
5777
  }).nullable(),
5022
- context: z55.strictObject({ status: z55.string(), reason: z55.string().nullable() }).nullable(),
5023
- reviewNeeds: z55.array(z55.string()),
5024
- evidenceFreshUntil: z55.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()
5025
5781
  });
5026
- var HostedReceiptVerificationInputSchema = z55.strictObject({
5782
+ var HostedReceiptVerificationInputSchema = z59.strictObject({
5027
5783
  receipt: DraftJobReceiptSchema,
5028
- expectedReceiptDigest: digest24,
5784
+ expectedReceiptDigest: digest25,
5029
5785
  deliveredCapsule: DraftContextVerificationOptionsSchema.shape.deliveredCapsule
5030
5786
  });
5031
- var HostedReceiptVerificationSchema = z55.strictObject({
5032
- authority: z55.literal("unapproved"),
5033
- status: z55.enum(["reproduced", "mismatch"]),
5034
- mismatches: z55.array(z55.string()),
5035
- decided: z55.strictObject({
5036
- jobId: id9,
5037
- entityId: id9,
5038
- releaseId: id9,
5039
- outcome: id9.nullable(),
5040
- case: z55.strictObject({ id: id9, mode: z55.enum(identityModes) }).optional(),
5041
- subject: z55.strictObject({
5042
- type: id9,
5043
- related: z55.array(z55.strictObject({ relationship: id9, subject: id9, id: id9, questions: z55.array(id9).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)
5044
5800
  }).optional(),
5045
- 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()
5046
5818
  }).optional()
5047
5819
  });
5048
5820
 
5049
5821
  // ../schemas/src/draft-hosted-output-check-record.ts
5050
- import { z as z58 } from "zod";
5822
+ import { z as z62 } from "zod";
5051
5823
 
5052
5824
  // ../schemas/src/draft-artifact-lint.ts
5053
- import { z as z57 } from "zod";
5825
+ import { z as z61 } from "zod";
5054
5826
 
5055
5827
  // ../schemas/src/draft-job-obligations.ts
5056
- import { z as z56 } from "zod";
5057
- var id10 = DraftApplicationScopeSchema.shape.authorityId;
5058
- var digest25 = DraftJobReceiptSchema.shape.receiptDigest;
5828
+ import { z as z60 } from "zod";
5829
+ var id11 = DraftApplicationScopeSchema.shape.authorityId;
5830
+ var digest26 = DraftJobReceiptSchema.shape.receiptDigest;
5059
5831
  var outcome2 = DraftJobObligationsOutcomeSchema;
5060
5832
  var DraftApplicationJobMaterialV3Schema = DraftApplicationJobMaterialV2Schema.extend({
5061
- schema: z56.literal("felspar.application-job-material.draft/v3"),
5833
+ schema: z60.literal("felspar.application-job-material.draft/v3"),
5062
5834
  obligations: DraftJobObligationsSchema
5063
- }).superRefine((value, context3) => {
5835
+ }).superRefine((value2, context3) => {
5064
5836
  if (context3.issues.length > 0) {
5065
5837
  return;
5066
5838
  }
5067
- const { obligations, discovery } = value;
5068
- const { proposal } = value.input.invocation.authority.catalog;
5839
+ const { obligations, discovery } = value2;
5840
+ const { proposal } = value2.input.invocation.authority.catalog;
5069
5841
  const isSourceMatches = Object.entries(proposal.source).every(([key3, expected2]) => Reflect.get(obligations.source, key3) === expected2);
5070
- const outcomes = new Set(obligations.outcomes.map((entry2) => entry2.outcomeId));
5071
- 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));
5072
5844
  const matches = [
5073
5845
  isSourceMatches,
5074
5846
  isComplete,
@@ -5086,57 +5858,57 @@ var DraftApplicationJobMaterialV3Schema = DraftApplicationJobMaterialV2Schema.ex
5086
5858
  }
5087
5859
  });
5088
5860
  var HostedProposalInputV3Schema = HostedProposalInputV2Schema.extend({
5089
- schema: z56.literal("felspar.hosted-proposal.draft/v3"),
5861
+ schema: z60.literal("felspar.hosted-proposal.draft/v3"),
5090
5862
  material: DraftApplicationJobMaterialV3Schema
5091
5863
  });
5092
5864
  var jobObligationsReplayRoutes = ["supplied", "evaluated"];
5093
5865
  var replayRoutes = new Set(jobObligationsReplayRoutes);
5094
5866
  var DraftJobObligationsExecutionSchema = DraftAnyJobExecutionSchema.refine((execution) => replayRoutes.has(execution.invocation.route), "Obligations assessments support supplied and evaluated native executions");
5095
- var DraftJobObligationsNativeResultSchema = z56.strictObject({
5096
- authority: z56.literal("unapproved"),
5097
- discovery: z56.record(z56.string(), z56.unknown()),
5098
- executed: z56.record(z56.string(), z56.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()),
5099
5871
  receipt: DraftJobReceiptSchema
5100
5872
  });
5101
- var DraftJobObligationsInputSchema = z56.strictObject({
5873
+ var DraftJobObligationsInputSchema = z60.strictObject({
5102
5874
  release: DraftApplicationReleaseSchema,
5103
- material: z56.union([DraftApplicationJobMaterialV3Schema, DraftAnyApplicationJobMaterialSchema]),
5875
+ material: z60.union([DraftApplicationJobMaterialV3Schema, DraftAnyApplicationJobMaterialSchema]),
5104
5876
  execution: DraftJobObligationsExecutionSchema,
5105
- expectedReceiptDigest: digest25,
5877
+ expectedReceiptDigest: digest26,
5106
5878
  job: DraftJobObligationsNativeResultSchema,
5107
5879
  explanation: HostedJobExplanationSchema,
5108
- invocation: DraftJobObligationsScopeSchema.extend({ caseId: id10 })
5880
+ invocation: DraftJobObligationsScopeSchema.extend({ caseId: id11 })
5109
5881
  });
5110
- var requirements2 = z56.strictObject({
5111
- status: z56.enum(["established", "unresolved"]),
5882
+ var requirements2 = z60.strictObject({
5883
+ status: z60.enum(["established", "unresolved"]),
5112
5884
  scope: DraftJobObligationsScopeSchema,
5113
5885
  artifacts: outcome2.shape.artifacts,
5114
5886
  approvals: outcome2.shape.approvals,
5115
- unresolved: z56.array(z56.strictObject({ scopeRef: id10, reasonCodes: z56.array(id10).min(1).max(64) })).max(64)
5887
+ unresolved: z60.array(z60.strictObject({ scopeRef: id11, reasonCodes: z60.array(id11).min(1).max(64) })).max(64)
5116
5888
  });
5117
- var nextReference = z56.discriminatedUnion("kind", [
5118
- z56.strictObject({ kind: z56.literal("evidence_need"), id: id10 }),
5119
- z56.strictObject({ kind: z56.literal("artifact_requirement"), id: id10 }),
5120
- z56.strictObject({ kind: z56.literal("approval_requirement"), id: id10 }),
5121
- z56.strictObject({ kind: z56.literal("unresolved_scope"), scopeRef: id10 })
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 })
5122
5894
  ]);
5123
- var DraftJobObligationsAssessmentBodySchema = z56.strictObject({
5124
- schema: z56.literal("felspar.job-obligations-assessment.draft/v0"),
5125
- binding: z56.strictObject({
5126
- releaseDigest: digest25,
5127
- materialDigest: digest25,
5128
- nativeReceiptDigest: digest25,
5129
- jobId: id10,
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,
5130
5902
  applicationScope: DraftApplicationScopeSchema,
5131
- caseId: id10,
5132
- entityId: id10,
5133
- evaluationTime: z56.iso.datetime({ offset: true }),
5134
- purposeRef: id10,
5135
- useRef: id10.nullable()
5903
+ caseId: id11,
5904
+ entityId: id11,
5905
+ evaluationTime: z60.iso.datetime({ offset: true }),
5906
+ purposeRef: id11,
5907
+ useRef: id11.nullable()
5136
5908
  }),
5137
5909
  requirements: requirements2,
5138
- next: z56.strictObject({
5139
- kind: z56.enum([
5910
+ next: z60.strictObject({
5911
+ kind: z60.enum([
5140
5912
  "stop",
5141
5913
  "review_required",
5142
5914
  "gather_evidence",
@@ -5144,20 +5916,20 @@ var DraftJobObligationsAssessmentBodySchema = z56.strictObject({
5144
5916
  "verify_before_action",
5145
5917
  "return_result"
5146
5918
  ]),
5147
- reasonCodes: z56.array(id10).max(64),
5148
- refs: z56.array(nextReference).max(64)
5919
+ reasonCodes: z60.array(id11).max(64),
5920
+ refs: z60.array(nextReference).max(64)
5149
5921
  })
5150
5922
  });
5151
5923
  function isNextRefDeclared(ref, required) {
5152
5924
  switch (ref.kind) {
5153
5925
  case "artifact_requirement": {
5154
- return required.artifacts.some((entry2) => entry2.id === ref.id);
5926
+ return required.artifacts.some((entry3) => entry3.id === ref.id);
5155
5927
  }
5156
5928
  case "approval_requirement": {
5157
- return required.approvals.some((entry2) => entry2.id === ref.id);
5929
+ return required.approvals.some((entry3) => entry3.id === ref.id);
5158
5930
  }
5159
5931
  case "unresolved_scope": {
5160
- return required.unresolved.some((entry2) => entry2.scopeRef === ref.scopeRef);
5932
+ return required.unresolved.some((entry3) => entry3.scopeRef === ref.scopeRef);
5161
5933
  }
5162
5934
  case "evidence_need": {
5163
5935
  return true;
@@ -5168,13 +5940,13 @@ function isNextRefDeclared(ref, required) {
5168
5940
  }
5169
5941
  }
5170
5942
  var DraftJobObligationsAssessmentSchema = DraftJobObligationsAssessmentBodySchema.extend({
5171
- assessmentDigest: digest25
5172
- }).superRefine((value, context3) => {
5173
- const { requirements: required } = value;
5943
+ assessmentDigest: digest26
5944
+ }).superRefine((value2, context3) => {
5945
+ const { requirements: required } = value2;
5174
5946
  if (required.status === "established" !== (required.unresolved.length === 0) || required.status === "unresolved" && (required.artifacts.length > 0 || required.approvals.length > 0)) {
5175
5947
  context3.addIssue({ code: "custom", message: "Requirements completeness differs" });
5176
5948
  }
5177
- for (const ref of value.next.refs) {
5949
+ for (const ref of value2.next.refs) {
5178
5950
  if (!isNextRefDeclared(ref, required)) {
5179
5951
  context3.addIssue({ code: "custom", message: "Dangling next reference" });
5180
5952
  }
@@ -5182,48 +5954,48 @@ var DraftJobObligationsAssessmentSchema = DraftJobObligationsAssessmentBodySchem
5182
5954
  });
5183
5955
 
5184
5956
  // ../schemas/src/draft-artifact-lint.ts
5185
- var id11 = DraftApplicationScopeSchema.shape.authorityId;
5186
- var digest26 = DraftJobReceiptSchema.shape.receiptDigest;
5957
+ var id12 = DraftApplicationScopeSchema.shape.authorityId;
5958
+ var digest27 = DraftJobReceiptSchema.shape.receiptDigest;
5187
5959
  var passage3 = ArtifactSpecificationSchema;
5188
- var plainArtifact = z57.strictObject({
5189
- id: id11,
5190
- revision: id11,
5191
- mediaType: z57.literal("text/plain"),
5192
- exportProfile: id11.nullable(),
5193
- content: z57.string().max(artifactLintLimits.maxTotalBytes),
5194
- expectedContentDigest: digest26
5195
- });
5196
- var structuredArtifact = z57.strictObject({
5197
- id: id11,
5198
- revision: id11,
5199
- mediaType: z57.literal("application/vnd.felspar.structured-output+json"),
5200
- exportProfile: id11.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(),
5201
5973
  content: DraftStructuredOutputSchema,
5202
- expectedContentDigest: digest26
5974
+ expectedContentDigest: digest27
5203
5975
  });
5204
- var ArtifactLintArtifactSchema = z57.discriminatedUnion("mediaType", [
5976
+ var ArtifactLintArtifactSchema = z61.discriminatedUnion("mediaType", [
5205
5977
  plainArtifact,
5206
5978
  structuredArtifact
5207
5979
  ]);
5208
- var ArtifactLintDecisionSchema = z57.strictObject({
5980
+ var ArtifactLintDecisionSchema = z61.strictObject({
5209
5981
  inputs: DraftJobObligationsInputSchema,
5210
5982
  assessment: DraftJobObligationsAssessmentSchema,
5211
- expectedAssessmentDigest: digest26
5983
+ expectedAssessmentDigest: digest27
5212
5984
  });
5213
- var ArtifactLintInputSchema = z57.strictObject({
5214
- schema: z57.literal("felspar.lint.draft/v1"),
5215
- requestId: id11,
5985
+ var ArtifactLintInputSchema = z61.strictObject({
5986
+ schema: z61.literal("felspar.lint.draft/v1"),
5987
+ requestId: id12,
5216
5988
  release: DraftApplicationReleaseSchema,
5217
5989
  material: DraftApplicationJobMaterialV3Schema,
5218
5990
  manifest: ArtifactCheckManifestSchema,
5219
- expectedManifestDigest: digest26,
5220
- attachedObligations: z57.strictObject({ expectedObligationsDigest: digest26 }).optional(),
5221
- attachedCase: z57.strictObject({
5222
- decisionReceiptDigest: digest26,
5223
- answers: z57.array(z57.strictObject({ key: id11, value: z57.union([z57.string().min(1).max(200), z57.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)
5224
5996
  }).optional(),
5225
- case: z57.strictObject({ caseId: id11, purposeRef: id11, useRef: id11.nullable() }),
5226
- artifactRequirementId: id11.nullable(),
5997
+ case: z61.strictObject({ caseId: id12, purposeRef: id12, useRef: id12.nullable() }),
5998
+ artifactRequirementId: id12.nullable(),
5227
5999
  decision: ArtifactLintDecisionSchema.nullable(),
5228
6000
  artifact: ArtifactLintArtifactSchema
5229
6001
  });
@@ -5236,11 +6008,11 @@ var artifactCheckStatuses = [
5236
6008
  "not_applicable",
5237
6009
  "skipped"
5238
6010
  ];
5239
- var range = z57.strictObject({
5240
- sectionId: id11,
5241
- start: z57.number().int().min(0).max(artifactLintLimits.maxSectionUnits),
5242
- end: z57.number().int().min(1).max(artifactLintLimits.maxSectionUnits),
5243
- offsetUnit: z57.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")
5244
6016
  });
5245
6017
  var findingCodes = [
5246
6018
  "section_missing",
@@ -5261,6 +6033,7 @@ var findingCodes = [
5261
6033
  "semantic_violation",
5262
6034
  "semantic_missing",
5263
6035
  "semantic_unresolved",
6036
+ "possible_prompt_injection",
5264
6037
  "case_answer_conflict",
5265
6038
  "case_answer_missing",
5266
6039
  "case_answer_unconfirmed",
@@ -5268,148 +6041,148 @@ var findingCodes = [
5268
6041
  "evaluation_budget_exceeded",
5269
6042
  "evaluation_skipped"
5270
6043
  ];
5271
- var ArtifactFindingSchema = z57.strictObject({
5272
- code: z57.enum(findingCodes),
5273
- checkId: id11.nullable(),
5274
- severity: z57.enum(["error", "warning"]),
6044
+ var ArtifactFindingSchema = z61.strictObject({
6045
+ code: z61.enum(findingCodes),
6046
+ checkId: id12.nullable(),
6047
+ severity: z61.enum(["error", "warning"]),
5275
6048
  specification: passage3.nullable(),
5276
6049
  location: range.nullable(),
5277
- insertionAnchor: z57.strictObject({ sectionId: id11.nullable(), at: z57.number().int().min(0) }).nullable(),
5278
- literalIndex: z57.number().int().min(0).max(artifactLintLimits.maxLiterals).nullable()
5279
- });
5280
- var ArtifactCheckObservationSchema = z57.strictObject({
5281
- checkId: id11,
5282
- kind: z57.enum(artifactCheckKinds),
5283
- required: z57.boolean(),
5284
- method: z57.enum(["deterministic", "semantic"]),
5285
- status: z57.enum(artifactCheckStatuses),
5286
- occurrences: z57.number().int().min(0),
5287
- parsedValue: z57.number().nullable(),
5288
- caseValue: z57.number().nullable()
5289
- });
5290
- var ArtifactLintRecordBodySchema = z57.strictObject({
5291
- schema: z57.literal("felspar.lint-record.draft/v1"),
5292
- requestId: id11,
5293
- status: z57.enum(["pass", "revise", "unavailable", "review_required"]),
5294
- caseContext: z57.enum(["bound", "not_required"]),
5295
- binding: z57.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({
5296
6069
  scope: DraftApplicationScopeSchema,
5297
- releaseId: id11,
5298
- releaseDigest: digest26,
5299
- materialDigest: digest26,
5300
- obligationsDigest: digest26.optional(),
5301
- caseFactsDigest: digest26.optional(),
5302
- jobId: id11,
5303
- manifestId: id11,
5304
- manifestDigest: digest26,
5305
- contract: z57.strictObject({ id: id11, digest: digest26 }),
5306
- caseId: id11,
5307
- purposeRef: id11,
5308
- useRef: id11.nullable(),
5309
- artifactRequirementId: id11.nullable(),
5310
- decisionReceiptDigest: digest26.nullable(),
5311
- 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()
5312
6085
  }),
5313
- artifact: z57.strictObject({
5314
- id: id11,
5315
- revision: id11,
5316
- mediaType: z57.enum(artifactLintMediaTypes),
5317
- exportProfile: id11.nullable(),
5318
- contentDigest: digest26,
5319
- sections: z57.array(z57.strictObject({
5320
- id: id11,
5321
- units: z57.number().int().min(0),
5322
- 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()
5323
6096
  })).max(artifactLintLimits.maxSections)
5324
6097
  }),
5325
- checks: z57.array(ArtifactCheckObservationSchema).max(artifactLintLimits.maxChecks),
5326
- findings: z57.array(ArtifactFindingSchema).max(2048),
6098
+ checks: z61.array(ArtifactCheckObservationSchema).max(artifactLintLimits.maxChecks),
6099
+ findings: z61.array(ArtifactFindingSchema).max(2048),
5327
6100
  semantic: ArtifactSemanticRecordSchema.nullable(),
5328
- coverage: z57.strictObject({
5329
- scope: z57.literal("declared_checks_only"),
5330
- declared: z57.number().int().min(0),
5331
- applicable: z57.number().int().min(0),
5332
- completed: z57.number().int().min(0),
5333
- required: z57.number().int().min(0),
5334
- requiredCompleted: z57.number().int().min(0),
5335
- textAssigned: z57.enum(["complete", "incomplete"]),
5336
- semantic: z57.enum(["not_declared", "complete", "incomplete"]),
5337
- nativeDocumentLayout: z57.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")
5338
6111
  }),
5339
- actionAuthorized: z57.literal(false)
6112
+ actionAuthorized: z61.literal(false)
5340
6113
  });
5341
6114
  var ArtifactLintRecordSchema = ArtifactLintRecordBodySchema.extend({
5342
- recordDigest: digest26
5343
- });
5344
- var ArtifactLintReceiptSchema = z57.strictObject({
5345
- schema: z57.literal("felspar.lint-receipt.draft/v1"),
5346
- recordDigest: digest26,
5347
- releaseDigest: digest26,
5348
- manifestDigest: digest26,
5349
- contractDigest: digest26,
5350
- caseId: id11,
5351
- caseContext: z57.enum(["bound", "not_required"]),
5352
- decisionReceiptDigest: digest26.nullable(),
5353
- obligationsAssessmentDigest: digest26.nullable(),
5354
- artifactId: id11,
5355
- artifactRevision: id11,
5356
- artifactDigest: digest26,
5357
- actionAuthorized: z57.literal(false),
5358
- 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
5359
6132
  });
5360
6133
 
5361
6134
  // ../schemas/src/draft-hosted-output-check-record.ts
5362
- var id12 = DraftApplicationScopeSchema.shape.authorityId;
5363
- var digest27 = DraftJobReceiptSchema.shape.receiptDigest;
5364
- var HostedOutputCheckInputSchema = z58.strictObject({
5365
- executionId: id12,
5366
- output: id12.optional(),
5367
- text: z58.string().min(1).max(artifactLintLimits.maxTotalBytes).refine(isWellFormedText, "text_not_well_formed"),
5368
- revision: id12.optional()
5369
- });
5370
- var HostedOutputCheckRecordSchema = z58.strictObject({
5371
- schema: z58.literal("felspar.hosted-output-check/v0"),
5372
- checkId: id12,
5373
- jobId: id12,
5374
- output: id12,
5375
- decision: z58.strictObject({ executionId: id12, outcome: id12, receiptDigest: digest27 }),
5376
- release: z58.strictObject({ releaseId: id12, 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 }),
5377
6150
  record: ArtifactLintRecordSchema,
5378
6151
  receipt: ArtifactLintReceiptSchema.nullable(),
5379
- evaluation: z58.strictObject({
5380
- modelCalls: z58.number().int().min(0),
5381
- reason: z58.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()
5382
6155
  })
5383
6156
  });
5384
6157
 
5385
6158
  // src/draft-hosted-client.ts
5386
- import { z as z59 } from "zod";
5387
- var digestText = z59.string().regex(/^sha256:[a-f0-9]{64}$/u);
5388
- var HostedOutputCheckReplySchema = z59.object({
5389
- status: z59.enum(["pass", "revise", "review_required", "unavailable"]),
5390
- checkId: z59.string(),
5391
- output: z59.string(),
5392
- findings: z59.array(z59.record(z59.string(), z59.unknown())),
5393
- receipt: z59.object({ receiptDigest: digestText, artifactDigest: digestText }).loose().nullable(),
5394
- decision: z59.object({ executionId: z59.string(), receiptDigest: digestText }),
5395
- actionAuthorized: z59.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)
5396
6169
  }).loose();
5397
- var quotedWords = z59.object({ text: z59.string() }).loose();
5398
- var FelsparCaseSchema = z59.object({ id: z59.string().min(1).max(200), mode: z59.enum(identityModes) });
5399
- var FelsparRelatedSchema = z59.object({
5400
- relationship: z59.string(),
5401
- subject: z59.string(),
5402
- id: z59.string(),
5403
- questions: z59.array(z59.string())
5404
- });
5405
- var FelsparResultSubjectSchema = z59.object({
5406
- type: z59.string(),
5407
- id: z59.string(),
5408
- related: z59.array(FelsparRelatedSchema)
5409
- });
5410
- var FelsparEscalationSchema = z59.object({
5411
- id: z59.string().min(1).max(200),
5412
- trigger: z59.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),
5413
6186
  why: quotedWords
5414
6187
  });
5415
6188
  var FelsparJobResultSchema = HostedJobResultSchema.extend({
@@ -5417,25 +6190,25 @@ var FelsparJobResultSchema = HostedJobResultSchema.extend({
5417
6190
  case: FelsparCaseSchema.optional(),
5418
6191
  subject: FelsparResultSubjectSchema.optional(),
5419
6192
  escalation: FelsparEscalationSchema.optional(),
5420
- missing: z59.array(z59.string()).optional()
6193
+ missing: z63.array(z63.string()).optional()
5421
6194
  }).nullable()
5422
6195
  });
5423
- var FelsparJobListSchema = z59.object({
5424
- jobs: z59.array(z59.object({ id: z59.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)
5425
6198
  });
5426
6199
  var hostedPartsContentType = "application/x.felspar-content-parts";
5427
- async function partsBody(value) {
5428
- const packed = await packContentParts(value);
6200
+ async function partsBody(value2) {
6201
+ const packed = await packContentParts(value2);
5429
6202
  return packed.text;
5430
6203
  }
5431
- async function factsRequest(value, describeRelease) {
5432
- if (typeof value.expectedReleaseDigest === "string") {
5433
- 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 });
5434
6207
  }
5435
- const described = await describeRelease(HostedObjectSchema.shape.id.parse(value.jobId));
6208
+ const described = await describeRelease(HostedObjectSchema.shape.id.parse(value2.jobId));
5436
6209
  return HostedFactsRequestSchema.parse({
5437
6210
  mode: "facts",
5438
- ...value,
6211
+ ...value2,
5439
6212
  expectedReleaseDigest: described.release.releaseDigest
5440
6213
  });
5441
6214
  }
@@ -5473,31 +6246,31 @@ ${jobId}`;
5473
6246
  return result;
5474
6247
  };
5475
6248
  }
5476
- var refusalCode = z59.string().regex(/^[a-z][a-z_]{2,63}$/u);
5477
- var fieldPath = z59.array(z59.string().max(256)).max(32);
5478
- var refusalEscalationSchema = z59.object({
5479
- id: z59.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:/@-]{0,199}$/u),
5480
- trigger: z59.enum(escalationTriggers),
5481
- why: z59.object({ text: z59.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) })
5482
6255
  });
5483
- var refusalSchema = z59.object({
6256
+ var refusalSchema = z63.object({
5484
6257
  error: refusalCode,
5485
6258
  path: fieldPath.optional(),
5486
- currentReleaseDigest: z59.string().regex(/^sha256:[a-f0-9]{64}$/u).optional(),
5487
- retryAfterSeconds: z59.number().int().min(1).max(3600).optional(),
5488
- escalation: z59.unknown().optional(),
5489
- issues: z59.array(z59.object({ code: refusalCode, path: fieldPath })).max(64).optional()
5490
- }).transform(({ escalation: named, ...value }) => {
5491
- const fix = hostedRefusalFix(value.error);
5492
- const recovery = hostedRefusalRecovery(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);
5493
6266
  const escalation = refusalEscalationSchema.safeParse(named).data;
5494
6267
  return {
5495
- ...value,
6268
+ ...value2,
5496
6269
  ...escalation !== void 0 && { escalation },
5497
6270
  ...fix !== null && { fix },
5498
6271
  ...recovery !== null && { recovery },
5499
- ...value.issues && {
5500
- issues: value.issues.map((issue) => {
6272
+ ...value2.issues && {
6273
+ issues: value2.issues.map((issue) => {
5501
6274
  const issueFix = hostedRefusalFix(issue.code);
5502
6275
  return issueFix === null ? issue : { ...issue, fix: issueFix };
5503
6276
  })
@@ -5541,7 +6314,7 @@ function outputCheckCalls(call) {
5541
6314
  const objectId = HostedObjectSchema.shape.id;
5542
6315
  const checksOf = (job) => `/v0/jobs/${encodeURIComponent(objectId.parse(job))}/output-checks`;
5543
6316
  return {
5544
- 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)),
5545
6318
  readOutputCheck: async (job, checkId) => await call(`${checksOf(job)}/${encodeURIComponent(objectId.parse(checkId))}`, HostedOutputCheckReplySchema)
5546
6319
  };
5547
6320
  }
@@ -5550,9 +6323,9 @@ function agentCalls(call) {
5550
6323
  return {
5551
6324
  listJobs: async () => await call("/v0/jobs", FelsparJobListSchema),
5552
6325
  describeCurrentJob: async (job) => await call(`/v0/jobs/${encodeURIComponent(objectId.parse(job))}/brief`, HostedJobDescriptionSchema),
5553
- resolveJob: async (id13, value) => {
5554
- const input = HostedSuppliedJobInputSchema.parse(value);
5555
- const releaseId = objectId.parse(id13);
6326
+ resolveJob: async (id14, value2) => {
6327
+ const input = HostedSuppliedJobInputSchema.parse(value2);
6328
+ const releaseId = objectId.parse(id14);
5556
6329
  const path3 = `/v0/releases/${encodeURIComponent(releaseId)}/jobs`;
5557
6330
  return pinnedResult(await call(path3, FelsparJobResultSchema, input), releaseId, input);
5558
6331
  }
@@ -5573,14 +6346,14 @@ function createHostedFelsparClient(configuration) {
5573
6346
  }
5574
6347
  const authorization = authorizationOf(configuration);
5575
6348
  const fetcher = configuration.fetcher ?? fetch;
5576
- async function call(path3, schema, value) {
6349
+ async function call(path3, schema, value2) {
5577
6350
  const headers = new Headers(authorization === null ? {} : { Authorization: authorization });
5578
- const body = value === void 0 ? void 0 : await partsBody(value);
6351
+ const body = value2 === void 0 ? void 0 : await partsBody(value2);
5579
6352
  if (body !== void 0) {
5580
6353
  headers.set("Content-Type", hostedPartsContentType);
5581
6354
  }
5582
6355
  const response = await fetcher(`${origin.origin}${path3}`, {
5583
- method: value === void 0 ? "GET" : "POST",
6356
+ method: value2 === void 0 ? "GET" : "POST",
5584
6357
  headers,
5585
6358
  credentials: "include",
5586
6359
  redirect: "error",
@@ -5595,19 +6368,19 @@ function createHostedFelsparClient(configuration) {
5595
6368
  const objectId = HostedObjectSchema.shape.id;
5596
6369
  const describe = jobDescriber(async (releaseId, jobId) => await call(describePath(releaseId, jobId), HostedJobDescriptionSchema));
5597
6370
  return {
5598
- submitSource: async (value) => await call("/v0/sources", HostedObjectSchema, HostedSourceInputSchema.parse(value)),
5599
- submitProposal: async (value) => await call("/v0/proposals", HostedObjectSchema, HostedProposalInputSchema.parse(value)),
5600
- approveProposal: async (id13, value) => await call(`/v0/proposals/${encodeURIComponent(objectId.parse(id13))}/approve`, HostedObjectSchema, HostedApprovalInputSchema.parse(value)),
5601
- releasePack: async (id13, value) => await call(`/v0/approvals/${encodeURIComponent(objectId.parse(id13))}/release`, DraftApplicationReleaseSchema, HostedReleaseInputSchema.parse(value)),
5602
- loadRelease: async (id13) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id13))}`, HostedReleaseBundleSchema),
5603
- describeJob: async (id13, job) => await describe(objectId.parse(id13), objectId.parse(job)),
5604
- 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)),
5605
6378
  ...outputCheckCalls(call),
5606
- executeJob: async (id13, value) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id13))}/jobs`, HostedJobResultSchema, HostedJobInputSchema.parse(value)),
6379
+ executeJob: async (id14, value2) => await call(`/v0/releases/${encodeURIComponent(objectId.parse(id14))}/jobs`, HostedJobResultSchema, HostedJobInputSchema.parse(value2)),
5607
6380
  ...agentCalls(call),
5608
- resolveFacts: async (id13, value) => {
5609
- const releaseId = objectId.parse(id13);
5610
- 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));
5611
6384
  const path3 = `/v0/releases/${encodeURIComponent(releaseId)}/jobs`;
5612
6385
  return pinnedResult(await call(path3, FelsparJobResultSchema, input), releaseId, input);
5613
6386
  }